I have implemented push notification for the app. When notification is tapped, How to start the application from splash screen if the app is already killed. I want to start from Splash screen if the app is already killed and start from Inside landing screen if the app is already in the background. How to handle this? Please help me.
Add this code to your create notification method:
Intent resultIntent = new Intent(this, SplashActivity.class);
resultIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
resultIntent.setAction(Intent.ACTION_MAIN);
resultIntent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent resultPendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
Play around with the intent flags [resultIntent.addFlags(/*intent flag here*/)], if you want to:
start from Splash screen if the app is already killed and start from
Inside landing screen if the app is already in the background.
Hope this helps!
Use pendingIntent to specify the action which should be performed once the user select the notification.
Example tutorial Here
Related
I'm developing notifications in my app, and I'm having some issue with the pending intent that is driving me crazy.
Normal flow: My app has the launcher activity (Activity A, singleTop) which shows a Splash and then launches Activity B (singleTop too).
Notification:
When app is in background, I show a notification on the notification bar, which opens the launcher activity of my app when clicked, through a PendingIntent. This PendingIntent addresses to Activity A (singleTop). But in this scenario, instead of open Activity A, it brings to foreground the Activity B, but without calling onNewIntent() (onResume() is being called instead), so I can't retrieve the extras of the notification Intent and show the information, because this Activity B.getIntent() retrieves the old intent which opened the activity the first time.
Can any of you bring me some light on this issue, please?
This is how I set up the PendingIntent:
Intent notificationIntent = new Intent(context, SplashActivity.class);
notificationIntent.putExtra(StaticResources.EXTRA_NOTIFICATION_TYPE, "Notification");
notificationIntent.putExtra(StaticResources.EXTRA_NOTIFICATION_MESSAGE, "Message");
notificationIntent.putExtra(StaticResources.EXTRA_NOTIFICATION_TITLE, "title");
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Edited:
Following the answer given by #Woodi_333, the code for creating the pending intent is as follow.
Intent notificationIntent = new Intent(context, SplashActivity.class);
notificationIntent.putExtra(StaticResources.EXTRA_NOTIFICATION_TYPE, "Notification");
notificationIntent.putExtra(StaticResources.EXTRA_NOTIFICATION_MESSAGE, "Message");
notificationIntent.putExtra(StaticResources.EXTRA_NOTIFICATION_TITLE, "title");
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
Some code would help but I can take a guess at what is causing this.
So it sounds like the Activity Stack before clicking the PendingIntent is A,B. When opening the PendingIntent, it closes B because of FLAG_ACTIVITY_CLEAR_TOP but leaves activity A alone so it remains running.
So onNewIntent won't run because A is still running, and the FLAG_ACTIVITY_SINGLE_TOP flag won't cause it to run as when the intent is fired, it is not on the top of the history stack.
You might want to combine it with FLAG_ACTIVITY_NEW_TASK as suggested in Documentation for FLAG_ACTIVITY_CLEAR_TOP
I'd also recommend looking at the flags you defined in the manifest to see if they are interfering with the flags of the Pending Intent, or add them to the activities so every time you launch them, they are obeying the same rules.
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'm a bit confused with pending intents in the notification builder. I've got a MainActivity activity and a MessageList activity. I have a service to show a notification when a new message in found, and I want it to be that if the user presses the notification it opens to the MessageList activity but when they press back they will return to the activity they were in.
Essentially I want to add MessageList activity to the top of the activity stack when they press the notification without modifying the current activity stack.
Thank you
Okay, so I got it to work with some old code I wrote a while back. This does what I wanted -
Intent notificationIntent = new Intent(this, AlertListActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
mBuilder.setContentIntent(contentIntent);
I'm trying to add a notification icon to my application, that will function much like Waze's notification icon - when you open the status bar and tap on the "Return to MyApp" line, the application will move to foreground - with exactly the same activity stack state it had when it was moved to background.
I went over numerous SO questions, and found a lot of answers that are all very good if I know in advance which activity is going to be shown when the notification is tapped. I obviously don't know which activity it's going to be - it can be any of the app's activities.
I also tried sending a broadcast when the notification is tapped. I can the broadcast in my receiver alright, but from there I'm stuck with the exact same problem - I don't know which activity to launch - I can't find the last activity (I can only find the last task, but since my app has one task, it's no help).
you need to create a pending intent.
Like this:
Intent notifyIntent = new Intent(context, Chat.class);
PendingIntent intent =
PendingIntent.getActivity(Chat.this, 0, notifyIntent, SIMPLE_NOTFICATION_ID);
notifyDetails.setLatestEventInfo(context, contentTitle, contentText, intent);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
mNotificationManager.notify(SIMPLE_NOTFICATION_ID, notifyDetails);
please see this link
sample project
related
I currently have a notification that displays in the notification bar and when the user clicks it it should bring them to the root Activity of my application.
I have used android:finishOnTaskLaunch ="true" & android:clearTaskOnLaunch="true" in my manifest to achieve this when the user presses the app icon from the apps screen or the home screen. The user is always taken to the root activity as expected.
However when I use the following code from my notification the user gets taken to the last screen they were on rather than the root activity which is StartActivity.
Does anyone know what I'm doing wrong?
Intent notificationIntent = new Intent(this, StartActivity.class);
contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(getApplicationContext(), getString(R.string.notification_app_name), notificationText, contentIntent);
mNotificationManager.notify(1, notification);
Adding these flags helps however it still doesn't work after a restart:
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
When I restart my application I set a service running which pops up the notification and when I do this the notification reverts back to the old undesired behavior .
SOLVED:
Solved the issue by adding this flag to the contentIntent of my notification - Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED.
Here is an link with some excellent information on the area Google dev group
try this 2 properties
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);