Android FCM push notification, how to handle background event - android

Someone please help to solve it.
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// checking for type intent filter
if (intent.getAction().equals(Config.REGISTRATION_COMPLETE)) {
// gcm successfully registered
// now subscribe to `global` topic to receive app wide notifications
FirebaseMessaging.getInstance().subscribeToTopic(Config.TOPIC_GLOBAL);
displayFirebaseRegId();
System.out.println("If condition :" + Config.REGISTRATION_COMPLETE + "::" + Config.PUSH_NOTIFICATION);
} else if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) {
// new push notification is received
String message = intent.getStringExtra("message");
showAlertDialog(MainActivity.this, "Alert", message, true);
txtMessage.setTextColor(Color.GREEN);
Picasso.with(context).load(message).into(iImageView);
// txtMessage.setText(message);
System.out.println("Else condition :" + Config.REGISTRATION_COMPLETE + "::" + Config.PUSH_NOTIFICATION);
}
}
};
This is the code written in main activity, if the app is in the foreground it goes to else if part, if the app is in the background, it does not even enter into onBroadcastReceiver method, then how can I handle background event?

You can use downstream service of FCM
public class FCMMessageHandler extends FirebaseMessagingService {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
String from = remoteMessage.getFrom();
String title = data.get("title");
String content = data.get("content");
// here you need parse a message and ....
}
// Creates notification based on title and body received
private void createNotification(String title, String content, long id, Intent intent) {
Context context = getBaseContext();
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);
android.support.v4.app.NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher).setContentTitle(title)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setContentText(content);
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify((int) id, mBuilder.build());
}
}
Add to Manifest.xml
<service
android:name=".firebase.FCMMessageHandler"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/common_google_signin_btn_icon_dark" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/colorAccent" />

Able to handle push notifications foreground and background events , created a method for notification in Service class and in mainactivity added the below code
if (getIntent().getExtras() != null) {
System.out.println("Coming to if method");
String sMessage = getIntent().getStringExtra("message");
String sImageUrl = getIntent().getStringExtra("image");
String sPhoto = getIntent().getStringExtra("photo");
System.out.println("Result :" +sMessage + "::" + sImageUrl + "::" + getIntent().getStringExtra("is_background"));
for (String key : getIntent().getExtras().keySet()) {
String value = getIntent().getExtras().getString(key);
if (key.equals("is_background") && value.equalsIgnoreCase("True")) {
txtMessage.setText("Success :" + sMessage);
Picasso.with(this).load(sPhoto).into(imageView);
}
}
}

You can use
private void generateNotification(Context context, String message) {
int icon = R.mipmap.app_icon;
final int soundResId = R.raw.notification_sound;
try {
Intent intent = new Intent(this, TragetActivityName.class);
intent.putExtra("usedfor", "");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.driver_app_ico)
.setContentTitle("Application name")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager1 = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager1.notify(0 /* ID of notification */, notificationBuilder.build());
} catch (Exception e) {
}
}

So Inorder to change notification icon you add this in your android manifest.
<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="#drawable/ic_stat_ic_notification" />
Change icon form resources.
This is the simplest method to change notification icon.
You can change notification color by adding
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="#color/colorAccent" />
and follow this answer in Stack Overflow to open particular activity on click of notification. Read fcm documentation Here

Related

Stop receiveing notification FCM when apps is remove from Task Manager

I made apps that need to get a notification though the apps are closed. I'm using fcm to get the notification. But when the apps are removed from the recent task, I stop getting a notification. I had seen other article but I still can't get the answer to my problem.
I'm using firebase:
'com.google.firebase:firebase-messaging:11.0.2'
MyFirebaseMessagingService.java
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = MyFirebaseMessagingService.class.getSimpleName();
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.e(TAG, "From: " + remoteMessage.getFrom());
Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());
Log.e(TAG," remote :" +remoteMessage.toString() );
try {
JSONObject json = new JSONObject(remoteMessage.getData());
String title = json.get("title").toString();
String message = json.get("message").toString();
createNottification(title, message);
}
catch (Exception ex){}
if(remoteMessage.getNotification() != null)
Log.d(TAG, "Message Notification Body: "+remoteMessage.getNotification().getBody());
}
private void createNottification(String title,String message)
{
Uri notificationSoundURI = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);;
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.mipmap.pmi_launcher)
.setSound(notificationSoundURI )
.build();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getApplicationContext());
notificationManager.notify(Config.NOTIFICATION_ID, notification);
}
}
Manifest.xml
<!-- Firebase Notifications -->
<service android:name=".services.MyFirebaseMessagingService" android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".services.MyFirebaseInstanceIDService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
first pass PendingIntent and also pass unique notification ID for generate bunch or stack of notification. also set Flags for notification Intent.so just do this in this way. Hope it helps to you and also other users.
private void sendNotification(String message,String title) {
int id = (int) System.currentTimeMillis();
Intent notificationIntent = new Intent(this, SplashActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setContentTitle(title)
.setContentText(message)
//.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(image).setSummaryText(message))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
} else {
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
}
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(id, notificationBuilder.build());
}

