package com.james.status.services;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v7.app.NotificationCompat;
import com.james.status.R;
import com.james.status.data.AppData;
import com.james.status.data.NotificationData;
import com.james.status.data.icon.NotificationsIconData;
import com.james.status.utils.PreferenceUtils;
import com.james.status.utils.StaticUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@TargetApi(18)
public class NotificationService extends NotificationListenerService {
public static final String ACTION_GET_NOTIFICATIONS = "com.james.status.ACTION_GET_NOTIFICATIONS";
public static final String ACTION_CANCEL_NOTIFICATION = "com.james.status.ACTION_CANCEL_NOTIFICATION";
public static final String EXTRA_NOTIFICATION = "com.james.status.EXTRA_NOTIFICATION";
public static final int BLANK_NOTIFICATION = 254231;
private boolean isConnected, shouldSendOnConnect;
private PackageManager packageManager;
private NotificationManagerCompat notificationManager;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent == null) return START_STICKY;
String action = intent.getAction();
if (action == null) return START_STICKY;
switch (action) {
case ACTION_GET_NOTIFICATIONS:
if (isConnected) sendNotifications();
else shouldSendOnConnect = true;
break;
case ACTION_CANCEL_NOTIFICATION:
NotificationData notification = intent.getParcelableExtra(EXTRA_NOTIFICATION);
if (isConnected && notification != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
cancelNotification(notification.key);
else
cancelNotification(notification.packageName, notification.tag, notification.id);
}
break;
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onListenerConnected() {
super.onListenerConnected();
packageManager = getPackageManager();
notificationManager = NotificationManagerCompat.from(this);
isConnected = true;
if (shouldSendOnConnect) {
sendNotifications();
shouldSendOnConnect = false;
}
}
@Override
public void onListenerDisconnected() {
super.onListenerDisconnected();
isConnected = false;
}
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
Boolean enabled = PreferenceUtils.getBooleanPreference(this, PreferenceUtils.PreferenceIdentifier.STATUS_ENABLED);
AppData app = null;
try {
app = new AppData(packageManager, packageManager.getApplicationInfo(sbn.getPackageName(), PackageManager.GET_META_DATA), packageManager.getPackageInfo(sbn.getPackageName(), PackageManager.GET_ACTIVITIES));
} catch (PackageManager.NameNotFoundException ignored) {
}
Boolean isEnabled = null;
if (app != null)
isEnabled = app.getSpecificBooleanPreference(this, AppData.PreferenceIdentifier.NOTIFICATIONS);
if (isEnabled == null) isEnabled = true;
if (enabled != null && enabled && isEnabled && !StaticUtils.shouldUseCompatNotifications(this) && !sbn.getPackageName().matches("com.james.status")) {
NotificationData notification = new NotificationData(sbn, getKey(sbn));
if (notification.shouldShowHeadsUp(this)) {
if (sbn.getId() != BLANK_NOTIFICATION) {
notificationManager.notify(BLANK_NOTIFICATION, new Notification.Builder(this)
.setContentTitle("").setContentText("")
.setSmallIcon(R.drawable.transparent)
.setPriority(Notification.PRIORITY_DEFAULT)
.setFullScreenIntent(PendingIntent.getBroadcast(this, 0, new Intent(), 0), true)
.setAutoCancel(true)
.build());
notificationManager.cancel(BLANK_NOTIFICATION);
} else return;
}
Intent intent = new Intent(NotificationsIconData.ACTION_NOTIFICATION_ADDED);
intent.putExtra(NotificationsIconData.EXTRA_NOTIFICATION, notification);
sendBroadcast(intent);
}
}
@Override
public void onNotificationRemoved(StatusBarNotification sbn) {
Boolean enabled = PreferenceUtils.getBooleanPreference(this, PreferenceUtils.PreferenceIdentifier.STATUS_ENABLED);
if (enabled != null && enabled && !StaticUtils.shouldUseCompatNotifications(this)) {
Intent intent = new Intent(NotificationsIconData.ACTION_NOTIFICATION_REMOVED);
intent.putExtra(NotificationsIconData.EXTRA_NOTIFICATION, new NotificationData(sbn, getKey(sbn)));
sendBroadcast(intent);
}
}
private ArrayList<StatusBarNotification> getNotifications() {
ArrayList<StatusBarNotification> activeNotifications = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
activeNotifications.addAll(Arrays.asList(getActiveNotifications()));
}
return activeNotifications;
}
private void sendNotifications() {
Boolean enabled = PreferenceUtils.getBooleanPreference(this, PreferenceUtils.PreferenceIdentifier.STATUS_ENABLED);
if (enabled != null && enabled && !StaticUtils.shouldUseCompatNotifications(this)) {
List<StatusBarNotification> notifications = getNotifications();
Collections.reverse(notifications);
for (StatusBarNotification sbn : notifications) {
if (sbn.getPackageName().matches("com.james.status"))
continue;
AppData app = null;
try {
app = new AppData(packageManager, packageManager.getApplicationInfo(sbn.getPackageName(), PackageManager.GET_META_DATA), packageManager.getPackageInfo(sbn.getPackageName(), PackageManager.GET_ACTIVITIES));
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
Boolean isEnabled = null;
if (app != null)
isEnabled = app.getSpecificBooleanPreference(this, AppData.PreferenceIdentifier.NOTIFICATIONS);
if (isEnabled != null && !isEnabled) continue;
NotificationData notification = new NotificationData(sbn, getKey(sbn));
notification.priority = NotificationCompat.PRIORITY_DEFAULT;
Intent intent = new Intent(NotificationsIconData.ACTION_NOTIFICATION_ADDED);
intent.putExtra(NotificationsIconData.EXTRA_NOTIFICATION, notification);
sendBroadcast(intent);
}
}
}
private String getKey(StatusBarNotification statusBarNotification) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
return statusBarNotification.getKey();
else
return statusBarNotification.getPackageName() + "/" + String.valueOf(statusBarNotification.getId());
}
}