notifications
This commit is contained in:
parent
28ef5cb2f5
commit
0b030406bb
@ -34,6 +34,8 @@ dependencies {
|
|||||||
implementation 'com.google.firebase:firebase-messaging:17.3.2'
|
implementation 'com.google.firebase:firebase-messaging:17.3.2'
|
||||||
implementation 'com.android.support:support-v4:27.1.1'
|
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.squareup.okhttp3:okhttp:3.10.0'
|
||||||
implementation 'com.github.kenglxn.QRGen:android:2.5.0'
|
implementation 'com.github.kenglxn.QRGen:android:2.5.0'
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,32 @@
|
|||||||
package com.blackforestbytes.simplecloudnotifier;
|
package com.blackforestbytes.simplecloudnotifier;
|
||||||
|
|
||||||
import android.app.Application;
|
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.content.Context;
|
||||||
import android.widget.Toast;
|
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.AccountFragment;
|
||||||
import com.blackforestbytes.simplecloudnotifier.view.MainActivity;
|
import com.blackforestbytes.simplecloudnotifier.view.MainActivity;
|
||||||
import com.blackforestbytes.simplecloudnotifier.view.TabAdapter;
|
import com.blackforestbytes.simplecloudnotifier.view.TabAdapter;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
public class SCNApp extends Application
|
public class SCNApp extends Application implements LifecycleObserver
|
||||||
{
|
{
|
||||||
private static SCNApp instance;
|
private static SCNApp instance;
|
||||||
private static WeakReference<MainActivity> mainActivity;
|
private static WeakReference<MainActivity> mainActivity;
|
||||||
|
|
||||||
|
private static boolean isBackground = true;
|
||||||
|
|
||||||
public SCNApp()
|
public SCNApp()
|
||||||
{
|
{
|
||||||
instance = this;
|
instance = this;
|
||||||
|
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Context getContext()
|
public static Context getContext()
|
||||||
@ -25,6 +34,11 @@ public class SCNApp extends Application
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isBackground()
|
||||||
|
{
|
||||||
|
return isBackground;
|
||||||
|
}
|
||||||
|
|
||||||
public static void showToast(final String msg, final int duration)
|
public static void showToast(final String msg, final int duration)
|
||||||
{
|
{
|
||||||
final MainActivity a = mainActivity.get();
|
final MainActivity a = mainActivity.get();
|
||||||
@ -62,4 +76,16 @@ public class SCNApp extends Application
|
|||||||
{
|
{
|
||||||
mainActivity = new WeakReference<>(a);
|
mainActivity = new WeakReference<>(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
|
||||||
|
public void onAppBackgrounded()
|
||||||
|
{
|
||||||
|
isBackground = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnLifecycleEvent(Lifecycle.Event.ON_START)
|
||||||
|
public void onAppForegrounded()
|
||||||
|
{
|
||||||
|
isBackground = false;
|
||||||
|
}
|
||||||
}
|
}
|
@ -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() {
|
CMessage msg = new CMessage(time, title, content);
|
||||||
@Override
|
|
||||||
public void run()
|
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<MessageAdapter> ref : _listener)
|
||||||
{
|
{
|
||||||
SharedPreferences sharedPref = SCNApp.getContext().getSharedPreferences("CMessageList", Context.MODE_PRIVATE);
|
MessageAdapter a = ref.get();
|
||||||
int count = sharedPref.getInt("message_count", 0);
|
if (a == null) continue;
|
||||||
|
a.customNotifyItemInserted(count);
|
||||||
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<MessageAdapter> ref : _listener)
|
|
||||||
{
|
|
||||||
MessageAdapter a = ref.get();
|
|
||||||
if (a == null) continue;
|
|
||||||
a.customNotifyItemInserted(count);
|
|
||||||
}
|
|
||||||
CleanUpListener();
|
|
||||||
}
|
}
|
||||||
|
CleanUpListener();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!run)
|
if (!run)
|
||||||
@ -76,6 +75,22 @@ public class CMessageList
|
|||||||
Messages.add(new CMessage(time, title, content));
|
Messages.add(new CMessage(time, title, content));
|
||||||
fullSave();
|
fullSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
Messages.clear();
|
||||||
|
fullSave();
|
||||||
|
|
||||||
|
for (WeakReference<MessageAdapter> ref : _listener)
|
||||||
|
{
|
||||||
|
MessageAdapter a = ref.get();
|
||||||
|
if (a == null) continue;
|
||||||
|
a.customNotifyDataSetChanged();
|
||||||
|
}
|
||||||
|
CleanUpListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fullSave()
|
public void fullSave()
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
package com.blackforestbytes.simplecloudnotifier.service;
|
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.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.R;
|
||||||
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.model.CMessage;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
|
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
|
import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.view.MainActivity;
|
||||||
import com.google.firebase.messaging.FirebaseMessagingService;
|
import com.google.firebase.messaging.FirebaseMessagingService;
|
||||||
import com.google.firebase.messaging.RemoteMessage;
|
import com.google.firebase.messaging.RemoteMessage;
|
||||||
|
|
||||||
@ -30,12 +38,19 @@ public class FBMService extends FirebaseMessagingService
|
|||||||
|
|
||||||
long time = Long.parseLong(remoteMessage.getData().get("timestamp"));
|
long time = Long.parseLong(remoteMessage.getData().get("timestamp"));
|
||||||
String title = remoteMessage.getData().get("title");
|
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)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
@ -66,8 +66,7 @@ public class AccountFragment extends Fragment
|
|||||||
|
|
||||||
v.findViewById(R.id.btnClearLocalStorage).setOnClickListener(cv ->
|
v.findViewById(R.id.btnClearLocalStorage).setOnClickListener(cv ->
|
||||||
{
|
{
|
||||||
CMessageList.inst().Messages.clear();
|
CMessageList.inst().clear();
|
||||||
CMessageList.inst().fullSave();
|
|
||||||
SCNApp.showToast("Notifications cleared", 1000);
|
SCNApp.showToast("Notifications cleared", 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -95,6 +94,7 @@ public class AccountFragment extends Fragment
|
|||||||
@SuppressLint("DefaultLocale")
|
@SuppressLint("DefaultLocale")
|
||||||
public void updateUI(View v)
|
public void updateUI(View v)
|
||||||
{
|
{
|
||||||
|
if (v == null) return;
|
||||||
TextView tvUserID = v.findViewById(R.id.tvUserID);
|
TextView tvUserID = v.findViewById(R.id.tvUserID);
|
||||||
TextView tvUserKey = v.findViewById(R.id.tvUserKey);
|
TextView tvUserKey = v.findViewById(R.id.tvUserKey);
|
||||||
TextView tvQuota = v.findViewById(R.id.tvQuota);
|
TextView tvQuota = v.findViewById(R.id.tvQuota);
|
||||||
|
@ -17,6 +17,7 @@ import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
|||||||
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
|
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
|
import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.ServerCommunication;
|
import com.blackforestbytes.simplecloudnotifier.model.ServerCommunication;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.service.NotificationService;
|
||||||
import com.google.firebase.iid.FirebaseInstanceId;
|
import com.google.firebase.iid.FirebaseInstanceId;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity
|
public class MainActivity extends AppCompatActivity
|
||||||
@ -24,10 +25,14 @@ public class MainActivity extends AppCompatActivity
|
|||||||
public TabAdapter adpTabs;
|
public TabAdapter adpTabs;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
NotificationService.inst();
|
||||||
|
CMessageList.inst();
|
||||||
|
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@ public class MessageAdapter extends RecyclerView.Adapter
|
|||||||
{
|
{
|
||||||
vNoElements = noElementsView;
|
vNoElements = noElementsView;
|
||||||
CMessageList.inst().register(this);
|
CMessageList.inst().register(this);
|
||||||
|
|
||||||
|
vNoElements.setVisibility(getItemCount()>0 ? View.GONE : View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@ -48,13 +50,13 @@ public class MessageAdapter extends RecyclerView.Adapter
|
|||||||
public void customNotifyItemInserted(int idx)
|
public void customNotifyItemInserted(int idx)
|
||||||
{
|
{
|
||||||
notifyItemInserted(idx);
|
notifyItemInserted(idx);
|
||||||
vNoElements.setVisibility(getItemCount()>0 ? View.VISIBLE : View.GONE);
|
vNoElements.setVisibility(getItemCount()>0 ? View.GONE : View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void customNotifyDataSetChanged()
|
public void customNotifyDataSetChanged()
|
||||||
{
|
{
|
||||||
notifyDataSetChanged();
|
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
|
private class MessagePresenter extends RecyclerView.ViewHolder implements View.OnClickListener
|
||||||
@ -82,11 +84,10 @@ public class MessageAdapter extends RecyclerView.Adapter
|
|||||||
data = msg;
|
data = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v)
|
public void onClick(View v)
|
||||||
{
|
{
|
||||||
SCNApp.showToast(data.Title, Toast.LENGTH_LONG);
|
//SCNApp.showToast(data.Title, Toast.LENGTH_LONG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,7 @@
|
|||||||
|
|
||||||
<HorizontalScrollView
|
<HorizontalScrollView
|
||||||
android:id="@+id/svUserKey"
|
android:id="@+id/svUserKey"
|
||||||
|
android:scrollbars="none"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
android:background="@color/cardview_light_background"
|
android:background="@color/cardview_light_background"
|
||||||
|
android:layout_margin="3dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
10
web/send.php
10
web/send.php
@ -55,11 +55,11 @@ $payload = json_encode(
|
|||||||
'to' => $fcm,
|
'to' => $fcm,
|
||||||
//'dry_run' => true,
|
//'dry_run' => true,
|
||||||
'android' => [ 'priority' => 'high' ],
|
'android' => [ 'priority' => 'high' ],
|
||||||
'notification' =>
|
//'notification' =>
|
||||||
[
|
//[
|
||||||
'title' => $message,
|
// 'title' => $message,
|
||||||
'body' => $content,
|
// 'body' => $content,
|
||||||
],
|
//],
|
||||||
'data' =>
|
'data' =>
|
||||||
[
|
[
|
||||||
'title' => $message,
|
'title' => $message,
|
||||||
|
Loading…
Reference in New Issue
Block a user