Skip to content

Commit

Permalink
Merge branch 'master' into release-0.2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
forrestguice committed Nov 18, 2024
2 parents ec8e3a3 + 4a5e37d commit a31278b
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 34 deletions.
20 changes: 13 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,23 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- name: set up JDK 1.8
uses: actions/setup-java@v1
- uses: actions/checkout@v4
- name: set up JDK 8.0.422+5
uses: actions/setup-java@v4
with:
java-version: 1.8
distribution: 'temurin'
java-version: '8.0.422+5'
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Build with Gradle
run: ./gradlew build
- name: Upload artifacts
uses: actions/upload-artifact@v1
- name: Upload artifacts (debug apk)
uses: actions/upload-artifact@v4
with:
name: app
path: app/build/outputs/apk/debug/app-debug.apk
path: app/build/outputs/apk/debug/app-debug.apk
- name: Upload artifacts (lint results)
uses: actions/upload-artifact@v4
with:
name: lint-results.html
path: app/build/reports/lint-results.html
19 changes: 16 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# Built application files
*.apk
*.ap_
*.aab

*.apk
*.apk.asc

*.tar.gz
*.tar.gz.asc

*.zip
*.zip.asc

# Files for the ART/Dalvik VM
*.dex

Expand All @@ -16,6 +24,8 @@ out/
# Uncomment the following line in case you need and you don't have the release build type files in your app
# release/

app/release/output.json

# Gradle files
.gradle/
build/
Expand All @@ -37,6 +47,9 @@ captures/

# IntelliJ
*.iml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/misc.xml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
Expand All @@ -51,8 +64,8 @@ captures/

# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
#*.jks
#*.keystore
*.jks
*.keystore

# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
Copyright (C) 2024 Forrest Guice
This file is part of SuntimesWidget.
SuntimesWidget is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
SuntimesWidget is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SuntimesWidget. If not, see <http://www.gnu.org/licenses/>.
*/

