diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index e17c4584a..e1aa01a27 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -1,15 +1,20 @@ package nodomain.freeyourgadget.gadgetbridge; import android.app.Application; +import android.app.NotificationManager; +import android.app.NotificationManager.Policy; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.res.Resources; +import android.database.Cursor; +import android.net.Uri; import android.os.Build; import android.os.Build.VERSION; import android.preference.PreferenceManager; +import android.provider.ContactsContract.PhoneLookup; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import android.util.TypedValue; @@ -59,6 +64,7 @@ public class GBApplication extends Application { private static Appender fileLogger; private static Prefs prefs; private static GBPrefs gbPrefs; + private static NotificationManager notificationManager; public static final String ACTION_QUIT = "nodomain.freeyourgadget.gadgetbridge.gbapplication.action.quit"; @@ -119,6 +125,10 @@ public class GBApplication extends Application { filterLocal.addAction(ACTION_QUIT); LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal); + if (isRunningMarshmallowOrLater()) { + notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE); + } + // for testing DB stuff // SQLiteDatabase db = mActivityDatabaseHandler.getWritableDatabase(); // db.close(); @@ -247,6 +257,61 @@ public class GBApplication extends Application { return VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; } + public static boolean isRunningMarshmallowOrLater() { + return VERSION.SDK_INT >= Build.VERSION_CODES.M; + } + + private static boolean isPrioritySender(int prioritySenders, String number) { + if (prioritySenders == Policy.PRIORITY_SENDERS_ANY) { + return true; + } else { + Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); + String[] projection = new String[]{PhoneLookup._ID, PhoneLookup.STARRED}; + Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null); + boolean exists = false; + int starred = 0; + try { + if (cursor.moveToFirst()) { + exists = true; + starred = cursor.getInt(cursor.getColumnIndexOrThrow(PhoneLookup.STARRED)); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + if (prioritySenders == Policy.PRIORITY_SENDERS_CONTACTS && exists) { + return true; + } else if (prioritySenders == Policy.PRIORITY_SENDERS_STARRED && starred == 1) { + return true; + } + return false; + } + } + + public static boolean isPriorityNumber(int priorityType, String number) { + NotificationManager.Policy notificationPolicy = notificationManager.getNotificationPolicy(); + if(priorityType == Policy.PRIORITY_CATEGORY_MESSAGES) { + if ((notificationPolicy.priorityCategories & Policy.PRIORITY_CATEGORY_MESSAGES) == Policy.PRIORITY_CATEGORY_MESSAGES) { + return isPrioritySender(notificationPolicy.priorityMessageSenders, number); + } + } else if (priorityType == Policy.PRIORITY_CATEGORY_CALLS) { + if ((notificationPolicy.priorityCategories & Policy.PRIORITY_CATEGORY_CALLS) == Policy.PRIORITY_CATEGORY_CALLS) { + return isPrioritySender(notificationPolicy.priorityCallSenders, number); + } + } + return false; + } + + public static int getGrantedInterruptionFilter() { + if (prefs.getBoolean("notification_filter", false) && GBApplication.isRunningMarshmallowOrLater()) { + if (notificationManager.isNotificationPolicyAccessGranted()) { + return notificationManager.getCurrentInterruptionFilter(); + } + } + return NotificationManager.INTERRUPTION_FILTER_ALL; + } + public static HashSet blacklist = null; private static void loadBlackList() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java index c8bfe8356..c6479695e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java @@ -6,6 +6,7 @@ import android.content.pm.ResolveInfo; import android.os.Bundle; import android.preference.ListPreference; import android.preference.Preference; +import android.preference.PreferenceCategory; import android.support.v4.content.LocalBroadcastManager; import android.widget.Toast; @@ -107,6 +108,12 @@ public class SettingsActivity extends AbstractSettingsActivity { }); + if (!GBApplication.isRunningMarshmallowOrLater()) { + pref = findPreference("notification_filter"); + PreferenceCategory category = (PreferenceCategory) findPreference("pref_key_notifications"); + category.removePreference(pref); + } + // Get all receivers of Media Buttons Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/K9Receiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/K9Receiver.java index 899ee0c6a..439c34b09 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/K9Receiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/K9Receiver.java @@ -1,5 +1,6 @@ package nodomain.freeyourgadget.gadgetbridge.externalevents; +import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -33,6 +34,14 @@ public class K9Receiver extends BroadcastReceiver { return; } } + switch (GBApplication.getGrantedInterruptionFilter()) { + case NotificationManager.INTERRUPTION_FILTER_ALL: + break; + case NotificationManager.INTERRUPTION_FILTER_ALARMS: + case NotificationManager.INTERRUPTION_FILTER_NONE: + case NotificationManager.INTERRUPTION_FILTER_PRIORITY: + return; + } String uriWanted = intent.getData().toString(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java index 9f93618b2..a3c3d37c4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java @@ -3,6 +3,7 @@ package nodomain.freeyourgadget.gadgetbridge.externalevents; import android.annotation.SuppressLint; import android.app.ActivityManager; import android.app.Notification; +import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; @@ -167,6 +168,16 @@ public class NotificationListener extends NotificationListenerService { return; } } + switch (GBApplication.getGrantedInterruptionFilter()) { + case NotificationManager.INTERRUPTION_FILTER_ALL: + break; + case NotificationManager.INTERRUPTION_FILTER_ALARMS: + case NotificationManager.INTERRUPTION_FILTER_NONE: + return; + case NotificationManager.INTERRUPTION_FILTER_PRIORITY: + // FIXME: Handle Reminders and Events if they are enabled in Do Not Disturb + return; + } String source = sbn.getPackageName(); Notification notification = sbn.getNotification(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java index 496872db3..29693538b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java @@ -1,5 +1,7 @@ package nodomain.freeyourgadget.gadgetbridge.externalevents; +import android.app.NotificationManager; +import android.app.NotificationManager.Policy; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -67,6 +69,19 @@ public class PhoneCallReceiver extends BroadcastReceiver { if ("never".equals(prefs.getString("notification_mode_calls", "always"))) { return; } + switch (GBApplication.getGrantedInterruptionFilter()) { + case NotificationManager.INTERRUPTION_FILTER_ALL: + break; + case NotificationManager.INTERRUPTION_FILTER_ALARMS: + case NotificationManager.INTERRUPTION_FILTER_NONE: + return; + case NotificationManager.INTERRUPTION_FILTER_PRIORITY: + if (GBApplication.isPriorityNumber(Policy.PRIORITY_CATEGORY_CALLS, mSavedNumber)) { + break; + } + // FIXME: Handle Repeat callers if it is enabled in Do Not Disturb + return; + } CallSpec callSpec = new CallSpec(); callSpec.number = mSavedNumber; callSpec.command = callCommand; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java index 0404cbc22..5df07c8d6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java @@ -1,5 +1,7 @@ package nodomain.freeyourgadget.gadgetbridge.externalevents; +import android.app.NotificationManager; +import android.app.NotificationManager.Policy; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -41,6 +43,18 @@ public class SMSReceiver extends BroadcastReceiver { notificationSpec.body = message.getDisplayMessageBody(); notificationSpec.phoneNumber = message.getOriginatingAddress(); if (notificationSpec.phoneNumber != null) { + switch (GBApplication.getGrantedInterruptionFilter()) { + case NotificationManager.INTERRUPTION_FILTER_ALL: + break; + case NotificationManager.INTERRUPTION_FILTER_ALARMS: + case NotificationManager.INTERRUPTION_FILTER_NONE: + return; + case NotificationManager.INTERRUPTION_FILTER_PRIORITY: + if (GBApplication.isPriorityNumber(Policy.PRIORITY_CATEGORY_MESSAGES, notificationSpec.phoneNumber)) { + break; + } + return; + } GBApplication.deviceService().onNotification(notificationSpec); } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 133216e52..95f0f1884 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -52,6 +52,8 @@ Support for applications which send Notifications to the Pebble via Intent. Can be used for Conversations. Generic notification support … also when screen is on + Do Not Disturb + Stop unwanted Notifications from being sent based on the Do Not Disturb mode. always when screen is off diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 4def8d019..6ae2be495 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -77,6 +77,13 @@ android:defaultValue="false" android:key="notifications_generic_whenscreenon" android:title="@string/pref_title_whenscreenon" /> + + +