Use Java background task for fetching notifications, close #18

Framework7
Skylar Ittner 6 years ago
parent 9cb914512b
commit d248aa5934

@ -51,6 +51,7 @@
<resource-file src="res/android/drawable-mdpi/ic_notification.png" target="app/src/main/res/drawable-mdpi/ic_notification.png" />
<resource-file src="res/android/drawable-xhdpi/ic_notification.png" target="app/src/main/res/drawable-xhdpi/ic_notification.png" />
<resource-file src="res/android/drawable-xxhdpi/ic_notification.png" target="app/src/main/res/drawable-xxhdpi/ic_notification.png" />
<resource-file src="src/android/BackgroundFetchHeadlessTask.java" target="app/src/main/java/com/transistorsoft/cordova/backgroundfetch/BackgroundFetchHeadlessTask.java" />
<splash density="port-ldpi" src="res/screen/android/splash-port-ldpi.png" />
<splash density="port-mdpi" src="res/screen/android/splash-port-mdpi.png" />
<splash density="port-hdpi" src="res/screen/android/splash-port-hdpi.png" />

@ -0,0 +1,175 @@
package com.transistorsoft.cordova.backgroundfetch;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import com.netsyms.BusinessMobile.R;
import com.transistorsoft.tsbackgroundfetch.BackgroundFetch;
import android.graphics.Color;
import android.os.Build;
import android.provider.Settings;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
public class BackgroundFetchHeadlessTask implements HeadlessTask {
private static final String PREFS_NAME = "NativeStorage";
private static final String KEY = "accounts";
private static String shownNotifications = "";
public final String NOTIFICATION_CHANNEL_ID = "background-channel-id";
public static String getValue(Context context, String key, String defaultValue) {
SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, Activity.MODE_PRIVATE);
return settings.getString(key, defaultValue);
}
/**
* https://stackoverflow.com/a/34691486
*
* @param urlString
* @return
* @throws IOException
*/
public static String getStringFromURL(String urlString) throws IOException {
HttpURLConnection urlConnection = null;
URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setDoOutput(true);
urlConnection.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
String jsonString = sb.toString();
return jsonString;
}
@Override
public void onFetch(Context context) {
Log.d(BackgroundFetch.TAG, "Notification Poller: onFetch");
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
String accountjson = getValue(context, KEY, null).replaceAll("\\\\", "");
accountjson = accountjson.substring(1, accountjson.length() - 1);
//Log.d(BackgroundFetch.TAG, "Notification Poller: Account JSON: " + accountjson);
try {
JSONArray accounts = new JSONArray(accountjson);
for (int i = 0; i < accounts.length(); i++) {
try {
JSONObject acct = accounts.getJSONObject(i);
Log.d(BackgroundFetch.TAG, "Notification Poller: Account " + i + " URL: " + acct.getString("syncurl"));
String notificationString = getStringFromURL(acct.getString("syncurl") + "?key=" + acct.getString("key") + "&username=" + acct.getString("username") + "&action=checknotifications");
//Log.d(BackgroundFetch.TAG, "Notification Poller: Account " + i + " JSON: " + notificationString);
JSONArray notifications = new JSONObject(notificationString).getJSONArray("notifications");
Log.d(BackgroundFetch.TAG, "Notification Poller: Account " + i + " JSON parsed: " + notifications.length() + " notifications");
for (int j = 0; j < notifications.length(); j++) {
JSONObject notif = notifications.getJSONObject(j);
Log.d(BackgroundFetch.TAG, "Notification Poller: Procesing notification ID " + notif.getString("id") + " with title " + notif.getString("title"));
if (notif.getBoolean("seen") || shownNotifications.contains("|" + i + ":" + notif.getString("id") + "|")) {
continue;
}
Intent intent = new Intent(context, com.netsyms.BusinessMobile.MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder b = new NotificationCompat.Builder(context);
b.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(notif.getString("title"))
.setContentText(notif.getString("content"))
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.setContentIntent(contentIntent)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setVisibility(Notification.VISIBILITY_PRIVATE);
// Create alternate notification for lockscreen
NotificationCompat.Builder lockb = new NotificationCompat.Builder(context);
if (notif.getBoolean("sensitive") == true) {
lockb
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("Contents hidden")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
} else {
lockb
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(notif.getString("title"))
.setContentText(notif.getString("content"))
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
}
b.setPublicVersion(lockb.build());
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Background Notifications";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, name, importance);
channel.enableLights(true);
channel.enableVibration(true);
channel.setLightColor(Color.rgb(33, 150, 243));
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
b.setChannelId(NOTIFICATION_CHANNEL_ID);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(Integer.parseInt(notif.getString("id")), b.build());
Log.d(BackgroundFetch.TAG, "Notification Poller: Shown notification " + notif.getString("id"));
shownNotifications += "|" + i + ":" + notif.getString("id") + "|";
}
} catch (Exception e) {
Log.d(BackgroundFetch.TAG, "Notification Poller: Exception: " + e.getMessage());
Log.d(BackgroundFetch.TAG, "Notification Poller: Stack trace: " + Log.getStackTraceString(e));
}
}
} catch (Exception e) {
Log.d(BackgroundFetch.TAG, "Notification Poller: Exception: " + e.getMessage());
Log.d(BackgroundFetch.TAG, "Notification Poller: Stack trace: " + Log.getStackTraceString(e));
} finally {
BackgroundFetch.getInstance(context).finish();
}
}
}
);
thread.start();
}
}

@ -219,7 +219,8 @@ function displayNotifications(callback) {
actions: [
{id: 'mark_read', title: "Mark Read"}
],
id: n.id
id: n.id,
lockscreen: !n.sensitive
}]);
shown_notifications.push(n.id);
@ -263,7 +264,9 @@ document.addEventListener("deviceready", function () {
}
cordova.plugins.notification.local.setDefaults({
led: {color: '#2196F3'},
led: true,
color: '#2196F3',
vibrate: true,
smallIcon: "res://ic_notification"
});
cordova.plugins.notification.local.on("mark_read", function (notification) {

Loading…
Cancel
Save