FCM Notification click_action not working - android

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);

Related

I dont get push notification when the app is running in the foreground

so i am making an app to get notifications but it only get the notifications when i close the app, but when i try to send notifications from the FCM when the app is in the foreground it wont receive any notification, and it crashes. What's wrong? can anyone help
This is my code
public class MyFirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
public MyFirebaseMessagingService() {
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//Check if message contains data payload
if (remoteMessage.getData().size() > 0) {
String title = remoteMessage.getNotification().getTitle();//get title
String body = remoteMessage.getNotification().getBody();//get body
String click_action = remoteMessage.getNotification().getClickAction(); //ge
sendNotification(title, body, click_action);
}
//Check if message contains a notification payload
if (remoteMessage.getNotification() != null) {
String title = remoteMessage.getNotification().getTitle();//get title
String body = remoteMessage.getNotification().getBody();//get body
String click_action = remoteMessage.getNotification().getClickAction(); //ge
sendNotification(title, body, click_action);
}
}
private void sendNotification(String title,String messageBody, String click_action) {
Intent intent;
if(click_action.equals("News")){
intent = new Intent(this, NewsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
else if(click_action.equals("Updates")){
intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}else{
intent = new Intent(this, MainActivity.class);
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.ic_launcher)
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
Have a look how you check and receive your data:
//Check if message contains data payload
if (remoteMessage.getData().size() > 0) {
String title = remoteMessage.getNotification().getTitle();//get title
String body = remoteMessage.getNotification().getBody();//get body
String click_action = remoteMessage.getNotification().getClickAction(); //ge
sendNotification(title, body, click_action);
}
Replace it with remoteMessage.getData().
The reason why it crashes: You checked if getData() is not empty. In foreground, both (notification and data payload) will be received in your onMessageReceived method (it won't crash because you can still collect the getNotification() data).
In background, the notification payload is not available and sent directly to the system tray, see https://firebase.google.com/docs/cloud-messaging/android/receive
Your code should look like this:
//Check if message contains data payload
if (remoteMessage.getData().size() > 0) {
String title = remoteMessage.getData().get("title");//get title
String body = remoteMessage.getData().get("body");//get body
String click_action = remoteMessage.getData().get("click_action"); //get action, maybe you have to debug this and look for the right key
sendNotification(title, body, click_action);
}
Have you added the service to the manifest?
<service
android:name=".MyFcmListenerService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
see the migration guide to see that you completed all necessary actions

Android FCM push notification, how to handle background event

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

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