How to collect Firebase cloud messaging notifications when the application is down?

I use Firebase Cloud Messaging to send push notifications from my server to my Android app.

When the application is running, notifications are stacked up because I installed them in a group in the FirebaseMessagingService . Which is nice.

However, when the application is not running, notifications are not stacked , and each of them is displayed separately. Which is not nice.

How can I make sure that notifications are stacked even if the application does not work?

This is what my FirebaseMessagingService looks like:

 public class MyFcmListenerService extends FirebaseMessagingService { @Override public void onMessageReceived(RemoteMessage remoteMessage) { RemoteMessage.Notification notification = remoteMessage.getNotification(); Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.notif_white) .setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.notif_white)) .setContentTitle(getResources().getString(R.string.app_name)) .setContentText(notification.getBody()) .setAutoCancel(true) .setPriority(2) .setSound(defaultSoundUri) .setContentIntent(pendingIntent) .setGroup("1") .setGroupSummary(true) .setOnlyAlertOnce(true); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0 , notificationBuilder.build()); } } 
+3
source share
3 answers

To add two or more notifications (indicated in the message list) and display them as notifications of the GMail style type, you can add a style for incoming messages for notification, for example below:

  private void showNotification(Context mContext, String title, List messages, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) { final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( mContext); NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); for(int i=0;i<messages.size();i++) inboxStyle.addLine(messages.get(i)); Notification notification; notification = mBuilder.setTicker(title) .setAutoCancel(true) .setContentTitle(title) .setContentIntent(resultPendingIntent) .setSound(alarmSound) .setStyle(inboxStyle) .setWhen(getTimeMilliSec(timeStamp)) .setSmallIcon(R.drawable.notification_small_icon) .setLargeIcon(R.drawable.notification_large_icon) .setDeleteIntent(PendingIntent.getBroadcast(mContext,101,new Intent(mContext, NotificationDismissedReceiver.class),PendingIntent.FLAG_CANCEL_CURRENT)) .build(); NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(NConfig.NOTIFICATION_ID, notification); } 

If you notice, I also added a delete intent for my notification, which launches NotificationDismissedReceiver (BroadcastReceiver), the main task of which is to clear the notifications that were dismissed by gestures, so that next time only new notifications will stack together.

 public class NotificationDismissedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO: This method is called when the BroadcastReceiver is receiving // an Intent broadcast. messages.clear(); } } 

The main logic is to collect all unread / unauthorized notifications inside the list of ie messages, below: onMessageReceive () FirebaseMessagingService: -

  public void onMessageReceived(RemoteMessage remoteMessage) { Log.e(TAG, "From: " + remoteMessage.getFrom()); if (remoteMessage == null) return; if (remoteMessage.getData()!=null && remoteMessage.getData().size() > 0) { try { JSONObject json = new JSONObject(remoteMessage.getData().toString()); Log.e(TAG, "Notification Data: " + json); Title = json.get("title").toString(); Message = json.get("body").toString(); messages.add(Message); } catch (Exception e) { Log.e(TAG, "Exception: " + e.getMessage()); } } showNotification(...); } 

When the application is in the foreground, the above onMessageReceive () FirebaseMessagingService runs fine, but when your application is in the background or killed, it fails. To execute it, you must omit part of the notification from the JSON message sent from the server side and include only part of the data, as shown below: -

  var data = new { to = token, // notification = new // { // body = messageBody, //Omitting notification part of data // title = messageTitle, // icon = "myicon", //}, data = new { body = messageBody, // adding all notification information inside data title = messageTitle, icon = "myicon", } }; 

Thus, your message now only becomes a data message, which means that it will always execute the onMessageReceive () FirebaseMessagingService regardless of whether your application is in the background or in the foreground.

We hope this explanation helps.

+5
source

Firebase will not call your onMessageReceived when your application is in the background or is killed, and you cannot configure your notification. A notification generated by the system will show.

make a onMessageReceived library to call your onMessageReceived in each case

a) foreground

b) Background

c) killed

You should not put a "notification" of the JSON key in your request to the Firebase API, but use "data" instead, see below.

For example, the following message will not call onMessageReceived()

 { "to": "/topics/test", "notification": { "title" : "title", "message": "data!" } } 

but it will work

 { "to": "/topics/test", "data": { "title":"title", "message":"data!" } } 

