How can one differentiate the Notifications and pass them to different activities?
In the below method the third parameter(String tag) value is retreived from onMessage() that contains a value.
According to that value i wanted to differentiate which URL to open e.g Google or Facebook.
The app terminates after i include the intent code in the "if" conditions below.
Please Help
private static void generateNotification(Context context, String message,
String tag) {
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher,
message, when);
String title = context.getString(R.string.app_name);
Log.d("GCM", "Tag Value " + tag);
if (tag.equals("one")) {
// pass to a different activity
notificationIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.google.com"));
}
if (tag.equals("two")) {
// pass to a different activity
notificationIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.facebook.com"));
}
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
}
On Manifest create intent filter for activities,that you need launch like this
<activity
android:name=".activities.TabsActivity"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="com.dittoadvertising.push" >
</action>
<category android:name="android.intent.category.DEFAULT" >
</category>
</intent-filter>
when
Uri.parse("https://www.facebook.com") = action name in filter
and in your activities will be called method onNewIntent(Intent newIntent), then intent incoming
Change your code to something like :
if (tag.equals("one")) {
notificationIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.google.com"));
} else if (tag.equals("two")) {
notificationIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("https://www.facebook.com"));
}
Related
When push notification is received while the app is not running and the user presses on notification, it just disappears and the log says:
2019-10-22 12:42:45.747 23260-23260/de.app.test.staging E/FirebaseMessaging: Notification pending intent canceled
Here is the SplashActivity that is supposed to be launched as a Launcher Activity:
<activity
android:name="de.app.test.login.SplashActivity"
android:screenOrientation="portrait"
android:exported="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar.FullScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
What can the issue be here?
For anyone looking for an answer, the back-end was sending the "click_action" to notification, therefore there was no intent filter for that Activity.
For me the click_action is "OPEN_ACTIVITY_1" so I just added one more intent-filter to my SplashActivity like this:
<intent-filter>
<action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
you need to set pendingIntent object in notificationBuilder instance like
mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);
Intent intent = new Intent(context, TargetActivity.class));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
builder.setContentIntent(pendingIntent);
Please note that CHANNEL_ID is for build version greater or equal to Oreo
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CHANNEL_ID = createNotificationChannel(CHANNEL_ID, "channelName");
}
#RequiresApi(Build.VERSION_CODES.O)
private String createNotificationChannel(String channelId, String channelName) {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
String description = "description";
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE);
channel.setLightColor(Color.BLUE);
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
mNotificationManager.createNotificationChannel(channel);
return channelId;
}
Forground app:
You need a PendingIntent to open app.
Try this:
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Intent notificationIntent = new Intent(context, SplashActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
If Activity is in background or closed then notification message is shown in the notification center for app launcher activity.
You can use a BroadcastReceiver class. When you close the app, broadcast can listen this action. So, if you create a BroadcastReceiver class, you don't take this problem.
public class ClosedBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context, HomePage.class));
} else {
context.startService(new Intent(context, HomePage.class));
}
}
}
More Information:
https://firebase.google.com/docs/cloud-messaging/android/receive
I am trying to make notification with remove button, notifications are stored in SQLite DB and after the press, I want to remove "record" by id. Firstly I get a notification, store it to db , store unique id and pass it to a method which creates a notification. It gets fine in the method.
public static String CUSTOM_ACTION = "com.example.app.Services.REMOVE";
Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
snoozeIntent.setAction(CUSTOM_ACTION);
snoozeIntent.putExtra("NOT_WORKING", String.valueOf(id));
PendingIntent snoozePendingIntent =
PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);
Intent 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);
String channelId = getString(R.string.default_notification_channel_id);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.drawable.ic_stat_bell)
.setContentTitle("Loggly")
.setContentText(messageBody)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.addAction(R.drawable.ic_delete_forever_black_24dp, "Remove", snoozePendingIntent);
then I have a broadcast receiver for handling data from notification. Here is how it looks in my manifest file.
<receiver android:name=".MyBroadcastReceiver" android:exported="false">
<intent-filter>
<action android:name="com.example.app.Services.REMOVE"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
And here is the broadcast receiver the value which I got from extras is always null ... I have been trying to find a solution, but with no result.
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
String id;
if (extras != null) {
id = extras.getString("NOT_WORKING");
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager notificationManager = (NotificationManager) context.getSystemService(ns);
if (notificationManager != null) {
notificationManager.cancel(0);
}
Intent inten = new Intent(context, RemoveService.class);
inten.putExtra("NOT_WORKING", id);
context.startService(inten);
}
}
}
Finally, I am starting intent service, which should delete the "record" from the database, but when the broadcast receiver does not receive id it can't do anything.
I just created a sample notification on my side and the problem is the way you are creating the pendingIntent. Just add the proper flag to the pendingIntent parameter and it will work fine.
PendingIntent snoozePendingIntent = PendingIntent.getBroadcast(this, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
You can use FLAG_ONE_SHOT as well. If it satisfies your use case. You can go through different flags which can be used in PendingIntent
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.
I have this code to generate a notification from inside the GCM-Service:
private void sendNotification(Bundle extras) {
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
String notification_type = extras.getString("type");
NotificationManager notificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, extras.getString("message"), when);
String title = this.getString(R.string.app_name);
Intent notificationIntent = new Intent(this, InvitationActivity.class);
if ( notification_type != null && notification_type.equals("invitation"))
{
notificationIntent = new Intent(this, InvitationActivity.class);
notificationIntent.putExtra("lobby_id", Integer.valueOf(extras.getString("messagedata", "0")));
} else {
notificationIntent = new Intent(this, MainActivity.class);
}
// set intent so it does not start a new activity
//notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
// Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(this, title, extras.getString("message"), intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// Play default notification sound
notification.defaults |= Notification.DEFAULT_SOUND;
// Vibrate if vibrate is enabled
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(0, notification);
}
The Problem is that MainActivity starts if I click on the notification, however if
notificationIntent = new Intent(this, InvitationActivity.class);
is called and I tap on the notification, nothing seems to happen, no error, no activity is launched. This only occurs with InvitationActivity, Mainactivity is working fine.
InvitationActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_invitation);
lobby_id = getIntent().getIntExtra("lobby_id", 0);
EDIT:
AndroidManifest.xml:
<activity
android:name=".activities_fragments.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities_fragments.InvitationActivity"
android:label="#string/title_activity_invitation"
android:theme="#android:style/Theme.Holo.Dialog">
</activity>
The strange thing is, if I start InvitationActivity from within MainActivity it works as expected, but not from inside the GCMService.
Add
android:exported="true"
Inside your invitationActivity tag like this:
<activity
android:name=".activities_fragments.InvitationActivity"
android:label="#string/title_activity_invitation"
android:exported="true"
android:theme="#android:style/Theme.Holo.Dialog">
</activity>
This will resolve your issue
I am in a problem with the notifications in android, whenever I click the notification evrytime I have to call the same activity again, but as far as I am thinking the new activity is called but the previous is also running in the backend, due to which my code is running again and again ( becoz of multiple instances )
Please help me how to resolve or close multiple instances each time a notification is clicked.
code
public void notificationforChat(CharSequence message,String toJid, int notificationID) {
int notificationCount = 1;
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
int icon = R.drawable.ic_launcher;
CharSequence tickerText = message;
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
//notification.number = notificationCount++;
Context context = getApplicationContext();
CharSequence contentTitle = "Chat";
CharSequence contentText = message;
Intent notificationIntentforChat = new Intent(this, UserChatActivity.class);
notificationIntentforChat.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
notificationIntentforChat.putExtra("userNameVal", toJid);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
notificationIntentforChat, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(context, contentTitle, contentText,
contentIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults = Notification.DEFAULT_ALL;
mNotificationManager.notify(notificationID, notification);
}
thanks
Put the below code for that activity in maifest :
android:launchMode="singleTop"
Then for handling the new changes when the activity is called again, override the following method.
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//Do your new intent handling here.
}
The code you put in manifest makes sure that only one instance of that activity is created. and you can handle the changes required on new intent in the onNewIntent overrided method in that activity.
To prevent multiple instances of activity.
You can use android:launchMode="singleTask" in your activity
<activity
android:launchMode="singleTask"
android:name=".UserChatActivity"
android:label="Your title" >
....
</activity>
Once you call it. The onNewIntent(Intent) will be triggered with a new intent
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
What about starting the activity in android:launchMode="singleInstance" mode or android:launchMode="singleTop" mode. I think this helps.
Add to your calling intent
mIntent. setFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Add to the activity in menifest
android:launchMode="singleTop"