package com.forrestguice.suntimes.naturalhour.data;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ExecutorUtils
{
public static boolean runTask(String tag, @NonNull final Callable<Boolean> r, long timeoutAfter)
{
Boolean result = getResult(tag, r, timeoutAfter);
return (result != null && result);
}

@Nullable
public static <T> T getResult(String tag, @NonNull final Callable<T> callable, long timeoutAfter)
{
ExecutorService executor = Executors.newSingleThreadExecutor();
final Future<T> task = executor.submit(callable);
try {
return task.get(timeoutAfter, TimeUnit.MILLISECONDS);

} catch (TimeoutException | InterruptedException | ExecutionException e) {
Log.e(tag, "getResult: failed! " + e);
return null;

} finally {
task.cancel(true);
executor.shutdownNow();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
Copyright (C) 2020 Forrest Guice
Copyright (C) 2020-2024 Forrest Guice
This file is part of Natural Hour.
Natural Hour is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -29,6 +29,7 @@

import java.util.Arrays;
import java.util.Calendar;
import java.util.concurrent.Callable;

public class NaturalHourCalculator
{
Expand Down Expand Up @@ -89,7 +90,7 @@ public boolean queryData(ContentResolver resolver, @NonNull NaturalHourData data
data.dayEnd = daylight[1];

if (querySolsticeEquinox) {
solsticeEquinox = queryEquinoxSolsticeDates(resolver, date);
solsticeEquinox = queryEquinoxSolsticeDatesWithTimeout(resolver, date, MAX_WAIT_MS);
data.solsticeEquinox = solsticeEquinox;
}

Expand All @@ -110,7 +111,7 @@ public long[] queryTwilights(ContentResolver resolver, long date, NaturalHourDat
Double longitude = (useDefaultLocation ? null : data.longitude);
Double altitude = (useDefaultLocation ? null : data.altitude);

return queryTwilight(resolver, date, latitude, longitude, altitude, new String[] {
return queryTwilightWithTimeout(resolver, date, latitude, longitude, altitude, new String[] {
CalculatorProviderContract.COLUMN_SUN_ASTRO_RISE, // 0
CalculatorProviderContract.COLUMN_SUN_NAUTICAL_RISE, // 1
CalculatorProviderContract.COLUMN_SUN_CIVIL_RISE, // 2
Expand All @@ -119,8 +120,7 @@ public long[] queryTwilights(ContentResolver resolver, long date, NaturalHourDat
CalculatorProviderContract.COLUMN_SUN_CIVIL_SET, // 5
CalculatorProviderContract.COLUMN_SUN_NAUTICAL_SET, // 6
CalculatorProviderContract.COLUMN_SUN_ASTRO_SET } // 7

);
, MAX_WAIT_MS);
}

public long[] queryStartEndDay(ContentResolver resolver, long dateMillis, NaturalHourData data)
Expand All @@ -139,19 +139,35 @@ public long[] queryStartEndDay(ContentResolver resolver, long dateMillis, Natura
}

public long[] querySunriseSunset(ContentResolver resolver, long dateMillis, Double latitude, Double longitude, Double altitude) {
return queryTwilight(resolver, dateMillis, latitude, longitude, altitude, new String[] { CalculatorProviderContract.COLUMN_SUN_ACTUAL_RISE, CalculatorProviderContract.COLUMN_SUN_ACTUAL_SET });
return queryTwilightWithTimeout(resolver, dateMillis, latitude, longitude, altitude, new String[] { CalculatorProviderContract.COLUMN_SUN_ACTUAL_RISE, CalculatorProviderContract.COLUMN_SUN_ACTUAL_SET }, MAX_WAIT_MS);
}

public long[] queryCivilTwilight(ContentResolver resolver, long date, Double latitude, Double longitude, Double altitude) {
return queryTwilight(resolver, date, latitude, longitude, altitude, new String[] { CalculatorProviderContract.COLUMN_SUN_CIVIL_RISE, CalculatorProviderContract.COLUMN_SUN_CIVIL_SET });
return queryTwilightWithTimeout(resolver, date, latitude, longitude, altitude, new String[] { CalculatorProviderContract.COLUMN_SUN_CIVIL_RISE, CalculatorProviderContract.COLUMN_SUN_CIVIL_SET }, MAX_WAIT_MS);
}

public long[] queryNauticalTwilight(ContentResolver resolver, long date, Double latitude, Double longitude, Double altitude) {
return queryTwilight(resolver, date, latitude, longitude, altitude, new String[] { CalculatorProviderContract.COLUMN_SUN_NAUTICAL_RISE, CalculatorProviderContract.COLUMN_SUN_NAUTICAL_SET });
return queryTwilightWithTimeout(resolver, date, latitude, longitude, altitude, new String[] { CalculatorProviderContract.COLUMN_SUN_NAUTICAL_RISE, CalculatorProviderContract.COLUMN_SUN_NAUTICAL_SET }, MAX_WAIT_MS);
}

public long[] queryAstroTwilight(ContentResolver resolver, long date, Double latitude, Double longitude, Double altitude) {
return queryTwilight(resolver, date, latitude, longitude, altitude, new String[] { CalculatorProviderContract.COLUMN_SUN_ASTRO_RISE, CalculatorProviderContract.COLUMN_SUN_ASTRO_SET });
return queryTwilightWithTimeout(resolver, date, latitude, longitude, altitude, new String[] { CalculatorProviderContract.COLUMN_SUN_ASTRO_RISE, CalculatorProviderContract.COLUMN_SUN_ASTRO_SET }, MAX_WAIT_MS);
}

public static final long MAX_WAIT_MS = 1000;
public long[] queryTwilightWithTimeout(final ContentResolver resolver, final long date, final Double latitude, final Double longitude, final Double altitude, final String[] projection, long timeoutAfter)
{
long[] result = ExecutorUtils.getResult("queryTwilight", new Callable<long[]>() {
public long[] call() throws Exception {
return queryTwilight(resolver, date, latitude, longitude, altitude, projection);
}
}, timeoutAfter);

if (result == null) {
result = new long[projection.length];
Arrays.fill(result, -1);
}
return result;
}

public long[] queryTwilight(ContentResolver resolver, long date, Double latitude, Double longitude, Double altitude, String[] projection)
Expand Down Expand Up @@ -183,6 +199,20 @@ public long[] queryTwilight(ContentResolver resolver, long date, Double latitude
return retValue;
}

public long[] queryEquinoxSolsticeDatesWithTimeout(final ContentResolver resolver, final long dateMillis, long timeoutAfter)
{
long[] result = ExecutorUtils.getResult("queryEquinox", new Callable<long[]>() {
public long[] call() throws Exception {
return queryEquinoxSolsticeDates(resolver, dateMillis);
}
}, timeoutAfter);

if (result == null) {
result = new long[] {-1, -1, -1, -1};
}
return result;
}

protected long[] solsticeEquinox = new long[] {-1, -1, -1, -1};
public long[] queryEquinoxSolsticeDates(ContentResolver resolver, long dateMillis)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
/*
Copyright (C) 2020 Forrest Guice
Copyright (C) 2020-2024 Forrest Guice
This file is part of Natural Hour.
Natural Hour is free software: you can redistribute it and/or modify
Expand All @@ -19,25 +19,31 @@

package com.forrestguice.suntimes.naturalhour.data;

import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import com.forrestguice.suntimes.ContextCompat;
import com.forrestguice.suntimes.addon.SuntimesInfo;
import com.forrestguice.suntimes.alarm.AlarmHelper;
import com.forrestguice.suntimes.naturalhour.AppSettings;
import com.forrestguice.suntimes.naturalhour.BuildConfig;
import com.forrestguice.suntimes.naturalhour.R;
import com.forrestguice.suntimes.naturalhour.ui.NaturalHourFragment;
import com.forrestguice.suntimes.naturalhour.ui.clockview.ClockColorValuesCollection;
import com.forrestguice.suntimes.naturalhour.ui.clockview.NaturalHourClockBitmap;
import com.forrestguice.suntimes.naturalhour.ui.colors.ColorValues;
import com.forrestguice.suntimes.naturalhour.ui.widget.NaturalHourWidget_3x2;
import com.forrestguice.suntimes.naturalhour.ui.widget.NaturalHourWidget_4x3;
import com.forrestguice.suntimes.naturalhour.ui.widget.NaturalHourWidget_5x3;
Expand Down Expand Up @@ -221,7 +227,32 @@ public Cursor queryWidgets(@NonNull Uri uri, @Nullable String[] projection, @Nul
String[] summary = (context == null) ? new String[] {"Clock Widget (3x2)", "Clock Widget (4x3)", "Clock Widget (5x3)"}
: new String[] { context.getString(R.string.widget_summary, "3x2"), context.getString(R.string.widget_summary, "4x3"), context.getString(R.string.widget_summary, "5x3") };
int[] icons = new int[] { R.mipmap.ic_launcher_round, R.mipmap.ic_launcher_round, R.mipmap.ic_launcher_round };
return WidgetListHelper.createWidgetListCursor(getContext(), columns, widgetClass, summary, icons);
return createWidgetListCursor(getContext(), columns, widgetClass, summary, icons);
}

public static MatrixCursor createWidgetListCursor(Context context, String[] columns, Class[] widgetClass, String[] summary, int[] iconResID)
{
MatrixCursor cursor = new MatrixCursor(columns);
if (context != null)
{
ClockColorValuesCollection<ColorValues> colorCollection = new ClockColorValuesCollection<>(context); // TODO: initClockColors instead
AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
for (int i=0; i<widgetClass.length; i++)
{
int[] widgetIDs = widgetManager.getAppWidgetIds(new ComponentName(context, widgetClass[i]));
for (int appWidgetID : widgetIDs)
{
ColorValues colors = colorCollection.getSelectedColors(context, appWidgetID);
String label = (colors != null ? colors.getID() : null);
String formatString = summary[i] + " (%s)";
String summary0 = (label != null ? String.format(formatString, label) : summary[i]);

Drawable icon = ContextCompat.getDrawable(context, iconResID[i]);
cursor.addRow(WidgetListHelper.createWidgetListRow(context, widgetManager, columns, appWidgetID, widgetClass[i].getName(), summary0, icon));
}
}
}
return cursor;
}

/**
Expand Down Expand Up @@ -445,7 +476,12 @@ public static long calculateAlarmTime(@NonNull Context context, @Nullable String
Calendar day = Calendar.getInstance();
NaturalHourData data = new NaturalHourData(day.getTimeInMillis(), latitude, longitude, altitude);
calculator.calculateData(resolver, data, false, false);
eventTime = data.getNaturalHour(hour[1], momentRatio);

int i = hour[1];
int j = (hour[0] != NaturalHourClockBitmap.HOURMODE_SUNSET) ? i
: (i >= 12) ? i - 12 : i + 12;

eventTime = data.getNaturalHour(j, momentRatio);
if (eventTime != null)
{
eventTime.set(Calendar.SECOND, 0);
Expand All @@ -467,7 +503,7 @@ public static long calculateAlarmTime(@NonNull Context context, @Nullable String
day.add(Calendar.DAY_OF_YEAR, 1);
data = new NaturalHourData(day.getTimeInMillis(), latitude, longitude, altitude);
calculator.calculateData(resolver, data, false, false);
eventTime = data.getNaturalHour(hour[1], momentRatio);
eventTime = data.getNaturalHour(j, momentRatio);
if (eventTime != null)
{
eventTime.set(Calendar.SECOND, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,17 @@ public ColorValuesCollection getColorCollection() {
return colorCollection;
}

protected void initClockColors(Context context)
public static ColorValuesCollection<ClockColorValues> initClockColors(Context context)
{
colorCollection = new ClockColorValuesCollection<>(context);
ColorValuesCollection<ClockColorValues> colorCollection = new ClockColorValuesCollection<ColorValues>(context);
colorCollection.setColors(context, ClockColorValues.getColorDefaults(context, true));
colorCollection.setColors(context, ClockColorValues.getColorDefaults(context, false));

String[] defaults = context.getResources().getStringArray(R.array.clockface_collection);
for (String json : defaults) {
colorCollection.setColors(context, new ClockColorValues(json));
}
return colorCollection;
}

public NaturalHourFragment() {
Expand All @@ -144,7 +145,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
info = SuntimesInfo.queryInfo(context);
}
if (colorCollection == null) {
initClockColors(getActivity());
colorCollection = initClockColors(getActivity());
}
if (clockColors == null) {
clockColors = colorCollection.getSelectedColors(getActivity());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ protected void onColorValuesSelected(int position)
public String getSelectedID() {
if (selector != null) {
ColorValuesItem item = (ColorValuesItem) selector.getSelectedItem();
return item.colorsID;
return (item != null ? item.colorsID : null);
} else return null;
}

Expand Down
Loading

0 comments on commit a31278b

Please sign in to comment.