FCM Notification click_action not working

I have a problem with FCM, when I receive the notification, I want it to opens specific activity, by the default when I don't add click_action it opens the main activity of the app, but when I add click_action and click on the notification it doesn't perform any action.
Here's the JSON I use in the web service:
{
"registration_ids": [
"f4............LL"
],
"notification": {
"title": "Rebate Confirmation",
"text": "Please Confirm",
"sound": "default",
"click_action": ".Activities.CustomerRebateConfirmation"
},
"data": {
"merchant_id": "20",
"customer_id": "1",
"points": "10",
"totalpoints": "100",
"message": "Please Confirm",
"type": "customer_points_rebate_confirmation"
}
}
and this is my onMessageReceived method:
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.e(TAG, "From: " + remoteMessage.getFrom());
customerRebateDetails = new String[5];
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Message data payload: " + remoteMessage.getData());
Log.e(TAG, "Message notification: " + remoteMessage.getNotification().getBody());
String type = remoteMessage.getData().get("type");
String message = remoteMessage.getData().get("message");
String text = remoteMessage.getNotification().getBody();
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
switch (type){
case "customer_points_rebate_confirmation":
customerRebateDetails[0] = remoteMessage.getData().get("customer_id");
customerRebateDetails[1] = remoteMessage.getData().get("merchant_id");
customerRebateDetails[2] = remoteMessage.getData().get("points");
customerRebateDetails[3] = remoteMessage.getData().get("totalpoints");
Intent customerRebate = new Intent(this, CustomerRebateConfirmation.class);
customerRebate.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
customerRebate.putExtra("customer_points_rebate_confirmation", customerRebateDetails);
PendingIntent customerRebatePendingIntent = PendingIntent.getActivity(this, 0, customerRebate,
PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder customerRebateBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(message)
.setContentText(text)
.setSound(defaultSoundUri)
.setAutoCancel(true)
.setContentIntent(customerRebatePendingIntent);
NotificationManager customerRebateManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
customerRebateManager.notify(0, customerRebateBuilder.build());
break;
}
Does anyone know what is the problem of the implementation?
Note that it works well when the app is in foreground but it's not working when the app is in background.
Make sure you have added this lines in your CustomerRebateConfirmation activity in Manifest file...
<intent-filter>
<action android:name=".Activities.CustomerRebateConfirmation" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
place intent filter in your Manifest inside activity tag which you want to use click performance in action you have to write same name which you had given in payload fiends.
<activity name="your activity name" >
<intent-filter>
<action android:name=".Activities.CustomerRebateConfirmation" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<activity>
try this in your MainActivity class.
#Override
public void onNewIntent(Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
if (extras.containsKey("type")) {
String type = extras.getString("type");
if (type.equals("test type")) {
Toast.makeText(this, extras.getString("message"), Toast.LENGTH_SHORT).show();
}
}
}
}
I have tried this when i am suffered from this issue. Hope this will be helpful to you.
MessagingServiceClass.java
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
int mNoti = 2019;
private final int NOTIFICATION_ID = 237;
private static int value = 0;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
String title = "0";
String type = "0";
String message = "0";
if (remoteMessage.getData().size() > 0) {
type = remoteMessage.getData().get("type");
title = remoteMessage.getData().get("title");
message = remoteMessage.getData().get("message");
sendNotification(type, title, message);
}
}
private void sendNotification(String type, String title, String message) {
Bitmap icon = BitmapFactory.decodeResource(getApplicationContext().getResources(),
R.mipmap.ic_launcher);
//AppMethod.setIntegerPreference(getApplicationContext(),NOTIFICATION_ID,)
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("type", type);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, value, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(icon)
.setContentTitle(title)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(value, notificationBuilder.build());
value++;
}
}
This question is 2 years old. But is still relevant. This is how you could do it with the firebase console (without `click_action).
When your app is in background onMessageReceived will not be called. But when you get a notification while your app is in background, you will get an Intent along with the custom data you specify in the firebase console.
So when the user taps the notification the intent will then be executed to open your launcher activity. You can check for the data by getIntent().hasExtra("key") in your launcher activity. Where the "key" is whatever key you specify in the console.
Check if you have that "key" then, you can make another Intent and call startActivity
Here is an implementation of mine,
On my SplashActivity > OnCreate (This method Looks best if you have a splash screen as the launcher activity):
if (getIntent().hasExtra("key")){
Intent intent = new Intent(this, TargetActivity.class);
startActivity(intent);
finish();
} else {
startActivity(new Intent(this, MainActivity.class));
finish();
}
This will just start the TargetActivity. You can add any functionality to this as per your wish :)
In your addFlags, try add Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK. It works for me.
in onMessageReceived() create
String click_action = remoteMessage.getNotification().getClickAction();
and replace your intent with this
Intent customerRebate = new Intent(click_action);

Get Firebase notification when app is in background (with only data-payload using REST client)

I want to receive notification when the app is in background with the data-payload only. I don't want to send any notification parameters like "notification" : {"sound": "default"}
Here is my code to receive the message and build notification.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String URL_KEY = "url";
private static final String TITLE_KEY = "title";
private static final String BODY_KEY = "body";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getNotification() != null) { //Here I made the dumb mistake
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
// Notification Data initialization
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
// String notificationTitle = remoteMessage.getNotification().getTitle();
String notificationTitle = remoteMessage.getData().get(TITLE_KEY);
// String notificationBody = remoteMessage.getNotification().getBody();
String notificationBody = remoteMessage.getData().get(BODY_KEY);
String receivedUrl = remoteMessage.getData().get(URL_KEY);
// BuildNotificaiton
Intent internetIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse(receivedUrl))
.setComponent(new ComponentName("com.example.suvajit.webview", "com.example.suvajit.webview.MainActivity"))
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
Random generator = new Random();
PendingIntent btn1Intent = PendingIntent.getActivity(this, generator.nextInt(), internetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setContentTitle(notificationTitle)
.setContentText(notificationBody)
.setSmallIcon(R.mipmap.ic_launcher)
.setSound(defaultSoundUri)
.setAutoCancel(true)
.addAction(R.mipmap.ic_launcher, "Previous", btn1Intent) // #0
.addAction(R.mipmap.ic_launcher, "Pause", null) // #1
.addAction(R.mipmap.ic_launcher, "Next", null) // #2
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
}
This is my manifest:
<service android:name="com.example.suvajit.webview.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name="com.example.suvajit.webview.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
And I'm sending notification using ARC
But when I'm sending only data payload notification is not received even if the app is in foreground.
{ "data": {
"url": "https://www.google.com",
"body" : "This is your message",
"title": "v-comply",
}
"to" : "dOa...hXIWnms"
}
When I'm sending sound or any thing else as notification parameter and the app is in foreground the notification is working as it should but when its in background its showing only my project name , the data part is not received I guess.
{ "data": {
"url": "https://www.google.com",
"body" : "This is your message",
"title": "v-comply",
},
"notification" : {
"sound": "default"
},
"to" : "dOa...hXIWnms"
}
Below there are two screenshots of notification when app in background and in foreground respectively.
How can I make it work to get notifications when my app is in background with only data-payload? Or am I doing something wrong? Someone please give a solution or guide me.
This was a very dumb and silly mistake which I have made. I was only sending data payload , but I was checking remoteMessage.getNotification() != null which means it doesen't run my code if there is nothing in my notification data. The condition should be like this
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getData().size() > 0) {
//Do stuffs to show notification with data payload only
}
}
After all my notification is working as expected.
This is for other users.
If someone wants to have both notification and data payload check separately they can include both conditions like this.
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getData().size() > 0) {
//Do stuffs with data payload only
}
if (remoteMessage.getNotification() != null) {
//Do stuffs with notificaiton data
}
}

Android clearing notifications not detected

I'm trying to stack push notifications with Firebase Cloud Messaging and I'm facing a problem, I don't know how to detect that the push notification has been cleared (with a sweep or with the Clear all button).
I've tried almost every tutorial I've seen on Stackoverflow with no success, so I'm missing something.
This is what I have right now:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
final static String GROUP_KEY_EMAILS = "group_key_emails";
protected PendingIntent getContentIntent(String data)
{
Intent notificationIntent = new Intent(getApplicationContext(), SplashScreen.class);
notificationIntent.putExtra("custom", data);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
return PendingIntent.getActivity(getApplicationContext(), 1, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
protected PendingIntent getDeleteIntent()
{
Intent intent = new Intent(getApplicationContext(), NotificationBroadcastReceiver.class);
intent.setAction("notification_cancelled");
return PendingIntent.getBroadcast(getApplicationContext(), 1, intent, PendingIntent.FLAG_CANCEL_CURRENT);
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if(remoteMessage.getNotification() != null)
{
try {
Map<String, String> data = remoteMessage.getData();
String customData = data.get("custom");
JSONObject customJSON = new JSONObject(customData);
final JSONObject pushData = customJSON.getJSONObject("custom data");
String message = remoteMessage.getNotification().getBody();
Notification notif1 = new android.support.v4.app.NotificationCompat.Builder(getApplicationContext())
.setContentTitle("My app")
.setContentText(message)
.setSmallIcon(R.drawable.icon)
.setAutoCancel(true)
.setGroup(GROUP_KEY_EMAILS)
.setContentIntent(getContentIntent(customData))
.setDeleteIntent(getDeleteIntent())
.build();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(1, notif1);
AuxiliaryFunctions.addPushNotificationsMessage(getApplicationContext(), message);
int notifId = AuxiliaryFunctions.readPushNotificationsMessagesNum(getApplicationContext());
if(notifId > 1)
{
NotificationCompat.InboxStyle style = new android.support.v4.app.NotificationCompat.InboxStyle()
.setSummaryText(notifId + " new messages");
JSONArray messages = AuxiliaryFunctions.readPushNotificationsMessages(getApplicationContext());
for(int i = 0; i < messages.length(); i++)
{
String localmessage = messages.getString(i);
style.addLine(localmessage);
}
Notification summaryNotification = new android.support.v4.app.NotificationCompat.Builder(getApplicationContext())
.setContentTitle("My app "+notifId+" new messages")
.setSmallIcon(R.drawable.iconplus)
.setStyle(style)
.setGroup(GROUP_KEY_EMAILS)
.setGroupSummary(true)
.setAutoCancel(true)
.setContentIntent(getContentIntent(""))
.setDeleteIntent(getDeleteIntent())
.build();
notificationManager.notify(1, summaryNotification);
}
} catch (JSONException e) {
}
}
}
}
This is my Notification Broadcast Receiver:
public class NotificationBroadcastReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Log.e("", "NotificationBroadcastReceiver:onReceive");
}
}
And finally I declare this in my manifest:
<receiver android:name="auxiliary.NotificationBroadcastReceiver">
<intent-filter>
<action android:name="notification_cancelled"/>
</intent-filter>
</receiver>
Well, the notifications are shown correctly, they are being stacked if there are more than one notification and if the user clicks on the notification (summary or not) everything is going well and the notification is processed with no problem.
But if the user makes a sweep in the notification (summary or not) or clicks on the Clear all notifications button, the notification dissapears but the NotificationBroadcastReceiver is never called (the log NotificationBroadcastReceiver:onReceive is not shown in the console).
What am I missing??
I'm very ashamed! I've found out the reason of my problem and it was complete stupidity.
In my AndroidManifest I had this:
<receiver android:name="auxiliary.NotificationBroadcastReceiver">
<intent-filter>
<action android:name="notification_cancelled"/>
</intent-filter>
</receiver>
I forgot the dot before auxiliary. Once I put it:
<receiver android:name=".auxiliary.NotificationBroadcastReceiver">
<intent-filter>
<action android:name="notification_cancelled"/>
</intent-filter>
</receiver>
the receiver callback was called.
What surprise me is that AndroidManifest gave no error resolving the wrong path.

Implementing deep linking in Localytics Push Notification

I am trying to implement Deep linking through Localytics Push notification in Android.In the below code I am able to receive the key value pair which I send through Localytics dashboard while creating the Push notification.
However, my requirement is to open a specific activity based on the key/value pair I receive in Push Notification.
public class GCMReceiver extends BroadcastReceiver {
String deeplink_key = "KEY_DEEPLINK";
public static final String CUSTOM_INTENT ="com.mypackage.action.TEST";
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
String deeplinkValues = extras.getString(deeplink_key);
Log.i("BASE", "deeplinkValues: " + deeplinkValues);
String action = intent.getAction();
Uri data = intent.getData();
Intent gotoOffersIntent = new Intent(context,OffersDisplayActivity.class);
gotoOffersIntent.putExtra(deeplink_key, deeplinkValues);
// gotoOffersIntent.setAction(CUSTOM_INTENT);
/*The below line opens the OffersDisplayActvity directly when Push notification is received*/
context.startActivity(gotoOffersIntent);
// context.sendOrderedBroadcast(gotoOffersIntent, null);
PushReceiver pushReceiver = new PushReceiver();
pushReceiver.onReceive(context, intent);
GCMBroadcastReceiver gcmBroadcastReceiver = new GCMBroadcastReceiver();
gcmBroadcastReceiver.onReceive(context, intent);
}
}
With the above code I am able to open OffersDisplayActivity on PushNotification received,But I want the OffersDisplayActivity to be opened when I click on the Push notification.
Please help me with this.Thank you!
You don't need deep linking for your requirement. Localytics guys sometimes misinforms developers by saying you need deeplinking for custom type of notifications.
We did same thing which you want to do in your app with localytics.
1)Receive Localytics information in your already implemented GCMBroadcastReciever.
2)In you message keep one field for identifying which Activity you want to open
If you added any extra Class for receiving intent with following action
com.google.android.c2dm.intent.RECEIVE
apart from your GCMReceiver then remove it..
In that way all notification either came from your server or localytics it will be received in onReceive method.
Here is complete example what we did for localytics and our own server..
Android Manifest.xml
<service
android:name=".gcm.CustomInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- for Gingerbread GSF backward compat -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.nearfox.android" />
</intent-filter>
</receiver>
<service android:name=".gcm.CustomGCMListenerService">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name=".gcm.RegistrationIntentService"
android:exported="false" />
in CustomGCMListenerService.java
public class CustomGCMListenerService extends GcmListenerService {
private static final String TAG = "CustomGCMListener";
public interface MESSAGE_TYPE {
String NOTIFICATION_NEWS = "news_notification";
String NOTIFICATION_EVENT = "event_notification";
}
#Override
public void onMessageReceived(String from, Bundle data) {
if (data.containsKey("msg_type") && data.getString("msg_type") != null) {
String messageType = data.getString("msg_type");
if (messageType.equals(MESSAGE_TYPE.NOTIFICATION_NEWS)) {
String newsJson = data.getString("news_body");
try {
JSONObject jsonObject = new JSONObject(newsJson).getJSONObject("message");
generateNotification(this, jsonObject.getString("title"), "", MESSAGE_TYPE.NOTIFICATION_NEWS, data);
} catch (JSONException e) {
e.printStackTrace();
Log.i(TAG, "Notification Parsing Error");
return;
}
} else if (messageType.equals(MESSAGE_TYPE.NOTIFICATION_EVENT)) {
String newsJson = data.getString("body");
try {
JSONObject jsonObject = new JSONObject(newsJson).getJSONObject("message");
generateNotification(this, jsonObject.getString("title"), "", MESSAGE_TYPE.NOTIFICATION_EVENT, data);
} catch (JSONException e) {
e.printStackTrace();
Log.i(TAG, "Notification Parsing Error");
return;
}
}
}
}
public static void generateNotification(Context context, String message, String ids, String messageType, Bundle data) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context);
notificationBuilder.setSmallIcon(R.drawable.small_notification_icon);
notificationBuilder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.app_icon));
String title = context.getString(R.string.app_name);
notificationBuilder.setContentTitle(title);
notificationBuilder.setContentText(message);
Notification notification ;
if (messageType.equals(MESSAGE_TYPE.NOTIFICATION_NEWS)) {
Intent notificationIntent = new Intent(context, SingleNewsActivity.class);
notificationIntent.putExtra("source", "notification");
notificationIntent.putExtra("news_title", message);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.setContentIntent(intent);
} else if (messageType.equals(MESSAGE_TYPE.NOTIFICATION_EVENT)) {
Intent notificationIntent = new Intent(context, SingleEventActivity.class);
notificationIntent.putExtra("source", "notification");
notificationIntent.putExtra("event_title", data);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.setContentIntent(intent);
}
notificationBuilder.setContentText(message);
notificationBuilder.setStyle(new android.support.v4.app.NotificationCompat.BigTextStyle().bigText(message));
notification = notificationBuilder.build();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
}
So here you can see if from localytics or from your own server you send GCM message which contains field "message_type"="news_notification" then user click on notification will open SingleNEwsActivity
and if "message_type"=event_notification" then it will open SingleEventActivity.. also here you can pass extra data with notificationIntent.putExtra()
Compare your key-value pair and based on it, call desire activity from Intent while generating push notification.
It will call it when user taps on notification.
// Set the action to take when a user taps the notification
Intent resultIntent = new Intent(context, LoginActivity.class);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (notificationObj!=null) {
resultIntent.putExtra(UserDefault.pushJSONObj, notificationObj);
}
PendingIntent resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_CANCEL_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
Here notificationObj is if any parameter you want to pass to your activity.

Categories

Resources