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
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);
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'
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.
I have a method which receives text from a push notification, via the Parse API, and packages it into a notification object. Pretty standard stuff. My problem is that I'm trying to use a BigTextStyle to display my notification in the list, but it refuses to do so, and only shows one line of text and the two-finger gesture does not cause it to expand.
However, if I tap the notification, which opens the app, then return to the notification list, it is displayed in the BigTextStyle and is responsive to gestures. So, my guess is that somehow tapping on the notification is activating it and allowing the BigTextStyle code to kick in.
I like that tapping on the notification opens the app, but I don't want to force my users to open the app then close it again to see the full text of my messages. So is there a way I could either make the notification display in the BigTextStyle format from the start, or to make it so that the first click "activates" the notification, allowing the full message text to be seen, and then a second click opens the app? Any help would be appreciated.
Here is my code from the Notification method:
public void receiveNotification() {
NotificationCompat.BigTextStyle bts = new NotificationCompat.BigTextStyle();
bts.bigText(SplashActivity.globalDataString);
bts.setSummaryText("Tap to open app, swipe to dismiss message");
NotificationCompat.Builder m = new NotificationCompat.Builder(this);
m.setContentTitle("New Push Notification")
.setContentText(SplashActivity.globalDataString)
.setSmallIcon(R.drawable.app_icon)
.setStyle(bts)
.build();
Intent openApp = new Intent(this, MenuActivity.class);
// This ensures that navigating backward from the Activity leads out of
// the application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MenuActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(openApp);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
m.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(pushMessageID, m.build());
pushMessageID++;
//reset notification
flag1 = false;
}
EDIT: I think my problem is with where I'm calling my receiveNotification() method from. Right now I have it in the onCreate() method of my app's starting activity, which doesn't make much sense looking back. Should I put it in my broadcastReceiver class, or would there be a better place to put it?
Yes, the creation and display of the notification is usually done either in the broadcast receiver, or in an intent service started by the broadcast receiver. Only when the user taps the notification, the relevant activity is launched. You can see Google's client code sample here.