I'm configuring my notifications to open a new instance of ActivityDetail on click:
Intent resultIntent = new Intent(getApplicationContext(), ActivityDetail.class);
resultIntent.putExtra("object_id", objectId);
...
TaskStackBuilder stackBuilder =TaskStackBuilder.create(getApplicationContext());
stackBuilder.addNextIntentWithParentStack(resultIntent);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_CANCEL_CURRENT);
I build each notifications with a different id, as clicking will populate the ActivityDetail with results unique to the notification.
When I receive two notifications, the first one will open ActivityDetail correctly. Clicking the second notification, however, does nothing (except dismiss it), whether I remain on the ActivityDetail screen or not. Specifying the activity launch mode as "singleTop" makes no difference.
I don't seem to have any problems if there is only one notification displayed at a time, but if there are two, the second one always fails to open a new instance of the ActivityDetail on click. Any help would be appreciated.
I think this is happening because you are sending static request code '0' in 'getPendingIntent' method while obtain pending intent. send a separate value for each notification instead of '0'. it will work.
You need to do like this:
PendingIntent resultPendingIntent =stackBuilder.getPendingIntent(SEPARATE_INT_VALUE, PendingIntent.FLAG_CANCEL_CURRENT);
// Now change value of 'SEPARATE_INT_VALUE'
Related
I have a location service running and I want to alert the user if my main activity hasn't been active for several minutes, so from the service I am showing a notification with the code below (based on the example here), using a flag FLAG_ACTIVITY_REORDER_TO_FRONT instead of FLAG_ACTIVITY_NEW_TASK.
But it always starts a new copy of the activity, rather than carrying on where the existing one left off.
Intent resultIntent = new Intent(ctx, MainActivity.class);
resultIntent.setAction(Intent.ACTION_VIEW );
resultIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
// Create the TaskStackBuilder and add the intent, which inflates the back stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(ctx);
stackBuilder.addNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(resultPendingIntent);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(ctx);
notificationManager.notify(NOTIFICATION_ID , builder.build());
Just to clarify, all I want to happen when the notification is clicked, is the same as what would happen if the standard task-switch control is used to navigate back to my activity when a different app is in use.
The question here sounds the same as my situation, but all the answers explain in length about saving and restoring states. Why is this necessary, when I can switch between apps in the normal way without saving states?
I guess I'm misunderstanding something pretty basic here.
[Edit]
As mentioned in a comment below, I have now found an answer for Android 8. But my Android 10 device still restarts the app rather than just switching to it.
In logcat I see the following at the time of the attempted switch:
2021-01-22 22:48:57.585 26173-26173/? I/n.wandrerhelpe: Late-enabling -Xcheck:jni
2021-01-22 22:48:57.619 26173-26173/? E/n.wandrerhelpe: Unknown bits set in runtime_flags: 0x8000
then there is a 2-second gap before the log shows the app starting from the beginning.
[Later edit]
After comments and more tests, my intent for the notification looks like this:
Intent resultIntent = new Intent(ctx, NotificationActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 0, resultIntent, 0);
with the simple NotificationActivity as suggested by #David Wasser:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Now finish, which will drop the user in to the activity that was at the top
// of the task stack
finish();
}
All working well in Android 8 but not 10
This question already has answers here:
Open application after clicking on Notification
(12 answers)
Closed 3 years ago.
I have an android app which uses FCM for push notifications. There is a backend that sends push notifications
Every time user makes an image upload , a push notification is sent to whoever is subscribed to the topic.
On click of the notification in the notification tray I'm redirected to the first page of the app.
How can I make the push notifications work like how Instagram does.
On receiving a notification and clicking on it , I want to move to that particular screen and see the image that got uploaded.
If the user is in the app while the notification arrives. How to refresh the activity to display the content. Do I have to make a backend request to show the new data or can I display content from the notification itself?
Is there any example I can look at.
Any help will be appreciated. Thank you.
To start an activity that includes a back stack of activities, you need to create an instance of TaskStackBuilder and call addNextIntentWithParentStack(), passing it the Intent for the activity you want to start.
As long as you've defined the parent activity for each activity as described above, you can call getPendingIntent() to receive a PendingIntent that includes the entire back stack.
// Create an Intent for the activity you want to start
Intent resultIntent = new Intent(this, ResultActivity.class);
// Create the TaskStackBuilder and add the intent, which inflates the back
stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
My question is a bit complicated so I am going to describe it briefly what I want to achieve. My application receives messages from GCM without any issue. When application is running and is visible to the user I am not displaying notification in Action Bar, I am displaying this message in dialog alert. I use BroadcastReceiver to achieve this.
The main issue is that, when app gets a few notifications in no time. When main activity is visible to the user, the first notification will be shown in dialog alert. And next will be placed in Action Bar as usual Android notifications. And at this moment user disposes the dialog alert and is going to choose a next notification from Action Bar. At this moment I am using in my CloudService (extends IntentService) intent with flag Intent.FLAG_ACTIVITY_CLEAR_TOP and also PendingIntent.FLAG_UPDATE_CURRENT flag for pendingIntent. PendingIntent is just the contentIntent for my NotificationCompat.Builder.
It works in this way that for each user click on the notification from Action Bar, my activity is refreshing (floats to the lower device edge and then floats from the upper edge with dialog alert with message - I am getting the extras from the intent in onResume method). This action is quite OK. Activity has only one instance in that case - I don't have to break through the few instances of the same activity while I have opened few notifications. But the big problem is that when user chooses any of the notifications in each case the last one will open in dialog alert. Activity seems to has the same intent despite of PendingIntent.FLAG_UPDATE_CURRENT.
There are two methods in CloudService which handle cloud messages:
private void showNotification(Bundle extras) {
notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
String message = extras.getString(CloudMetaData.MESSAGE);
if (App.isMyActivityVisible() && !CloudMessageDialogFragment.isAttached()) {
sendBroadcast(message, NOTIFICATION_ID);
} else {
Intent intent = new Intent(this, MyParentActivity.class);
intent.putExtra(CloudMetaData.MESSAGE, message);
intent.putExtra(CloudMetaData.NOTIFICATION_ID, NOTIFICATION_ID);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentTitle(getString(R.string.app_name));
builder.setStyle(new NotificationCompat.BigTextStyle().bigText(alert));
builder.setContentText(alert);
builder.setAutoCancel(true);
builder.setDefaults(Notification.DEFAULT_SOUND);
builder.setContentIntent(contentIntent);
notificationManager.notify(NOTIFICATION_ID, builder.build());
}
NOTIFICATION_ID++;
}
And method which send broadcast is just like that:
private void sendBroadcast(String message, int notificationId) {
Intent intent = new Intent();
intent.setAction(ACTION_FROM_CLOUD_SERVICE);
intent.putExtra(CloudMetaData.MESSAGE, message);
intent.putExtra(CloudMetaData.NOTIFICATION_ID, notificationId);
sendBroadcast(intent);
}
In which way can I achieve similar solution? But it is important for user of course to open notification from Action Bar and shown him its correct message.
EDIT
I have switched my dialog alert into the dialog activity. This is its definition in AndroidManifest:
<activity
android:name="com.myapp.activity.CloudMessageDialogActivity"
android:theme="#android:style/Theme.Dialog"
android:parentActivityName="com.myapp.activity.MyParentActivity"/>
But the result is still the same - when app receives a few notifications, clicking on one of them will open the dialog with the intent for the last received notification.
But the big problem is that when user chooses any of the notifications in each case the last one will open in dialog alert. Activity seems to has the same intent despite of PendingIntent.FLAG_UPDATE_CURRENT.
That's because you are using the same request code (i.e., 0) for all PendingIntents here:
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
By doing so, you are ultimately receiving the same intent, because the platform is failing to see the difference between the intents and delivering the same object everytime:
... it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen. The parts of the Intent that are used for matching are the same ones defined by Intent.filterEquals. If you use two Intent objects that are equivalent as per Intent.filterEquals, then you will get the same PendingIntent for both of them.
So, instead of a constant value, please use a unique request code. For e.g. change the above line with:
PendingIntent contentIntent = PendingIntent.getActivity(this, NOTIFICATION_ID,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
Hope this helps.
My android application generates a notification. This notification is definid in the following way:
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_action_alarms)
.setContentTitle("title")
.setContentText("example text");
Intent resultIntent = new Intent(this, MyActivity.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this,0,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
So when I open the notification drawer and click on the notification area, the actvity MyActivity starts. But, If another instance of the MyActivty is already running, I obtain that two MyActivty instances will running at the same time, while I want that always just one instance at time, runs in my application.
I have tried using
android:launchMode="singleTop"
android:clearTaskOnLaunch="true"
but the result is the same.
How can I achieve this task?
Ultimately, you probably need to think about using Fragments, instead of Activities for the kind of UI interaction you are wanting (and really the way the NavDrawer is designed to work - and they way the official examples implement it).
You can use different intent flags to bring an old Activity back to the front, but this is really not the intended behavior you ultimately need (which is Fragment related).
Ex Intent Flags
Intent intent = new Intent(this, ActivityExamlpe.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Explanation:
I have used Daemon Thread.
In my application when user send any file (.jpg,.txt,.pdf etc) then it will generate the individual notifications for every file.
Suppose there are 3 notifications.
When user Tap on any of Notifications then it will call the android.content.Intent.ACTION_VIEW according to the file and suggest openwith option.
Problem:
When user select notification it will be opened in respective application(e.g If user selects sample.txt then it will be opened in colornote)and
after that when user tap on another notification then it will do nothing and onwards same thing happens.
I have passed also unique ID's for Notifications..!
long timestamp=System.currentTimeMillis();
int i=(int) timestamp;
mNotificationManager.notify(i, mBuilder.build());
Please help me find the error.
You need to add PendingIntent to your notification builder:
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MyActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
Read this article: Creating a Simple Notification