look this, it has a detailed description of the type of firebase message. For instance:

 @Override public void onMessageReceived(RemoteMessage remoteMessage) { Log.d(TAG, "From: " + remoteMessage.getFrom()); // Check if message contains a data payload. if (remoteMessage.getData().size() > 0) { Log.d(TAG, "Message data payload: " + remoteMessage.getData()); sendNotification(remoteMessage.getData().get("message").toString(), remoteMessage.getData().get("title").toString()); } } private void sendNotification(String message, String title) { int requestID = (int) System.currentTimeMillis(); Intent intent = new Intent(this, activityCompat); PendingIntent pendingIntent = PendingIntent.getActivity(this, requestID, intent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.small_logo) .setContentTitle(title) .setContentText(message).setContentIntent(pendingIntent) .setAutoCancel(true) .setStyle(new NotificationCompat.BigTextStyle() .bigText(messageBody)) .setTicker(messageBody); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationBuilder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL; Notification notification = notificationBuilder.build(); notificationManager.notify(0, notification); } 
+5
source

You can use the following code to group notifications. I use the application to browse the Internet via Android, so I pass the URL as intentional content. I used 2 types of grouping notifications based on Android versions, because Android nougat and later versions automatically group notifications based on the group ID, but Marshmallow and earlier will not group notifications. Remember one thing: you must send your notifications as data notifications. because you can handle data notifications inside onMessageReceived even if the application is in the background or onMessageReceived state.

My Firebase messaging service looks like this:

 import static com.packageName.config.AppConstant.MY_NOTIFICATION; public class MyFireBaseMessagingService extends FirebaseMessagingService { private static final String TAG = "MyFireBaseService"; private static final int SUMMARY_ID = 999; @Override public void onNewToken(String refreshedToken) { super.onNewToken(refreshedToken); //Store fcm token to shared preferences SharedPrefManager.getInstance(getApplicationContext()).setFCMToken(refreshedToken); } @Override public void onCreate() { super.onCreate(); } /* Data messages should be in the form of * { * type(Required) : "NotificationDTO type" * title(Required) : "NotificationDTO title" * message(Required) : "Message to be displayed in the notification panel" * notificationURL(Required) : "Url to be loaded into the web view" * groupId(Optional) : "Based on this group id, system will group the notification" * channelId(optional) : "This channel id will be used to send notification" * image(optional) : "This image will be displayed on notification panel" * label(optional) : "NotificationDTO label" * priority(optional) : "NotificationDTO priority. If notification priority not mentioned, * Then default priority will be assigned to the notification" * } */ @Override public void onMessageReceived(RemoteMessage remoteMessage) { boolean isForeGround = false; super.onMessageReceived(remoteMessage); // Fetching data part from the notification Map<String, String> data = remoteMessage.getData(); String message = data.get("message"); String id = data.get("notificationId"); int notificationId; // If notification id is empty then no need to show a notification if (id == null || id.isEmpty()) { return; } else { notificationId = Integer.parseInt(id); } if (message == null || message.equals("")) { message = getString(R.string.default_notification_message); } String notificationURL = data.get("notificationURL"); String title = data.get("title"); // Group id should be a string String groupKey = AppConstant.GROUP_KEY_NOTIFICATION; if (data.get("groupKey") != null) { groupKey = data.get("groupKey"); } // Current we have only one channel with id 'general_notification_id' String channelId = data.get("channelId"); String label = data.get("label"); String image = data.get("image"); /* * Notification priority(String Value) should be one of the following * PRIORITY_HIGH/PRIORITY_LOW/PRIORITY_MAX/PRIORITY_MIN * If no priority mentioned, system will automatically assign the default priority */ String priority = data.get("priority"); int notificationPriority = 0; if (priority != null && !priority.isEmpty()) { priority = priority.toUpperCase(); switch (priority) { case "PRIORITY_HIGH": notificationPriority = NotificationCompat.PRIORITY_HIGH; break; case "PRIORITY_LOW": notificationPriority = NotificationCompat.PRIORITY_LOW; break; case "PRIORITY_MAX": notificationPriority = NotificationCompat.PRIORITY_MAX; break; case "PRIORITY_MIN": notificationPriority = NotificationCompat.PRIORITY_MIN; break; default: notificationPriority = NotificationCompat.PRIORITY_DEFAULT; break; } } /* * Category should be from the following list. * Because system will sort the notification based on the category. * * CATEGORY_ALARM,CATEGORY_CALL,CATEGORY_MESSAGE,CATEGORY_EMAIL,CATEGORY_EVENT, * CATEGORY_PROMO,CATEGORY_ALARM,CATEGORY_PROGRESS,CATEGORY_SOCIAL,CATEGORY_ERROR, * CATEGORY_TRANSPORT,CATEGORY_SYSTEM,CATEGORY_SERVICE,CATEGORY_REMINDER, * CATEGORY_RECOMMENDATION,CATEGORY_STATUS */ String category = data.get("category"); String notificationCategory = ""; if (category != null && !category.isEmpty()) { category = category.toUpperCase(); switch (category) { case "CATEGORY_ALARM": notificationCategory = NotificationCompat.CATEGORY_ALARM; break; case "CATEGORY_CALL": notificationCategory = NotificationCompat.CATEGORY_CALL; break; case "CATEGORY_MESSAGE": notificationCategory = NotificationCompat.CATEGORY_MESSAGE; break; case "CATEGORY_EMAIL": notificationCategory = NotificationCompat.CATEGORY_EMAIL; break; case "CATEGORY_EVENT": notificationCategory = NotificationCompat.CATEGORY_EVENT; break; case "CATEGORY_PROMO": notificationCategory = NotificationCompat.CATEGORY_PROMO; break; case "CATEGORY_PROGRESS": notificationCategory = NotificationCompat.CATEGORY_PROGRESS; break; case "CATEGORY_SOCIAL": notificationCategory = NotificationCompat.CATEGORY_SOCIAL; break; case "CATEGORY_ERROR": notificationCategory = NotificationCompat.CATEGORY_ERROR; break; case "CATEGORY_TRANSPORT": notificationCategory = NotificationCompat.CATEGORY_TRANSPORT; break; case "CATEGORY_SYSTEM": notificationCategory = NotificationCompat.CATEGORY_SYSTEM; break; case "CATEGORY_SERVICE": notificationCategory = NotificationCompat.CATEGORY_SERVICE; break; case "CATEGORY_RECOMMENDATION": notificationCategory = NotificationCompat.CATEGORY_RECOMMENDATION; break; case "CATEGORY_REMINDER": notificationCategory = NotificationCompat.CATEGORY_REMINDER; break; case "CATEGORY_STATUS": notificationCategory = NotificationCompat.CATEGORY_STATUS; break; } } // Default notification visibility is private String visibility = data.get("visibility"); int notificationVisibility = 0; if (visibility != null && !visibility.isEmpty()) { visibility = visibility.toUpperCase(); switch (visibility) { case "VISIBILITY_PUBLIC": notificationVisibility = NotificationCompat.VISIBILITY_PUBLIC; break; case "VISIBILITY_SECRET": notificationVisibility = NotificationCompat.VISIBILITY_SECRET; break; default: notificationVisibility = NotificationCompat.VISIBILITY_PRIVATE; break; } } //creating default notification url for grouped notifications // if notification grouped, user cannot go the url corresponding to the each notification therefore assign a common url for the notification String defaultNotificationURL = "https://something.com" // Creating notification object NotificationDTO notificationDTO = new NotificationDTO( notificationId, groupKey, message, notificationURL, channelId, image, label, notificationPriority, title, notificationCategory, notificationVisibility, defaultNotificationURL); // Checking app is in foreground or background // if the app in the foreground this message service send a broadcast message // else app will create a notification in notification panel try { isForeGround = new ForegroundCheckTask().execute(this).get(); } catch (ExecutionException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } //Android implement new grouping and channel mechanisms after android API version 24, //So we need to implement different notification settings for both above 24 and below 24 if (android.os.Build.VERSION.SDK_INT >= 24) { createNotificationForAPILevelAbove24(notificationDTO, isForeGround); } else { createNotificationForAPILevelBelow24(notificationDTO, isForeGround); } } /** * Creating notification for api level above 24 * * @param notificationDTO NotificationDTO * @param isForeGround Boolean */ private void createNotificationForAPILevelAbove24(NotificationDTO notificationDTO, Boolean isForeGround) { Log.d(TAG, String.valueOf(isForeGround)); if (isForeGround) { Intent intent = new Intent(MY_NOTIFICATION); intent.putExtra("notificationURL", notificationDTO.getNotificationURL()); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } else { int requestID = (int) System.currentTimeMillis(); Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.putExtra("notificationURL", notificationDTO.getNotificationURL()); PendingIntent resultIntent = PendingIntent.getActivity(this, requestID, intent, PendingIntent.FLAG_ONE_SHOT); Uri notificationSoundURI = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); String defaultChannel = getString(R.string.general_notification_id); NotificationCompat.Builder mNotificationBuilder = new NotificationCompat.Builder(this, defaultChannel); mNotificationBuilder.setSmallIcon(R.drawable.ic_stat_notification); mNotificationBuilder.setColor(getResources().getColor(R.color.colorPrimary)); mNotificationBuilder.setContentTitle(notificationDTO.getTitle()); mNotificationBuilder.setContentText(notificationDTO.getMessage()); mNotificationBuilder.setGroup(notificationDTO.getGroupKey()); mNotificationBuilder.setAutoCancel(true); mNotificationBuilder.setSound(notificationSoundURI); mNotificationBuilder.setPriority(notificationDTO.getPriority()); if (notificationDTO.getImage() != null) { Bitmap bitmap = getBitmapFromUrl(notificationDTO.getImage()); mNotificationBuilder.setStyle(new NotificationCompat.BigPictureStyle() .bigPicture(bitmap)); } mNotificationBuilder.setContentIntent(resultIntent); if (notificationDTO.getCategory() != null) { mNotificationBuilder.setCategory(notificationDTO.getCategory()); } mNotificationBuilder.setVisibility(notificationDTO.getVisibility()); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); boolean areNotificationsEnabled = notificationManager.areNotificationsEnabled(); String appPushEnabled = String.valueOf(areNotificationsEnabled); notificationManager.notify(notificationDTO.getId(), mNotificationBuilder.build()); // Creating notification summary for grouping notifications Notification summaryNotification = new NotificationCompat.Builder(this, defaultChannel) .setContentTitle(getString(R.string.app_name)) .setSmallIcon(R.drawable.ic_stat_notification) //specify which group this notification belongs to .setGroup(notificationDTO.getGroupKey()) //set this notification as the summary for the group .setGroupSummary(true) //automatically remove the notifications from the notification tray .setAutoCancel(true) .build(); notificationManager.notify(getString(R.string.app_name), SUMMARY_ID, summaryNotification); } } /** * Handling notification for api level below 24 * * @param notificationDTO NotificationDTO * @param isForeGround Boolean */ private void createNotificationForAPILevelBelow24(NotificationDTO notificationDTO, Boolean isForeGround) { if (isForeGround) { Intent intent = new Intent(MY_NOTIFICATION); intent.putExtra("notificationURL", notificationDTO.getNotificationURL()); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } else { //Grouping notifications String storedNotifications = SharedPrefManager.getInstance(this).getNotifications(); JSONArray notificationArray; try { boolean isDuplicateNotification = false; JSONObject notificationObject = new JSONObject(); notificationObject.put("notificationId", notificationDTO.getId()); notificationObject.put("description", notificationDTO.getMessage()); notificationObject.put("title", notificationDTO.getTitle()); if (storedNotifications != null && !storedNotifications.equals("")) { Log.d(TAG, storedNotifications); notificationArray = new JSONArray(storedNotifications); for (int i = 0; i < notificationArray.length(); i++) { JSONObject json = notificationArray.getJSONObject(i); if (json.getInt("notificationId") == notificationDTO.getId()) { isDuplicateNotification = true; break; } } } else { notificationArray = new JSONArray(); } if (isDuplicateNotification) { //Notification already added to the tray return; } notificationArray.put(notificationObject); SharedPrefManager.getInstance(this).setNotificationDetails(notificationArray.toString()); Uri notificationSoundURI = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); NotificationCompat.Builder summary = new NotificationCompat.Builder(this); summary.setSmallIcon(R.drawable.ic_stat_notification); summary.setGroup(notificationDTO.getGroupKey()); summary.setAutoCancel(true); summary.setPriority(notificationDTO.getPriority()); summary.setColor(ContextCompat.getColor(this, R.color.colorPrimary)); summary.setSound(notificationSoundURI); summary.setContentTitle(notificationDTO.getTitle()); summary.setContentText(notificationDTO.getMessage()); summary.setPriority(notificationDTO.getPriority()); if (notificationDTO.getCategory() != null) { summary.setCategory(notificationDTO.getCategory()); } summary.setVisibility(notificationDTO.getVisibility()); if (notificationDTO.getImage() != null) { Bitmap bitmap = getBitmapFromUrl(notificationDTO.getImage()); summary.setStyle(new NotificationCompat.BigPictureStyle() .bigPicture(bitmap)); } /* * This is used to pass notification url to the main class of the application. * Based on this url MainActivity load the corresponding url into the web view */ Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); /* * checking more than 2 notifications received by the system, * then this will create a summary of that notifications. * else create a single notification */ if (notificationArray.length() > 1) { summary.setGroupSummary(true); NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); inboxStyle.setBigContentTitle(getString(R.string.app_name)); summary.setStyle(inboxStyle); int messageCount; for (messageCount = 0; messageCount < notificationArray.length(); messageCount++) { JSONObject json = notificationArray.getJSONObject(messageCount); inboxStyle.addLine(json.getString("title") + " " + json.getString("description")); } inboxStyle.setSummaryText(String.valueOf (messageCount) + " notifications"); summary.setNumber(messageCount); summary.setContentText(String.valueOf(messageCount + " notifications")); intent.putExtra("notificationURL", notificationDTO.getDefaultNotificationUrl()); } else { intent.putExtra("notificationURL", notificationDTO.getNotificationURL()); } PendingIntent resultIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); summary.setContentIntent(resultIntent); /* * One cancel intent is used to clear the notifications stored in * the shared preferences when user delete the notifications. */ Intent onCancelIntent = new Intent(this, OnCancelBroadcastReceiver.class); PendingIntent onDismissPendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, onCancelIntent, 0); summary.setDeleteIntent(onDismissPendingIntent); notificationManager.notify(getString(R.string.app_name), SUMMARY_ID, summary.build()); } catch (Exception e) { e.printStackTrace(); } } } /** * Used to load image from notification * * @param imageUrl String * @return Bitmap */ public Bitmap getBitmapFromUrl(String imageUrl) { try { URL url = new URL(imageUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.connect(); InputStream input = connection.getInputStream(); return BitmapFactory.decodeStream(input); } catch (Exception e) { return null; } } } 

The notification object class is as follows:

 public class NotificationDTO { private String groupKey, message, notificationURL, channelId; private String image, label, title, category,defaultNotificationUrl; private int priority, id, visibility; public NotificationDTO( int id, String groupKey, String message, String notificationURL, String channelId, String image, String label, int priority, String title, String category, int visibility, String defaultNotificationUrl) { this.groupKey = groupKey; this.message = message; this.id = id; this.notificationURL = notificationURL; this.channelId = channelId; this.image = image; this.label = label; this.priority = priority; this.title = title; this.category = category; this.visibility = visibility; this.defaultNotificationUrl = defaultNotificationUrl; } public String getGroupKey() { return groupKey; } public String getMessage() { return message; } public String getNotificationURL() { return notificationURL; } public String getChannelId() { return channelId; } public String getLabel() { return label; } public String getImage() { return image; } public int getPriority() { return priority; } public String getTitle() { return title; } public String getCategory() { return category; } public int getId() { return id; } public int getVisibility() { return visibility; } public String getDefaultNotificationUrl() { return defaultNotificationUrl; } } 

The SharedPreference manager is as follows:

 public class SharedPrefManager { private static final String KEY_FCM_TOKEN = "keyFCMToken"; private static final String KEY_NOTIFICATIONS = "keyNotifications"; private static SharedPrefManager mInstance; private static Context mContext; private SharedPrefManager(Context context) { mContext = context; } public static synchronized SharedPrefManager getInstance(Context context) { if (mInstance == null) { mInstance = new SharedPrefManager(context); } return mInstance; } public void setNotificationDetails(String descriptions) { SharedPreferences sharedPreferences = mContext.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString(KEY_NOTIFICATIONS, descriptions); editor.apply(); } public void setFCMToken(String fcmToken) { SharedPreferences sharedPreferences = mContext.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString(KEY_FCM_TOKEN, fcmToken); editor.apply(); } public String getNotifications() { SharedPreferences sharedPreferences = mContext.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE); return sharedPreferences.getString(KEY_NOTIFICATIONS, null); } public String getFCMToken() { SharedPreferences sharedPreferences = mContext.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE); return sharedPreferences.getString(KEY_FCM_TOKEN, null); } } 

and to create channels for notification, I use the application controller class, which extends the application class.

 public class AppController extends Application { public static final String TAG = AppController.class.getSimpleName(); @Override public void onCreate() { super.onCreate(); mInstance = this; /* Define notification channels here. */ //NotificationDTO channel is necessary //create a notification channel id in res/values/strings.xml if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Create channel to show notifications. String defaultChannel = getString(R.string.general_notification_id); String channelName = getString(R.string.general_notification_name); // String miscellaneousChannel = getString(R.string.miscellaneous_notification_id); // String miscellaneousChannelName = getString(R.string.miscellaneous_notification_name); NotificationManager notificationManager = getSystemService(NotificationManager.class); if (notificationManager != null) { notificationManager.createNotificationChannel(new NotificationChannel(defaultChannel, channelName, NotificationManager.IMPORTANCE_DEFAULT)); } } } 

The broadcast receiver is implemented to clear the general settings as shown below

 public class OnCancelBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d("ON_CANCEL","Cancelled"); SharedPrefManager.getInstance(context).setNotificationDetails(""); } } 
0
source

Source: https://habr.com/ru/post/1257494/


All Articles