gui: add persistent notification and run NfdService in foreground to improve stability
Change-Id: I47e7ff07888e4638a75ddb607d335511467a7779
refs: #4766
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 51c923b..9705135 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -10,6 +10,7 @@
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:allowBackup="true"
diff --git a/app/src/main/java/net/named_data/nfd/MainActivity.java b/app/src/main/java/net/named_data/nfd/MainActivity.java
index a1de558..616d562 100644
--- a/app/src/main/java/net/named_data/nfd/MainActivity.java
+++ b/app/src/main/java/net/named_data/nfd/MainActivity.java
@@ -19,6 +19,7 @@
package net.named_data.nfd;
+import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
@@ -115,6 +116,22 @@
}
}
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ setIntent(intent);
+ FragmentManager fragmentManager = getSupportFragmentManager();
+
+ int drawItem = getIntent().getIntExtra(INTENT_KEY_FRAGMENT_TAG, -1);
+ if (drawItem == DRAWER_ITEM_GENERAL) {
+ MainFragment mainFragment = MainFragment.newInstance();
+ fragmentManager
+ .beginTransaction()
+ .replace(R.id.main_fragment_container, mainFragment)
+ .commit();
+ }
+ }
+
/**
* Convenience method that replaces the main fragment container with the
* new fragment and adding the current transaction to the backstack.
@@ -201,4 +218,7 @@
public static final int DRAWER_ITEM_PING = 4;
//public static final int DRAWER_ITEM_STRATEGIES = X;
public static final int DRAWER_ITEM_WIFIDIRECT = 5;
+
+ /** Indent key for jump to a fragment */
+ public static final String INTENT_KEY_FRAGMENT_TAG = "fragmentTag";
}
diff --git a/app/src/main/java/net/named_data/nfd/service/NfdService.java b/app/src/main/java/net/named_data/nfd/service/NfdService.java
index 79d18ca..5b85a6e 100644
--- a/app/src/main/java/net/named_data/nfd/service/NfdService.java
+++ b/app/src/main/java/net/named_data/nfd/service/NfdService.java
@@ -1,6 +1,6 @@
/* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2015-2017 Regents of the University of California
+ * Copyright (c) 2015-2018 Regents of the University of California
* <p>
* This file is part of NFD (Named Data Networking Forwarding Daemon) Android.
* See AUTHORS.md for complete list of NFD Android authors and contributors.
@@ -19,10 +19,16 @@
package net.named_data.nfd.service;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Color;
import android.os.AsyncTask;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
@@ -39,6 +45,7 @@
import com.intel.jndn.management.types.RibEntry;
import net.named_data.jndn.Name;
+import net.named_data.nfd.MainActivity;
import net.named_data.nfd.MainFragment;
import net.named_data.nfd.R;
import net.named_data.nfd.utils.G;
@@ -179,6 +186,20 @@
m_nfdServiceMessenger = null;
}
+ /**
+ * Ensure the persistent notification will be removed after the app is swiped out.
+ *
+ * @param rootIntent
+ */
+ @Override
+ public void onTaskRemoved(Intent rootIntent) {
+ super.onTaskRemoved(rootIntent);
+
+ stopForeground(true);
+
+ stopSelf();
+ }
+
/////////////////////////////////////////////////////////////////////////////
/**
@@ -207,6 +228,7 @@
// from a Handler's message through binding with the service.
startService(new Intent(this, NfdService.class));
G.Log(TAG, "serviceStartNfd()");
+ startForeground(NOTIFICATION_ID, createNotification());
} else {
G.Log(TAG, "serviceStartNfd(): NFD Service already running!");
}
@@ -259,6 +281,7 @@
SharedPreferencesManager.clearFaceIds(getApplicationContext());
stopSelf();
G.Log(TAG, "serviceStopNfd()");
+ stopForeground(true);
}
}
@@ -456,6 +479,46 @@
}
/**
+ * Create a persistent notification to indicate NFD is running.
+ */
+ private Notification
+ createNotification() {
+ NotificationManager notificationManager =
+ (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
+ Intent intent = new Intent(getApplicationContext(), MainActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ intent.putExtra(MainActivity.INTENT_KEY_FRAGMENT_TAG, MainActivity.DRAWER_ITEM_GENERAL);
+
+ PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
+ NOTIFICATION_ID, intent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+
+ Notification.Builder builder;
+ // If devices's sdk version is >= 26, we need to create a channel for notification.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationChannel channel =
+ new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
+ channel.setDescription(getApplicationContext().getResources().getString(R.string.channel_description));
+ channel.setVibrationPattern(new long[]{0});
+ channel.enableVibration(true);
+ notificationManager.createNotificationChannel(channel);
+ builder = new Notification.Builder(getApplicationContext(), CHANNEL_ID);
+ } else {
+ builder = new Notification.Builder(getApplicationContext());
+ builder.setVibrate(new long[]{0L});
+ }
+ builder
+ .setContentTitle(getApplicationContext().getResources().getString(R.string.notification_content_title))
+ .setContentText(getApplicationContext().getResources().getString(R.string.notification_content_text))
+ .setContentIntent(pendingIntent)
+ .setSmallIcon(R.drawable.nfd_notification)
+ .setColor(getApplication().getColor(R.color.notification_color_orange))
+ .setOngoing(true);
+
+ return builder.build();
+ }
+
+ /**
* Messenger to handle messages that are passed to the NfdService
*/
private Messenger m_nfdServiceMessenger = null;
@@ -469,4 +532,19 @@
* Handler to deal with timeout behaviors
*/
private Handler m_handler = new Handler();
+
+ /**
+ * Unique notification ID
+ */
+ private static final int NOTIFICATION_ID = 7;
+
+ /**
+ * Unique notification channel ID
+ */
+ private static final String CHANNEL_ID = "0404";
+
+ /**
+ * User visible notification channel name
+ */
+ private static final String CHANNEL_NAME = "nfd-channel";
}
diff --git a/app/src/main/res/drawable-hdpi/nfd_notification.png b/app/src/main/res/drawable-hdpi/nfd_notification.png
new file mode 100644
index 0000000..a93def4
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/nfd_notification.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/nfd_notification.png b/app/src/main/res/drawable-mdpi/nfd_notification.png
new file mode 100644
index 0000000..b51fea8
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/nfd_notification.png
Binary files differ
diff --git a/app/src/main/res/drawable-xhdpi/nfd_notification.png b/app/src/main/res/drawable-xhdpi/nfd_notification.png
new file mode 100644
index 0000000..588f755
--- /dev/null
+++ b/app/src/main/res/drawable-xhdpi/nfd_notification.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxhdpi/nfd_notification.png b/app/src/main/res/drawable-xxhdpi/nfd_notification.png
new file mode 100644
index 0000000..a099777
--- /dev/null
+++ b/app/src/main/res/drawable-xxhdpi/nfd_notification.png
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index b9519a1..c5320ab 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -2,4 +2,5 @@
<resources>
<item name="ndn_color_fire_bush" type="color">#DB9710</item>
<item name="android_color_gray" type="color">#C6C6C6</item>
+ <item name="notification_color_orange" type="color">#CD5F31</item>
</resources>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 47032af..eb7b812 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -114,4 +114,8 @@
<string name="fragment_route_details_next_hops">List of next hops</string>
<string name="fragment_route_route_name_title">Route Name</string>
<string name="ping_client_prefix_hint">Prefix (e.g., /ndn/edu/arizona)</string>
+
+ <string name="notification_content_title">Status</string>
+ <string name="notification_content_text">NFD is running</string>
+ <string name="channel_description">NDN Android notification.</string>
</resources>