Skip to content

Commit

Permalink
Merge pull request #852 from forrestguice/content-provider
Browse files Browse the repository at this point in the history
content provider
  • Loading branch information
forrestguice authored Dec 1, 2024
2 parents 37e94fd + 929e31b commit 678466f
Show file tree
Hide file tree
Showing 9 changed files with 313 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ public void onClick(View v) {
*/
protected void updateViews(@NonNull Context context)
{
widgetListAdapter = WidgetListAdapter.createWidgetListAdapter(context);
widgetListAdapter = WidgetListAdapter.createWidgetListAdapter(context, false);
widgetList.setAdapter(widgetListAdapter);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
Copyright (C) 2021-2022 Forrest Guice
Copyright (C) 2021-2024 Forrest Guice
This file is part of SuntimesWidget.
SuntimesWidget is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -28,6 +28,7 @@
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;

import android.support.annotation.Nullable;
Expand All @@ -40,6 +41,13 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
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;

/**
* AlarmAddon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@
import com.forrestguice.suntimeswidget.events.EventIcons;
import com.forrestguice.suntimeswidget.events.EventSettings;
import com.forrestguice.suntimeswidget.settings.SolarEvents;
import com.forrestguice.suntimeswidget.views.ExecutorUtils;

import java.util.ArrayList;
import java.util.Set;
import java.util.concurrent.Callable;

import static com.forrestguice.suntimeswidget.alarmclock.AlarmEventContract.REPEAT_SUPPORT_BASIC;
import static com.forrestguice.suntimeswidget.alarmclock.AlarmEventContract.REPEAT_SUPPORT_DAILY;
Expand Down Expand Up @@ -120,6 +122,8 @@ public int getQuantity() {
*/
public static class AlarmEventItem
{
public static final long MAX_WAIT_MS = 1000;

protected SolarEvents event;
protected String title = "", summary = null;
protected AlarmEventPhrase phrase = null;
Expand All @@ -135,23 +139,32 @@ public AlarmEventItem( @NonNull SolarEvents event ) {
resolved = true;
}

public AlarmEventItem( @NonNull String authority, @NonNull String name, @Nullable ContentResolver resolver)
public AlarmEventItem( @NonNull String authority, @NonNull String name, @Nullable final ContentResolver resolver)
{
event = null;
uri = AlarmAddon.getEventInfoUri(authority, name);
resolved = AlarmAddon.queryDisplayStrings(this, resolver);
resolved = ExecutorUtils.runTask("AlarmEventItem", resolveItemTask(resolver), MAX_WAIT_MS);
}

public AlarmEventItem( @Nullable String eventUri, @Nullable ContentResolver resolver)
public AlarmEventItem( @Nullable String eventUri, @Nullable final ContentResolver resolver)
{
event = SolarEvents.valueOf(eventUri, null);
if (event == null) {
uri = eventUri;
title = eventUri != null ? Uri.parse(eventUri).getLastPathSegment() : "";
resolved = AlarmAddon.queryDisplayStrings(this, resolver);
resolved = ExecutorUtils.runTask("AlarmEventItem", resolveItemTask(resolver), MAX_WAIT_MS);
}
}

private Callable<Boolean> resolveItemTask(@Nullable final ContentResolver resolver)
{
return new Callable<Boolean>() {
public Boolean call() {
return AlarmAddon.queryDisplayStrings(AlarmEventItem.this, resolver);
}
};
}

@NonNull
public String getTitle() {
return (event != null ? event.getLongDisplayString() : title);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import com.forrestguice.suntimeswidget.BuildConfig;
import com.forrestguice.suntimeswidget.alarmclock.bedtime.BedtimeActivity;
import com.forrestguice.suntimeswidget.alarmclock.bedtime.BedtimeSettings;
import com.forrestguice.suntimeswidget.views.ExecutorUtils;
import com.forrestguice.suntimeswidget.views.Toast;

import com.forrestguice.suntimeswidget.R;
Expand Down Expand Up @@ -92,6 +93,7 @@
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.Callable;

public class AlarmNotifications extends BroadcastReceiver
{
Expand Down Expand Up @@ -134,6 +136,8 @@ public class AlarmNotifications extends BroadcastReceiver

public static final int NOTIFICATION_BEDTIME_ACTIVE_ID = -1000;

public static final int NOTIFICATION_ERROR_ID = -9999;

public static final String ACTION_LOCKED_BOOT_COMPLETED;
static {
if (Build.VERSION.SDK_INT >= 24) {
Expand Down Expand Up @@ -1386,6 +1390,19 @@ public static NotificationCompat.Builder warningNotificationBuilder(Context cont
return builder;
}

public static Notification createWarningNotification(Context context, String message)
{
NotificationCompat.Builder builder = warningNotificationBuilder(context);
builder.setContentText(message);

NotificationCompat.BigTextStyle style = new NotificationCompat.BigTextStyle();
style.setBigContentTitle(context.getString(R.string.app_name_alarmclock));
style.bigText(message);
builder.setStyle(style);

return builder.build();
}

public static Notification createAutostartWarningNotification(Context context)
{
NotificationCompat.Builder builder = warningNotificationBuilder(context);
Expand Down Expand Up @@ -2611,7 +2628,7 @@ public static boolean updateAlarmTime(Context context, final AlarmClockItem item
eventTime = updateAlarmTime_solarEvent(context, event, item.location, item.offset, item.repeating, repeatingDays, now);

} else if (eventID != null) {
eventTime = updateAlarmTime_addonEvent(context.getContentResolver(), eventID, item.location, item.offset, item.repeating, repeatingDays, now);
eventTime = updateAlarmTime_addonEvent(context, context.getContentResolver(), eventID, item.location, item.offset, item.repeating, repeatingDays, now);

} else {
modifyHourMinute = false; // "clock time" alarms should leave "hour" and "minute" values untouched
Expand Down Expand Up @@ -2866,7 +2883,7 @@ private static Calendar updateAlarmTime_seasonEvent(Context context, @NonNull So
return eventTime;
}

protected static Calendar updateAlarmTime_addonEvent(@Nullable ContentResolver resolver, @NonNull String eventID, @Nullable Location location, long offset, boolean repeating, @NonNull ArrayList<Integer> repeatingDays, @NonNull Calendar now)
protected static Calendar updateAlarmTime_addonEvent(Context context, @Nullable ContentResolver resolver, @NonNull String eventID, @Nullable Location location, long offset, boolean repeating, @NonNull ArrayList<Integer> repeatingDays, @NonNull Calendar now)
{
if (repeatingDays.isEmpty()) {
//Log.w(TAG, "updateAlarmTime_addonEvent: empty repeatingDays! using EVERYDAY instead..");
Expand All @@ -2875,38 +2892,53 @@ protected static Calendar updateAlarmTime_addonEvent(@Nullable ContentResolver r

Log.d(TAG, "updateAlarmTime_addonEvent: eventID: " + eventID + ", offset: " + offset + ", repeating: " + repeating + ", repeatingDays: " + repeatingDays);
long nowMillis = now.getTimeInMillis();

Uri uri_id = Uri.parse(eventID);
Uri uri_calc = Uri.parse(AlarmAddon.getEventCalcUri(uri_id.getAuthority(), uri_id.getLastPathSegment()));
if (resolver != null)
{
StringBuilder repeatingDaysString = new StringBuilder("[");
if (repeating) {
for (int i = 0; i < repeatingDays.size(); i++) {
repeatingDaysString.append(repeatingDays.get(i));
if (i != repeatingDays.size() - 1) {
repeatingDaysString.append(",");
}

StringBuilder repeatingDaysString = new StringBuilder("[");
if (repeating) {
for (int i = 0; i < repeatingDays.size(); i++) {
repeatingDaysString.append(repeatingDays.get(i));
if (i != repeatingDays.size() - 1) {
repeatingDaysString.append(",");
}
}
repeatingDaysString.append("]");
}
repeatingDaysString.append("]");

String[] selectionArgs = new String[] { Long.toString(nowMillis), Long.toString(offset), Boolean.toString(repeating), repeatingDaysString.toString() };
String selection = AlarmEventContract.EXTRA_ALARM_NOW + "=? AND "
+ AlarmEventContract.EXTRA_ALARM_OFFSET + "=? AND "
+ AlarmEventContract.EXTRA_ALARM_REPEAT + "=? AND "
+ AlarmEventContract.EXTRA_ALARM_REPEAT_DAYS + "=?";
String[] selectionArgs = new String[] { Long.toString(nowMillis), Long.toString(offset), Boolean.toString(repeating), repeatingDaysString.toString() };
String selection = AlarmEventContract.EXTRA_ALARM_NOW + "=? AND "
+ AlarmEventContract.EXTRA_ALARM_OFFSET + "=? AND "
+ AlarmEventContract.EXTRA_ALARM_REPEAT + "=? AND "
+ AlarmEventContract.EXTRA_ALARM_REPEAT_DAYS + "=?";

if (location != null)
{
selectionArgs = new String[] { Long.toString(nowMillis), Long.toString(offset), Boolean.toString(repeating), repeatingDaysString.toString(),
location.getLatitude(), location.getLongitude(), location.getAltitude() };
selection += " AND "
+ CalculatorProviderContract.COLUMN_CONFIG_LATITUDE + "=? AND "
+ CalculatorProviderContract.COLUMN_CONFIG_LONGITUDE + "=? AND "
+ CalculatorProviderContract.COLUMN_CONFIG_ALTITUDE + "=?";
if (location != null)
{
selectionArgs = new String[] { Long.toString(nowMillis), Long.toString(offset), Boolean.toString(repeating), repeatingDaysString.toString(),
location.getLatitude(), location.getLongitude(), location.getAltitude() };
selection += " AND "
+ CalculatorProviderContract.COLUMN_CONFIG_LATITUDE + "=? AND "
+ CalculatorProviderContract.COLUMN_CONFIG_LONGITUDE + "=? AND "
+ CalculatorProviderContract.COLUMN_CONFIG_ALTITUDE + "=?";
}
return queryAddonAlarmTimeWithTimeout(resolver, uri_calc, selection, selectionArgs, offset, now, MAX_WAIT_MS);
}

public static final long MAX_WAIT_MS = 990;
protected static Calendar queryAddonAlarmTimeWithTimeout(@Nullable final ContentResolver resolver, final Uri uri_calc, final String selection, final String[] selectionArgs, final long offset, final Calendar now, long timeoutAfter)
{
return ExecutorUtils.getResult(TAG, new Callable<Calendar>() {
public Calendar call() {
return queryAddonAlarmTime(resolver, uri_calc, selection, selectionArgs, offset, now);
}
}, timeoutAfter);
}

protected static Calendar queryAddonAlarmTime(@Nullable ContentResolver resolver, Uri uri_calc, String selection, String[] selectionArgs, long offset, Calendar now)
{
if (resolver != null)
{
long nowMillis = now.getTimeInMillis();
Cursor cursor = resolver.query(uri_calc, AlarmEventContract.QUERY_EVENT_CALC_PROJECTION, selection, selectionArgs, null);
if (cursor != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,14 @@
import com.forrestguice.suntimeswidget.settings.AppSettings;
import com.forrestguice.suntimeswidget.settings.PrefTypeInfo;
import com.forrestguice.suntimeswidget.settings.WidgetActions;
import com.forrestguice.suntimeswidget.views.ExecutorUtils;
import com.forrestguice.suntimeswidget.views.Toast;

import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.concurrent.Callable;

import static android.content.ContentResolver.SCHEME_ANDROID_RESOURCE;

Expand Down Expand Up @@ -535,15 +537,22 @@ public static Uri getFallbackRingtoneUri(Context context, AlarmClockItem.AlarmTy
+ (type == AlarmClockItem.AlarmType.ALARM ? R.raw.alarmsound : R.raw.notifysound));
}

public static final long MAX_WAIT_MS = 990;
public static Uri getDefaultRingtoneUri(Context context, AlarmClockItem.AlarmType type) {
return getDefaultRingtoneUri(context, type, false);
}
public static Uri getDefaultRingtoneUri(Context context, AlarmClockItem.AlarmType type, boolean resolveDefaults)
public static Uri getDefaultRingtoneUri(final Context context, final AlarmClockItem.AlarmType type, boolean resolveDefaults)
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String uriString = prefs.getString((type == AlarmClockItem.AlarmType.ALARM) ? PREF_KEY_ALARM_RINGTONE_URI_ALARM : PREF_KEY_ALARM_RINGTONE_URI_NOTIFICATION, VALUE_RINGTONE_DEFAULT);
if (resolveDefaults && VALUE_RINGTONE_DEFAULT.equals(uriString)) {
return new AlarmSettings().setDefaultRingtone(context, type);
return ExecutorUtils.getResult("defaultRingtoneUri", new Callable<Uri>()
{
public Uri call() {
Uri result = new AlarmSettings().setDefaultRingtone(context, type);
return (result != null ? result : Uri.parse(VALUE_RINGTONE_DEFAULT));
}
}, MAX_WAIT_MS);
} else return (uriString != null ? Uri.parse(uriString) : Uri.parse(VALUE_RINGTONE_DEFAULT));
}
public static String getDefaultRingtoneName(Context context, AlarmClockItem.AlarmType type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ protected void ringtonePicker(@NonNull AlarmClockItem item)
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, item.type.getDisplayString());
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, AlarmSettings.getDefaultRingtoneUri(this, item.type, true)); // TODO: setDefaultRingtoneUri may block (potential ANR)...
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, AlarmSettings.getDefaultRingtoneUri(this, item.type, true));
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, (item.ringtoneURI != null ? Uri.parse(item.ringtoneURI) : null));
startActivityForResult(Intent.createChooser(intent, getString(R.string.configAction_setAlarmSound)), REQUEST_RINGTONE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@
import com.forrestguice.suntimeswidget.alarmclock.AlarmEventContract;
import com.forrestguice.suntimeswidget.alarmclock.AlarmEventProvider;
import com.forrestguice.suntimeswidget.settings.WidgetSettings;
import com.forrestguice.suntimeswidget.views.ExecutorUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.Callable;

import static com.forrestguice.suntimeswidget.alarmclock.AlarmEventContract.AUTHORITY;

Expand Down Expand Up @@ -157,9 +159,14 @@ public Integer getColor() {
}

private String summary;
public String getSummary(Context context) {
public String getSummary(final Context context) {
if (summary == null) {
summary = resolveSummary(context);
summary = ExecutorUtils.getResult("getSummary", new Callable<String>()
{
public String call() {
return resolveSummary(context);
}
}, 1000);
}
return summary;
}
Expand Down
Loading

0 comments on commit 678466f

Please sign in to comment.