2015-04-20 22:39:35 +02:00
|
|
|
package nodomain.freeyourgadget.gadgetbridge.externalevents;
|
2015-01-07 14:00:18 +01:00
|
|
|
|
2015-09-01 21:58:36 +02:00
|
|
|
import android.annotation.SuppressLint;
|
2015-04-04 23:20:28 +02:00
|
|
|
import android.app.ActivityManager;
|
2015-01-07 14:00:18 +01:00
|
|
|
import android.app.Notification;
|
2015-08-31 22:27:25 +02:00
|
|
|
import android.app.PendingIntent;
|
2015-07-21 01:25:22 +02:00
|
|
|
import android.content.BroadcastReceiver;
|
|
|
|
import android.content.Context;
|
2015-01-07 14:00:18 +01:00
|
|
|
import android.content.Intent;
|
2015-07-21 01:25:22 +02:00
|
|
|
import android.content.IntentFilter;
|
2015-03-06 14:00:56 +01:00
|
|
|
import android.content.SharedPreferences;
|
2015-01-07 14:00:18 +01:00
|
|
|
import android.os.Bundle;
|
2015-03-04 23:47:47 +01:00
|
|
|
import android.os.PowerManager;
|
2015-03-06 14:00:56 +01:00
|
|
|
import android.preference.PreferenceManager;
|
2015-01-07 14:00:18 +01:00
|
|
|
import android.service.notification.NotificationListenerService;
|
|
|
|
import android.service.notification.StatusBarNotification;
|
2015-07-21 01:25:22 +02:00
|
|
|
import android.support.v4.content.LocalBroadcastManager;
|
2015-05-12 06:28:11 +02:00
|
|
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
2015-01-07 14:00:18 +01:00
|
|
|
|
2015-09-12 00:19:36 +02:00
|
|
|
import java.util.HashSet;
|
|
|
|
|
2015-08-21 00:58:18 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
2015-09-13 00:39:53 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
|
2015-09-16 01:09:03 +02:00
|
|
|
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
2015-04-20 22:39:35 +02:00
|
|
|
|
2015-01-07 14:00:18 +01:00
|
|
|
public class NotificationListener extends NotificationListenerService {
|
|
|
|
|
2015-05-12 06:28:11 +02:00
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(NotificationListener.class);
|
2015-01-07 14:00:18 +01:00
|
|
|
|
2015-07-21 01:25:22 +02:00
|
|
|
public static final String ACTION_DISMISS
|
|
|
|
= "nodomain.freeyourgadget.gadgetbridge.notificationlistener.action.dismiss";
|
2015-09-01 21:58:36 +02:00
|
|
|
public static final String ACTION_DISMISS_ALL
|
|
|
|
= "nodomain.freeyourgadget.gadgetbridge.notificationlistener.action.dismiss_all";
|
2015-08-31 22:27:25 +02:00
|
|
|
public static final String ACTION_OPEN
|
|
|
|
= "nodomain.freeyourgadget.gadgetbridge.notificationlistener.action.open";
|
2015-07-21 01:25:22 +02:00
|
|
|
|
|
|
|
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
2015-09-01 21:58:36 +02:00
|
|
|
@SuppressLint("NewApi")
|
2015-07-21 01:25:22 +02:00
|
|
|
@Override
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
String action = intent.getAction();
|
2015-08-31 22:27:25 +02:00
|
|
|
if (action.equals(ACTION_OPEN)) {
|
|
|
|
StatusBarNotification[] sbns = NotificationListener.this.getActiveNotifications();
|
|
|
|
int handle = intent.getIntExtra("handle", -1);
|
|
|
|
for (StatusBarNotification sbn : sbns) {
|
|
|
|
if ((int) sbn.getPostTime() == handle) {
|
|
|
|
try {
|
|
|
|
PendingIntent pi = sbn.getNotification().contentIntent;
|
|
|
|
if (pi != null) {
|
|
|
|
pi.send();
|
|
|
|
}
|
|
|
|
} catch (PendingIntent.CanceledException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (action.equals(ACTION_DISMISS)) {
|
2015-09-01 21:58:36 +02:00
|
|
|
StatusBarNotification[] sbns = NotificationListener.this.getActiveNotifications();
|
|
|
|
int handle = intent.getIntExtra("handle", -1);
|
|
|
|
for (StatusBarNotification sbn : sbns) {
|
|
|
|
if ((int) sbn.getPostTime() == handle) {
|
|
|
|
if (GBApplication.isRunningLollipopOrLater()) {
|
|
|
|
String key = sbn.getKey();
|
|
|
|
NotificationListener.this.cancelNotification(key);
|
|
|
|
} else {
|
|
|
|
int id = sbn.getId();
|
|
|
|
String pkg = sbn.getPackageName();
|
|
|
|
String tag = sbn.getTag();
|
|
|
|
NotificationListener.this.cancelNotification(pkg, tag, id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (action.equals(ACTION_DISMISS_ALL)) {
|
2015-07-21 01:25:22 +02:00
|
|
|
NotificationListener.this.cancelAllNotifications();
|
|
|
|
}
|
2015-09-01 21:58:36 +02:00
|
|
|
|
2015-07-21 01:25:22 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-01-07 14:00:18 +01:00
|
|
|
@Override
|
|
|
|
public void onCreate() {
|
|
|
|
super.onCreate();
|
2015-07-21 01:25:22 +02:00
|
|
|
IntentFilter filterLocal = new IntentFilter();
|
2015-08-31 22:27:25 +02:00
|
|
|
filterLocal.addAction(ACTION_OPEN);
|
2015-09-01 21:58:36 +02:00
|
|
|
filterLocal.addAction(ACTION_DISMISS);
|
|
|
|
filterLocal.addAction(ACTION_DISMISS_ALL);
|
2015-07-21 01:25:22 +02:00
|
|
|
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
|
2015-01-07 14:00:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
2015-07-21 01:25:22 +02:00
|
|
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
|
2015-01-07 14:00:18 +01:00
|
|
|
super.onDestroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onNotificationPosted(StatusBarNotification sbn) {
|
2015-04-04 23:20:28 +02:00
|
|
|
/*
|
2015-08-04 01:01:14 +02:00
|
|
|
* return early if DeviceCommunicationService is not running,
|
2015-04-04 23:20:28 +02:00
|
|
|
* else the service would get started every time we get a notification.
|
|
|
|
* unfortunately we cannot enable/disable NotificationListener at runtime like we do with
|
|
|
|
* broadcast receivers because it seems to invalidate the permissions that are
|
2015-08-06 22:24:44 +02:00
|
|
|
* necessary for NotificationListenerService
|
2015-04-04 23:20:28 +02:00
|
|
|
*/
|
2015-08-06 22:24:44 +02:00
|
|
|
if (!isServiceRunning()) {
|
2015-04-04 23:20:28 +02:00
|
|
|
return;
|
|
|
|
}
|
2015-03-04 23:47:47 +01:00
|
|
|
|
2015-03-06 14:00:56 +01:00
|
|
|
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
if (!sharedPrefs.getBoolean("notifications_generic_whenscreenon", false)) {
|
|
|
|
PowerManager powermanager = (PowerManager) getSystemService(POWER_SERVICE);
|
|
|
|
if (powermanager.isScreenOn()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2015-03-04 23:47:47 +01:00
|
|
|
|
2015-05-08 12:50:42 +02:00
|
|
|
String source = sbn.getPackageName();
|
2015-01-07 14:00:18 +01:00
|
|
|
Notification notification = sbn.getNotification();
|
2015-01-18 22:44:38 +01:00
|
|
|
|
2015-05-08 12:50:42 +02:00
|
|
|
if ((notification.flags & Notification.FLAG_ONGOING_EVENT) == Notification.FLAG_ONGOING_EVENT) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-01-18 22:44:38 +01:00
|
|
|
/* do not display messages from "android"
|
|
|
|
* This includes keyboard selection message, usb connection messages, etc
|
|
|
|
* Hope it does not filter out too much, we will see...
|
|
|
|
*/
|
2015-01-24 12:21:15 +01:00
|
|
|
|
|
|
|
if (source.equals("android") ||
|
2015-04-09 18:48:52 +02:00
|
|
|
source.equals("com.android.systemui") ||
|
2015-01-24 12:21:15 +01:00
|
|
|
source.equals("com.android.dialer") ||
|
2015-09-05 21:32:46 +02:00
|
|
|
source.equals("com.cyanogenmod.eleven")) {
|
2015-01-18 22:44:38 +01:00
|
|
|
return;
|
2015-01-24 12:21:15 +01:00
|
|
|
}
|
2015-01-18 22:44:38 +01:00
|
|
|
|
2015-05-08 12:50:42 +02:00
|
|
|
if (source.equals("eu.siacs.conversations")) {
|
2015-05-10 15:07:28 +02:00
|
|
|
if (!"never".equals(sharedPrefs.getString("notification_mode_pebblemsg", "when_screen_off"))) {
|
2015-05-08 12:50:42 +02:00
|
|
|
return;
|
|
|
|
}
|
2015-03-04 23:47:47 +01:00
|
|
|
}
|
|
|
|
|
2015-09-05 21:32:46 +02:00
|
|
|
if (source.equals("com.fsck.k9")) {
|
|
|
|
if (!"never".equals(sharedPrefs.getString("notification_mode_k9mail", "when_screen_off"))) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-16 01:09:03 +02:00
|
|
|
if (source.equals("com.moez.QKSMS") || source.equals("com.android.mms")) {
|
2015-09-13 22:47:56 +02:00
|
|
|
if (!"never".equals(sharedPrefs.getString("notification_mode_sms", "when_screen_off"))) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-12 00:19:36 +02:00
|
|
|
HashSet<String> blacklist = (HashSet<String>) sharedPrefs.getStringSet("package_blacklist", null);
|
|
|
|
if (blacklist != null && blacklist.contains(source)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-09-13 00:39:53 +02:00
|
|
|
// Set application icons for generic notifications
|
2015-09-13 13:38:11 +02:00
|
|
|
NotificationKind notificationKind;
|
2015-09-13 13:48:21 +02:00
|
|
|
switch (source) {
|
|
|
|
case "org.mariotaku.twidere":
|
|
|
|
case "com.twitter.android":
|
|
|
|
case "org.andstatus.app":
|
|
|
|
case "org.mustard.android":
|
|
|
|
notificationKind = NotificationKind.TWITTER;
|
|
|
|
break;
|
|
|
|
case "com.fsck.k9":
|
|
|
|
case "com.android.email":
|
|
|
|
notificationKind = NotificationKind.EMAIL;
|
|
|
|
break;
|
2015-09-13 22:47:56 +02:00
|
|
|
case "com.moez.QKSMS":
|
|
|
|
notificationKind = NotificationKind.SMS;
|
|
|
|
break;
|
2015-09-13 13:48:21 +02:00
|
|
|
case "eu.siacs.conversations":
|
|
|
|
notificationKind = NotificationKind.CHAT;
|
|
|
|
break;
|
|
|
|
case "org.indywidualni.fblite":
|
|
|
|
notificationKind = NotificationKind.FACEBOOK;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
notificationKind = NotificationKind.UNDEFINED;
|
|
|
|
break;
|
2015-09-13 00:39:53 +02:00
|
|
|
}
|
|
|
|
|
2015-05-12 06:28:11 +02:00
|
|
|
LOG.info("Processing notification from source " + source);
|
2015-01-22 22:49:50 +01:00
|
|
|
|
2015-01-07 14:00:18 +01:00
|
|
|
Bundle extras = notification.extras;
|
2015-01-26 18:52:19 +01:00
|
|
|
String title = extras.getCharSequence(Notification.EXTRA_TITLE).toString();
|
2015-05-04 01:03:56 +02:00
|
|
|
String content = null;
|
2015-05-10 15:07:28 +02:00
|
|
|
if (extras.containsKey(Notification.EXTRA_TEXT)) {
|
2015-01-26 18:52:19 +01:00
|
|
|
CharSequence contentCS = extras.getCharSequence(Notification.EXTRA_TEXT);
|
|
|
|
if (contentCS != null) {
|
|
|
|
content = contentCS.toString();
|
|
|
|
}
|
|
|
|
}
|
2015-01-12 00:35:15 +01:00
|
|
|
|
2015-05-10 15:07:28 +02:00
|
|
|
if (content != null) {
|
2015-09-13 13:38:11 +02:00
|
|
|
GBApplication.deviceService().onGenericNotification(title, content, (int) sbn.getPostTime(), notificationKind); //FIMXE: a truly unique id would be better
|
2015-01-12 00:35:15 +01:00
|
|
|
}
|
2015-01-07 14:00:18 +01:00
|
|
|
}
|
|
|
|
|
2015-08-06 22:24:44 +02:00
|
|
|
private boolean isServiceRunning() {
|
|
|
|
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
|
|
|
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
|
|
|
|
if (DeviceCommunicationService.class.getName().equals(service.service.getClassName())) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-01-07 14:00:18 +01:00
|
|
|
@Override
|
|
|
|
public void onNotificationRemoved(StatusBarNotification sbn) {
|
|
|
|
|
|
|
|
}
|
2015-09-13 00:39:53 +02:00
|
|
|
}
|