Skip to content

Commit

Permalink
Move all notification handling into common file
Browse files Browse the repository at this point in the history
  • Loading branch information
Nutomic committed Oct 3, 2017
1 parent e184c43 commit 4c2b325
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
import com.nutomic.syncthingandroid.activities.FirstStartActivity;
import com.nutomic.syncthingandroid.activities.FolderPickerActivity;
import com.nutomic.syncthingandroid.activities.MainActivity;
import com.nutomic.syncthingandroid.receiver.AppConfigReceiver;
import com.nutomic.syncthingandroid.service.DeviceStateHolder;
import com.nutomic.syncthingandroid.service.EventProcessor;
import com.nutomic.syncthingandroid.service.NotificationHandler;
import com.nutomic.syncthingandroid.service.RestApi;
import com.nutomic.syncthingandroid.service.SyncthingRunnable;
import com.nutomic.syncthingandroid.service.SyncthingService;
import com.nutomic.syncthingandroid.util.Languages;
Expand All @@ -26,4 +29,7 @@ public interface DaggerComponent {
void inject(DeviceStateHolder deviceStateHolder);
void inject(EventProcessor eventProcessor);
void inject(SyncthingRunnable syncthingRunnable);
void inject(NotificationHandler notificationHandler);
void inject(AppConfigReceiver appConfigReceiver);
void inject(RestApi restApi);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

import com.nutomic.syncthingandroid.service.NotificationHandler;

import javax.inject.Singleton;

import dagger.Module;
Expand All @@ -22,4 +24,10 @@ public SyncthingModule(SyncthingApp app) {
public SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(mApp);
}

@Provides
@Singleton
public NotificationHandler getNotificationHandler() {
return new NotificationHandler(mApp);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
package com.nutomic.syncthingandroid.activities;

import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;

import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.service.SyncthingService;
import com.nutomic.syncthingandroid.service.NotificationHandler;

/**
* Shows restart dialog.
Expand All @@ -20,8 +14,6 @@
*/
public class RestartActivity extends SyncthingActivity {

public static final int NOTIFICATION_RESTART = 2;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All @@ -48,20 +40,7 @@ protected void onCreate(Bundle savedInstanceState) {
* Creates a notification prompting the user to restart the app.
*/
private void createRestartNotification() {
Intent intent = new Intent(this, SyncthingService.class)
.setAction(SyncthingService.ACTION_RESTART);
PendingIntent pi = PendingIntent.getService(this, 0, intent, 0);

Notification n = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.restart_title))
.setContentText(getString(R.string.restart_notification_text))
.setSmallIcon(R.drawable.ic_stat_notify)
.setContentIntent(pi)
.build();
n.flags |= Notification.FLAG_ONLY_ALERT_ONCE | Notification.FLAG_AUTO_CANCEL;
NotificationManager nm = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(NOTIFICATION_RESTART, n);
new NotificationHandler(getService()).showRestartNotification();
getApi().setRestartPostponed();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
package com.nutomic.syncthingandroid.receiver;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.support.v4.app.NotificationCompat;

import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.activities.MainActivity;
import com.nutomic.syncthingandroid.SyncthingApp;
import com.nutomic.syncthingandroid.service.NotificationHandler;
import com.nutomic.syncthingandroid.service.SyncthingService;

import javax.inject.Inject;

/**
* Broadcast-receiver to control and configure SyncThing remotely
*
* Created by sqrt-1764 on 25.03.16.
*/
public class AppConfigReceiver extends BroadcastReceiver {
private static final int ID_NOTIFICATION_BACKGROUND_ACTIVE = 3;

/**
* Start the Syncthing-Service
Expand All @@ -33,40 +29,19 @@ public class AppConfigReceiver extends BroadcastReceiver {
*/
public static final String ACTION_STOP = "com.nutomic.syncthingandroid.action.STOP";

@Inject NotificationHandler mNotificationHandler;

@Override
public void onReceive(Context context, Intent intent) {
((SyncthingApp) context.getApplicationContext()).component().inject(this);
switch (intent.getAction()) {
case ACTION_START:
context.startService(new Intent(context, SyncthingService.class));
break;

case ACTION_STOP:
if (SyncthingService.alwaysRunInBackground(context)) {
final String msg = context.getString(R.string.appconfig_receiver_background_enabled);

Context appContext = context.getApplicationContext();

NotificationCompat.Builder nb = new NotificationCompat.Builder(context)
.setContentText(msg)
.setTicker(msg)
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentTitle(context.getText(context.getApplicationInfo().labelRes))
.setSmallIcon(R.drawable.ic_stat_notify)
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(appContext,
0,
new Intent(appContext, MainActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT));

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
nb.setCategory(Notification.CATEGORY_ERROR); // Only supported in API 21 or better
}

NotificationManager nm =
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);

nm.notify(ID_NOTIFICATION_BACKGROUND_ACTIVE, nb.build());

mNotificationHandler.showStopSyncthingWarningNotification();
} else {
context.stopService(new Intent(context, SyncthingService.class));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
package com.nutomic.syncthingandroid.service;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.annimon.stream.Stream;
Expand Down Expand Up @@ -56,6 +52,7 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene
private final Context mContext;
private final RestApi mApi;
@Inject SharedPreferences mPreferences;
@Inject NotificationHandler mNotificationHandler;

public EventProcessor(Context context, RestApi api) {
((SyncthingApp) context.getApplicationContext()).component().inject(this);
Expand Down Expand Up @@ -200,20 +197,9 @@ public void shutdown() {
}

private void notify(String text, PendingIntent pi) {
NotificationManager nm = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Notification n = new NotificationCompat.Builder(mContext)
.setContentTitle(mContext.getString(R.string.app_name))
.setContentText(text)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(text))
.setContentIntent(pi)
.setSmallIcon(R.drawable.ic_stat_notify)
.setAutoCancel(true)
.build();
// HACK: Use a random, deterministic ID between 1000 and 2000 to avoid duplicate
// notifications.
int notificationId = 1000 + text.hashCode() % 1000;
nm.notify(notificationId, n);
mNotificationHandler.showEventNotification(text, pi, notificationId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package com.nutomic.syncthingandroid.service;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.support.v4.app.NotificationCompat;

import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.SyncthingApp;
import com.nutomic.syncthingandroid.activities.FirstStartActivity;
import com.nutomic.syncthingandroid.activities.MainActivity;

import javax.inject.Inject;

public class NotificationHandler {

private static final int ID_PERSISTENT = 1;
private static final int ID_RESTART = 2;
private static final int ID_STOP_BACKGROUND_WARNING = 3;
private static final int ID_CRASH = 9;

private final Context mContext;
@Inject SharedPreferences mPreferences;
private final NotificationManager mNotificationManager;

public NotificationHandler(Context context) {
((SyncthingApp) context.getApplicationContext()).component().inject(this);
mContext = context;
mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
}

/**
* Shows or hides the persistent notification based on running state and
* {@link SyncthingService#PREF_NOTIFICATION_TYPE}.
*/
public void updatePersistentNotification(SyncthingService service, SyncthingService.State currentState) {
String type = mPreferences.getString(SyncthingService.PREF_NOTIFICATION_TYPE, "low_priority");
boolean foreground = mPreferences.getBoolean(SyncthingService.PREF_FOREGROUND_SERVICE, false);
if ("none".equals(type) && foreground) {
// foreground priority requires any notification
// so this ensures that we either have a "default" or "low_priority" notification,
// but not "none".
type = "low_priority";
}
if ((currentState == SyncthingService.State.ACTIVE || currentState == SyncthingService.State.STARTING) &&
!type.equals("none")) {
// Launch FirstStartActivity instead of MainActivity so we can request permission if
// necessary.
PendingIntent pi = PendingIntent.getActivity(mContext, 0,
new Intent(mContext, FirstStartActivity.class), 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
.setContentTitle(mContext.getString(R.string.syncthing_active))
.setSmallIcon(R.drawable.ic_stat_notify)
.setOngoing(true)
.setContentIntent(pi);
if (type.equals("low_priority"))
builder.setPriority(NotificationCompat.PRIORITY_MIN);

if (foreground) {
builder.setContentText(mContext.getString(R.string.syncthing_active_foreground));
service.startForeground(ID_PERSISTENT, builder.build());
} else {
service.stopForeground(false); // ensure no longer running with foreground priority
mNotificationManager.notify(ID_PERSISTENT, builder.build());
}
} else {
// ensure no longer running with foreground priority
cancelPersistentNotification(service);
}
}

public void cancelPersistentNotification(SyncthingService service) {
service.stopForeground(false);
mNotificationManager.cancel(ID_PERSISTENT);
}

public void showCrashedNotification(Intent intent) {
if (mPreferences.getBoolean("notify_crashes", false)) {
Notification n = new NotificationCompat.Builder(mContext)
.setContentTitle(mContext.getString(R.string.notification_crash_title))
.setContentText(mContext.getString(R.string.notification_crash_text))
.setSmallIcon(R.drawable.ic_stat_notify)
.setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0))
.setAutoCancel(true)
.build();
mNotificationManager.notify(ID_CRASH, n);
}
}

public void showEventNotification(String text, PendingIntent pi, int id) {
Notification n = new NotificationCompat.Builder(mContext)
.setContentTitle(mContext.getString(R.string.app_name))
.setContentText(text)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(text))
.setContentIntent(pi)
.setSmallIcon(R.drawable.ic_stat_notify)
.setAutoCancel(true)
.build();
mNotificationManager.notify(id, n);
}

public void showRestartNotification() {
Intent intent = new Intent(mContext, SyncthingService.class)
.setAction(SyncthingService.ACTION_RESTART);
PendingIntent pi = PendingIntent.getService(mContext, 0, intent, 0);

Notification n = new NotificationCompat.Builder(mContext)
.setContentTitle(mContext.getString(R.string.restart_title))
.setContentText(mContext.getString(R.string.restart_notification_text))
.setSmallIcon(R.drawable.ic_stat_notify)
.setContentIntent(pi)
.build();
n.flags |= Notification.FLAG_ONLY_ALERT_ONCE | Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(ID_RESTART, n);
}

public void cancelRestartNotification() {
mNotificationManager.cancel(ID_RESTART);
}

public void showStopSyncthingWarningNotification() {
final String msg = mContext.getString(R.string.appconfig_receiver_background_enabled);
NotificationCompat.Builder nb = new NotificationCompat.Builder(mContext)
.setContentText(msg)
.setTicker(msg)
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentTitle(mContext.getText(mContext.getApplicationInfo().labelRes))
.setSmallIcon(R.drawable.ic_stat_notify)
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(mContext, 0,
new Intent(mContext, MainActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT));


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
nb.setCategory(Notification.CATEGORY_ERROR);
}
mNotificationManager.notify(ID_STOP_BACKGROUND_WARNING, nb.build());
}
}
Loading

0 comments on commit 4c2b325

Please sign in to comment.