From 0b030406bbb90b7520c7ad58a5cf81add4b8794e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Thu, 27 Sep 2018 01:38:56 +0200 Subject: [PATCH] notifications --- android/app/build.gradle | 2 + .../simplecloudnotifier/SCNApp.java | 28 +++++++- .../model/CMessageList.java | 63 ++++++++++------- .../service/FBMService.java | 21 +++++- .../service/NotificationService.java | 70 +++++++++++++++++++ .../view/AccountFragment.java | 4 +- .../view/MainActivity.java | 7 +- .../view/MessageAdapter.java | 9 +-- .../src/main/res/layout/fragment_account.xml | 1 + .../app/src/main/res/layout/message_card.xml | 1 + web/send.php | 10 +-- 11 files changed, 176 insertions(+), 40 deletions(-) create mode 100644 android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/service/NotificationService.java diff --git a/android/app/build.gradle b/android/app/build.gradle index 026882d..2d423b2 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -34,6 +34,8 @@ dependencies { implementation 'com.google.firebase:firebase-messaging:17.3.2' implementation 'com.android.support:support-v4:27.1.1' + implementation "android.arch.lifecycle:extensions:1.1.1" + implementation 'com.squareup.okhttp3:okhttp:3.10.0' implementation 'com.github.kenglxn.QRGen:android:2.5.0' } diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/SCNApp.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/SCNApp.java index 2f2c607..9432585 100644 --- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/SCNApp.java +++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/SCNApp.java @@ -1,23 +1,32 @@ package com.blackforestbytes.simplecloudnotifier; import android.app.Application; +import android.arch.lifecycle.Lifecycle; +import android.arch.lifecycle.LifecycleObserver; +import android.arch.lifecycle.OnLifecycleEvent; +import android.arch.lifecycle.ProcessLifecycleOwner; import android.content.Context; import android.widget.Toast; +import com.blackforestbytes.simplecloudnotifier.model.CMessageList; +import com.blackforestbytes.simplecloudnotifier.service.NotificationService; import com.blackforestbytes.simplecloudnotifier.view.AccountFragment; import com.blackforestbytes.simplecloudnotifier.view.MainActivity; import com.blackforestbytes.simplecloudnotifier.view.TabAdapter; import java.lang.ref.WeakReference; -public class SCNApp extends Application +public class SCNApp extends Application implements LifecycleObserver { private static SCNApp instance; private static WeakReference mainActivity; + private static boolean isBackground = true; + public SCNApp() { instance = this; + ProcessLifecycleOwner.get().getLifecycle().addObserver(this); } public static Context getContext() @@ -25,6 +34,11 @@ public class SCNApp extends Application return instance; } + public static boolean isBackground() + { + return isBackground; + } + public static void showToast(final String msg, final int duration) { final MainActivity a = mainActivity.get(); @@ -62,4 +76,16 @@ public class SCNApp extends Application { mainActivity = new WeakReference<>(a); } + + @OnLifecycleEvent(Lifecycle.Event.ON_STOP) + public void onAppBackgrounded() + { + isBackground = true; + } + + @OnLifecycleEvent(Lifecycle.Event.ON_START) + public void onAppForegrounded() + { + isBackground = false; + } } \ No newline at end of file diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/CMessageList.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/CMessageList.java index f8a9ff1..c5d51a1 100644 --- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/CMessageList.java +++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/model/CMessageList.java @@ -42,33 +42,32 @@ public class CMessageList } } - public void add(final long time, final String title, final String content) + public CMessage add(final long time, final String title, final String content) { - boolean run = SCNApp.runOnUiThread(new Runnable() { - @Override - public void run() + CMessage msg = new CMessage(time, title, content); + + boolean run = SCNApp.runOnUiThread(() -> + { + SharedPreferences sharedPref = SCNApp.getContext().getSharedPreferences("CMessageList", Context.MODE_PRIVATE); + int count = sharedPref.getInt("message_count", 0); + + SharedPreferences.Editor e = sharedPref.edit(); + + Messages.add(msg); + e.putInt("message_count", count+1); + e.putLong("message["+count+"].timestamp", time); + e.putString("message["+count+"].title", title); + e.putString("message["+count+"].content", content); + + e.apply(); + + for (WeakReference ref : _listener) { - SharedPreferences sharedPref = SCNApp.getContext().getSharedPreferences("CMessageList", Context.MODE_PRIVATE); - int count = sharedPref.getInt("message_count", 0); - - SharedPreferences.Editor e = sharedPref.edit(); - - Messages.add(new CMessage(time, title, content)); - e.putInt("message_count", count+1); - e.putLong("message["+count+"].timestamp", time); - e.putString("message["+count+"].title", title); - e.putString("message["+count+"].content", content); - - e.apply(); - - for (WeakReference ref : _listener) - { - MessageAdapter a = ref.get(); - if (a == null) continue; - a.customNotifyItemInserted(count); - } - CleanUpListener(); + MessageAdapter a = ref.get(); + if (a == null) continue; + a.customNotifyItemInserted(count); } + CleanUpListener(); }); if (!run) @@ -76,6 +75,22 @@ public class CMessageList Messages.add(new CMessage(time, title, content)); fullSave(); } + + return msg; + } + + public void clear() + { + Messages.clear(); + fullSave(); + + for (WeakReference ref : _listener) + { + MessageAdapter a = ref.get(); + if (a == null) continue; + a.customNotifyDataSetChanged(); + } + CleanUpListener(); } public void fullSave() diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/service/FBMService.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/service/FBMService.java index 79873dc..6bf4dfe 100644 --- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/service/FBMService.java +++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/service/FBMService.java @@ -1,11 +1,19 @@ package com.blackforestbytes.simplecloudnotifier.service; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.support.v4.app.NotificationCompat; import android.util.Log; import android.widget.Toast; +import com.blackforestbytes.simplecloudnotifier.R; import com.blackforestbytes.simplecloudnotifier.SCNApp; +import com.blackforestbytes.simplecloudnotifier.model.CMessage; import com.blackforestbytes.simplecloudnotifier.model.CMessageList; import com.blackforestbytes.simplecloudnotifier.model.SCNSettings; +import com.blackforestbytes.simplecloudnotifier.view.MainActivity; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; @@ -30,12 +38,19 @@ public class FBMService extends FirebaseMessagingService long time = Long.parseLong(remoteMessage.getData().get("timestamp")); String title = remoteMessage.getData().get("title"); - String content = remoteMessage.getData().get("content"); + String content = remoteMessage.getData().get("body"); - CMessageList.inst().add(time, title, content); + CMessage msg = CMessageList.inst().add(time, title, content); - SCNApp.showToast(title, Toast.LENGTH_LONG); + if (SCNApp.isBackground()) + { + NotificationService.inst().show(msg); + } + else + { + SCNApp.showToast("Message recieved: " + title, Toast.LENGTH_LONG); + } } catch (Exception e) { diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/service/NotificationService.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/service/NotificationService.java new file mode 100644 index 0000000..2c03d02 --- /dev/null +++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/service/NotificationService.java @@ -0,0 +1,70 @@ +package com.blackforestbytes.simplecloudnotifier.service; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.os.Build; +import android.support.v4.app.NotificationCompat; + +import com.blackforestbytes.simplecloudnotifier.R; +import com.blackforestbytes.simplecloudnotifier.SCNApp; +import com.blackforestbytes.simplecloudnotifier.model.CMessage; +import com.blackforestbytes.simplecloudnotifier.model.CMessageList; +import com.blackforestbytes.simplecloudnotifier.view.MainActivity; + +public class NotificationService +{ + private final static String CHANNEL_ID = "CHAN_BFB_SCN_MESSAGES"; + + private final static Object _lock = new Object(); + private static NotificationService _inst = null; + public static NotificationService inst() + { + synchronized (_lock) + { + if (_inst != null) return _inst; + return _inst = new NotificationService(); + } + } + + private NotificationService() + { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) + { + Context ctxt = SCNApp.getContext(); + + NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Push notifications", NotificationManager.IMPORTANCE_HIGH); + channel.setDescription("Messages from the API"); + channel.setLightColor(Color.rgb(255, 0, 0)); + channel.setVibrationPattern(new long[]{200}); + channel.enableLights(true); + channel.enableVibration(true); + + NotificationManager notificationManager = ctxt.getSystemService(NotificationManager.class); + if (notificationManager != null) notificationManager.createNotificationChannel(channel); + } + + } + + public void show(CMessage msg) + { + Context ctxt = SCNApp.getContext(); + + NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctxt, CHANNEL_ID) + .setSmallIcon(R.drawable.ic_bfb) + .setContentTitle(msg.Title) + .setContentText(msg.Content) + .setShowWhen(true) + .setWhen(msg.Timestamp) + .setPriority(NotificationCompat.PRIORITY_HIGH) + .setAutoCancel(true); + Intent intent = new Intent(ctxt, MainActivity.class); + PendingIntent pi = PendingIntent.getActivity(ctxt, 0, intent, 0); + mBuilder.setContentIntent(pi); + NotificationManager mNotificationManager = (NotificationManager) ctxt.getSystemService(Context.NOTIFICATION_SERVICE); + if (mNotificationManager != null) mNotificationManager.notify(0, mBuilder.build()); + } +} diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/AccountFragment.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/AccountFragment.java index eeb2418..ee6e18f 100644 --- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/AccountFragment.java +++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/AccountFragment.java @@ -66,8 +66,7 @@ public class AccountFragment extends Fragment v.findViewById(R.id.btnClearLocalStorage).setOnClickListener(cv -> { - CMessageList.inst().Messages.clear(); - CMessageList.inst().fullSave(); + CMessageList.inst().clear(); SCNApp.showToast("Notifications cleared", 1000); }); @@ -95,6 +94,7 @@ public class AccountFragment extends Fragment @SuppressLint("DefaultLocale") public void updateUI(View v) { + if (v == null) return; TextView tvUserID = v.findViewById(R.id.tvUserID); TextView tvUserKey = v.findViewById(R.id.tvUserKey); TextView tvQuota = v.findViewById(R.id.tvQuota); diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MainActivity.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MainActivity.java index 33b0d38..e7ef73a 100644 --- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MainActivity.java +++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MainActivity.java @@ -17,6 +17,7 @@ import com.blackforestbytes.simplecloudnotifier.SCNApp; import com.blackforestbytes.simplecloudnotifier.model.CMessageList; import com.blackforestbytes.simplecloudnotifier.model.SCNSettings; import com.blackforestbytes.simplecloudnotifier.model.ServerCommunication; +import com.blackforestbytes.simplecloudnotifier.service.NotificationService; import com.google.firebase.iid.FirebaseInstanceId; public class MainActivity extends AppCompatActivity @@ -24,10 +25,14 @@ public class MainActivity extends AppCompatActivity public TabAdapter adpTabs; @Override - protected void onCreate(Bundle savedInstanceState) { + protected void onCreate(Bundle savedInstanceState) + { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + NotificationService.inst(); + CMessageList.inst(); + Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); diff --git a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MessageAdapter.java b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MessageAdapter.java index 03e850a..2613b31 100644 --- a/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MessageAdapter.java +++ b/android/app/src/main/java/com/blackforestbytes/simplecloudnotifier/view/MessageAdapter.java @@ -21,6 +21,8 @@ public class MessageAdapter extends RecyclerView.Adapter { vNoElements = noElementsView; CMessageList.inst().register(this); + + vNoElements.setVisibility(getItemCount()>0 ? View.GONE : View.VISIBLE); } @NonNull @@ -48,13 +50,13 @@ public class MessageAdapter extends RecyclerView.Adapter public void customNotifyItemInserted(int idx) { notifyItemInserted(idx); - vNoElements.setVisibility(getItemCount()>0 ? View.VISIBLE : View.GONE); + vNoElements.setVisibility(getItemCount()>0 ? View.GONE : View.VISIBLE); } public void customNotifyDataSetChanged() { notifyDataSetChanged(); - vNoElements.setVisibility(getItemCount()>0 ? View.VISIBLE : View.GONE); + vNoElements.setVisibility(getItemCount()>0 ? View.GONE : View.VISIBLE); } private class MessagePresenter extends RecyclerView.ViewHolder implements View.OnClickListener @@ -82,11 +84,10 @@ public class MessageAdapter extends RecyclerView.Adapter data = msg; } - @Override public void onClick(View v) { - SCNApp.showToast(data.Title, Toast.LENGTH_LONG); + //SCNApp.showToast(data.Title, Toast.LENGTH_LONG); } } } diff --git a/android/app/src/main/res/layout/fragment_account.xml b/android/app/src/main/res/layout/fragment_account.xml index d6bd560..711b902 100644 --- a/android/app/src/main/res/layout/fragment_account.xml +++ b/android/app/src/main/res/layout/fragment_account.xml @@ -110,6 +110,7 @@ diff --git a/web/send.php b/web/send.php index a7218f7..6666030 100644 --- a/web/send.php +++ b/web/send.php @@ -55,11 +55,11 @@ $payload = json_encode( 'to' => $fcm, //'dry_run' => true, 'android' => [ 'priority' => 'high' ], - 'notification' => - [ - 'title' => $message, - 'body' => $content, - ], + //'notification' => + //[ + // 'title' => $message, + // 'body' => $content, + //], 'data' => [ 'title' => $message,