mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-30 22:12:55 +01:00
Allow configuration of notification times
This commit is contained in:
parent
dc0b044977
commit
20f4248e1c
@ -22,14 +22,12 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.externalevents;
|
package nodomain.freeyourgadget.gadgetbridge.externalevents;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
@ -53,6 +51,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.time.LocalTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -81,6 +80,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.BitmapUtil;
|
import nodomain.freeyourgadget.gadgetbridge.util.BitmapUtil;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
|
import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.MediaManager;
|
import nodomain.freeyourgadget.gadgetbridge.util.MediaManager;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
|
||||||
@ -120,8 +120,8 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
add("mikado.bizcalpro");
|
add("mikado.bizcalpro");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
public static ArrayList<String> notificationStack = new ArrayList<>();
|
public static final ArrayList<String> notificationStack = new ArrayList<>();
|
||||||
private static ArrayList<Integer> notificationsActive = new ArrayList<Integer>();
|
private static final ArrayList<Integer> notificationsActive = new ArrayList<>();
|
||||||
|
|
||||||
private long activeCallPostTime;
|
private long activeCallPostTime;
|
||||||
private int mLastCallCommand = CallSpec.CALL_UNDEFINED;
|
private int mLastCallCommand = CallSpec.CALL_UNDEFINED;
|
||||||
@ -130,7 +130,7 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
private Runnable mSetMusicInfoRunnable = null;
|
private Runnable mSetMusicInfoRunnable = null;
|
||||||
private Runnable mSetMusicStateRunnable = null;
|
private Runnable mSetMusicStateRunnable = null;
|
||||||
|
|
||||||
private GoogleMapsNotificationHandler googleMapsNotificationHandler = new GoogleMapsNotificationHandler();
|
private final GoogleMapsNotificationHandler googleMapsNotificationHandler = new GoogleMapsNotificationHandler();
|
||||||
|
|
||||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||||
|
|
||||||
@ -163,8 +163,8 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
if (pi != null) {
|
if (pi != null) {
|
||||||
pi.send();
|
pi.send();
|
||||||
}
|
}
|
||||||
} catch (PendingIntent.CanceledException e) {
|
} catch (final PendingIntent.CanceledException e) {
|
||||||
e.printStackTrace();
|
LOG.error("Failed to open notification {}", sbn.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,7 +176,7 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
LOG.info("could not lookup handle for mute action");
|
LOG.info("could not lookup handle for mute action");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LOG.info("going to mute " + packageName);
|
LOG.info("going to mute {}", packageName);
|
||||||
if (GBApplication.getPrefs().getString("notification_list_is_blacklist", "true").equals("true")) {
|
if (GBApplication.getPrefs().getString("notification_list_is_blacklist", "true").equals("true")) {
|
||||||
GBApplication.addAppToNotifBlacklist(packageName);
|
GBApplication.addAppToNotifBlacklist(packageName);
|
||||||
} else {
|
} else {
|
||||||
@ -206,6 +206,10 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
String reply = intent.getStringExtra("reply");
|
String reply = intent.getStringExtra("reply");
|
||||||
if (wearableAction != null) {
|
if (wearableAction != null) {
|
||||||
PendingIntent actionIntent = wearableAction.getActionIntent();
|
PendingIntent actionIntent = wearableAction.getActionIntent();
|
||||||
|
if (actionIntent == null) {
|
||||||
|
LOG.warn("Action intent is null");
|
||||||
|
break;
|
||||||
|
}
|
||||||
Intent localIntent = new Intent();
|
Intent localIntent = new Intent();
|
||||||
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
if (wearableAction.getRemoteInputs() != null && wearableAction.getRemoteInputs().length > 0) {
|
if (wearableAction.getRemoteInputs() != null && wearableAction.getRemoteInputs().length > 0) {
|
||||||
@ -218,8 +222,8 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
LOG.info("will send exec intent to remote application");
|
LOG.info("will send exec intent to remote application");
|
||||||
actionIntent.send(context, 0, localIntent);
|
actionIntent.send(context, 0, localIntent);
|
||||||
mActionLookup.remove(handle);
|
mActionLookup.remove(handle);
|
||||||
} catch (PendingIntent.CanceledException e) {
|
} catch (final PendingIntent.CanceledException e) {
|
||||||
LOG.warn("replyToLastNotification error: " + e.getLocalizedMessage());
|
LOG.warn("replyToLastNotification error", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG.warn("Received ACTION_REPLY but cannot find the corresponding wearableAction");
|
LOG.warn("Received ACTION_REPLY but cannot find the corresponding wearableAction");
|
||||||
@ -264,7 +268,11 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
|
|
||||||
if (isServiceNotRunningAndShouldIgnoreNotifications()) return;
|
if (isServiceNotRunningAndShouldIgnoreNotifications()) return;
|
||||||
|
|
||||||
final Prefs prefs = GBApplication.getPrefs();
|
final GBPrefs prefs = GBApplication.getPrefs();
|
||||||
|
|
||||||
|
if (isOutsideNotificationTimes(prefs)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final boolean ignoreWorkProfile = prefs.getBoolean("notifications_ignore_work_profile", false);
|
final boolean ignoreWorkProfile = prefs.getBoolean("notifications_ignore_work_profile", false);
|
||||||
if (ignoreWorkProfile && isWorkProfile(sbn)) {
|
if (ignoreWorkProfile && isWorkProfile(sbn)) {
|
||||||
@ -458,6 +466,30 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
GBApplication.deviceService().onNotification(notificationSpec);
|
GBApplication.deviceService().onNotification(notificationSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isOutsideNotificationTimes(final GBPrefs prefs) {
|
||||||
|
if (!prefs.getNotificationTimesEnabled()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final LocalTime now = LocalTime.now();
|
||||||
|
final LocalTime start = prefs.getNotificationTimesStart();
|
||||||
|
final LocalTime end = prefs.getNotificationTimesEnd();
|
||||||
|
final boolean shouldIgnore;
|
||||||
|
if (start.isBefore(end)) {
|
||||||
|
// eg. 06:00 -> 22:00
|
||||||
|
shouldIgnore = now.isAfter(start) && now.isBefore(end);
|
||||||
|
} else {
|
||||||
|
// goes past midnight, eg. 22:00 -> 06:00
|
||||||
|
shouldIgnore = now.isAfter(start) || now.isBefore(end);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldIgnore) {
|
||||||
|
LOG.debug("Ignoring notification outside of notification times {}/{}", start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shouldIgnore;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean checkNotificationContentForWhiteAndBlackList(String packageName, String body) {
|
private boolean checkNotificationContentForWhiteAndBlackList(String packageName, String body) {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
@ -707,7 +739,11 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
|
|
||||||
if (isServiceNotRunningAndShouldIgnoreNotifications()) return;
|
if (isServiceNotRunningAndShouldIgnoreNotifications()) return;
|
||||||
|
|
||||||
final Prefs prefs = GBApplication.getPrefs();
|
final GBPrefs prefs = GBApplication.getPrefs();
|
||||||
|
|
||||||
|
if (isOutsideNotificationTimes(prefs)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final boolean ignoreWorkProfile = prefs.getBoolean("notifications_ignore_work_profile", false);
|
final boolean ignoreWorkProfile = prefs.getBoolean("notifications_ignore_work_profile", false);
|
||||||
if (ignoreWorkProfile && isWorkProfile(sbn)) {
|
if (ignoreWorkProfile && isWorkProfile(sbn)) {
|
||||||
|
@ -31,6 +31,7 @@ import android.util.Log;
|
|||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
|
import java.time.LocalTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
@ -153,4 +154,16 @@ public class GBPrefs extends Prefs {
|
|||||||
}
|
}
|
||||||
return new float[]{longitude, latitude};
|
return new float[]{longitude, latitude};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getNotificationTimesEnabled() {
|
||||||
|
return getBoolean("notification_times_enabled", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalTime getNotificationTimesStart() {
|
||||||
|
return getLocalTime("notification_times_start", "08:00");
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalTime getNotificationTimesEnd() {
|
||||||
|
return getLocalTime("notification_times_end", "22:00");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,11 @@ import android.util.Log;
|
|||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.LocalTime;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -178,6 +181,7 @@ public class Prefs {
|
|||||||
return getList(key, defaultValue, ",");
|
return getList(key, defaultValue, ",");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated // use getLocalTime
|
||||||
public Date getTimePreference(final String key, final String defaultValue) {
|
public Date getTimePreference(final String key, final String defaultValue) {
|
||||||
final String time = getString(key, defaultValue);
|
final String time = getString(key, defaultValue);
|
||||||
|
|
||||||
@ -191,6 +195,23 @@ public class Prefs {
|
|||||||
return new Date();
|
return new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LocalTime getLocalTime(final String key, final String defaultValue) {
|
||||||
|
final String time = getString(key, defaultValue);
|
||||||
|
|
||||||
|
final DateFormat df = new SimpleDateFormat("HH:mm", Locale.ROOT);
|
||||||
|
try {
|
||||||
|
final Date parse = df.parse(time);
|
||||||
|
final Calendar calendar = GregorianCalendar.getInstance();
|
||||||
|
calendar.setTime(parse);
|
||||||
|
|
||||||
|
return LocalTime.of(calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), 0);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
Log.e(TAG, "Error reading localtime preference value: " + key + "; returning default current time", e); // log the first exception
|
||||||
|
}
|
||||||
|
|
||||||
|
return LocalTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
private void logReadError(String key, Exception ex) {
|
private void logReadError(String key, Exception ex) {
|
||||||
Log.e(TAG, "Error reading preference value: " + key + "; returning default value", ex); // log the first exception
|
Log.e(TAG, "Error reading preference value: " + key + "; returning default value", ex); // log the first exception
|
||||||
}
|
}
|
||||||
|
@ -269,6 +269,8 @@
|
|||||||
<string name="pref_summary_notification_cache_while_disconnected">Send missed notifications when a device reconnects after being out of range</string>
|
<string name="pref_summary_notification_cache_while_disconnected">Send missed notifications when a device reconnects after being out of range</string>
|
||||||
<string name="pref_title_notification_filter">Do Not Disturb</string>
|
<string name="pref_title_notification_filter">Do Not Disturb</string>
|
||||||
<string name="pref_summary_notification_filter">Block all notifications when Do Not Disturb is enabled on the phone</string>
|
<string name="pref_summary_notification_filter">Block all notifications when Do Not Disturb is enabled on the phone</string>
|
||||||
|
<string name="pref_title_notification_times_enabled">Notification times</string>
|
||||||
|
<string name="pref_summary_notification_times_enabled">Only send notifications between specific times</string>
|
||||||
<string name="pref_title_notification_media_ignores_application_list">Media notifications ignore app list</string>
|
<string name="pref_title_notification_media_ignores_application_list">Media notifications ignore app list</string>
|
||||||
<string name="pref_summary_notification_media_ignores_application_list">Process media notifications before the app list. If this preference is unchecked, media applications need to be allowed in the application list for media controls to work on the device.</string>
|
<string name="pref_summary_notification_media_ignores_application_list">Process media notifications before the app list. If this preference is unchecked, media applications need to be allowed in the application list for media controls to work on the device.</string>
|
||||||
<string name="pref_header_notification_application_settings">Per application settings</string>
|
<string name="pref_header_notification_application_settings">Per application settings</string>
|
||||||
|
@ -130,6 +130,34 @@
|
|||||||
android:summary="@string/pref_summary_notification_filter"
|
android:summary="@string/pref_summary_notification_filter"
|
||||||
android:title="@string/pref_title_notification_filter"
|
android:title="@string/pref_title_notification_filter"
|
||||||
app:iconSpaceReserved="false" />
|
app:iconSpaceReserved="false" />
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:title="@string/pref_title_notification_times_enabled"
|
||||||
|
app:iconSpaceReserved="false">
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="notification_times_enabled"
|
||||||
|
android:layout="@layout/preference_checkbox"
|
||||||
|
android:summary="@string/pref_summary_notification_times_enabled"
|
||||||
|
android:title="@string/pref_title_notification_times_enabled"
|
||||||
|
app:iconSpaceReserved="false" />
|
||||||
|
|
||||||
|
<nodomain.freeyourgadget.gadgetbridge.util.XTimePreference
|
||||||
|
android:defaultValue="08:00"
|
||||||
|
android:dependency="notification_times_enabled"
|
||||||
|
android:key="notification_times_start"
|
||||||
|
android:title="@string/mi2_prefs_do_not_disturb_start"
|
||||||
|
app:iconSpaceReserved="false"/>
|
||||||
|
|
||||||
|
<nodomain.freeyourgadget.gadgetbridge.util.XTimePreference
|
||||||
|
android:defaultValue="22:00"
|
||||||
|
android:dependency="notification_times_enabled"
|
||||||
|
android:key="notification_times_end"
|
||||||
|
android:title="@string/mi2_prefs_do_not_disturb_end"
|
||||||
|
app:iconSpaceReserved="false"/>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
Loading…
Reference in New Issue
Block a user