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 android.graphics.Color; import android.os.Build; import android.provider.Settings; import android.support.v4.app.NotificationCompat; import android.util.Log; import com.netsyms.repairapp.MainActivity; import com.netsyms.repairapp.R; import com.transistorsoft.tsbackgroundfetch.BackgroundFetch; import org.json.JSONArray; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class BackgroundFetchHeadlessTask implements HeadlessTask { private static final String PREFS_NAME = "NativeStorage"; private static final String NOTIFICATION_URL = "https://apis.netsyms.net/repairapp/notifications.php"; private static final String UUID_KEY = "client_uuid"; private static final String SINCE_KEY = "last_notification_check"; 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); } public static void setValue(Context context, String key, String value) { SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, Activity.MODE_PRIVATE); SharedPreferences.Editor edit = settings.edit(); edit.putString(key, value); edit.commit(); } /** * 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 clientuuid = getValue(context, UUID_KEY, null); String lastcheck = getValue(context, SINCE_KEY, null); //Log.d(BackgroundFetch.TAG, "Notification Poller: Account JSON: " + accountjson); try { String notificationString = getStringFromURL(NOTIFICATION_URL + "?clientuuid=" + clientuuid + "&since=" + lastcheck); //Log.d(BackgroundFetch.TAG, "Notification Poller: Account " + i + " JSON: " + notificationString); JSONObject jsonresp = new JSONObject(notificationString); JSONArray notifications = jsonresp.getJSONArray("notifications"); Log.d(BackgroundFetch.TAG, "Notification Poller: 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 (shownNotifications.contains("|" + notif.getString("id") + "|")) { continue; } Intent intent = new Intent(context, 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); 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 += "|" + notif.getString("id") + "|"; } setValue(context, SINCE_KEY, jsonresp.getString("timestamp")); } 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(); } }