Start multiple activities from Notification via PendingIntent - android

I'd like to start multiple activities when press on Notification. I didn't find any docs about how to set multiple intents in a single PendingIntent.
One solution could be to start next activity in the first one's onCreate() and so forth, but I don't like this, maybe there is something else.

Finally, I got the answer for this - it's pretty trivial, just using method getActivities() to the PendingIntent like so:
Intent myIntent1= new Intent(ctx, MyActivity1.class);
myIntent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
Intent myIntent2= new Intent(ctx, MyActivity2.class);
Intent[] intents = new Intent[]{myIntent1, myIntent2};
PendingIntent pendingIntent = PendingIntent.getActivities(ctx, pid, intents, PendingIntent.FLAG_ONE_SHOT);

Related

PendingIntent launches different activity of the app package

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.

Passing extras from widget in PendingIntent to Activity

I can't find a way to pass extras from widget to Activity properly.
I wan't to open activity on button click with some extras passed.
Intent intent = new Intent(context, CreateOperationsActivity.class);
intent.putExtra("someKey", true);
PendingIntent pendingIntent = PendingIntent.getActivity(context, Constants.RequestCodes.CREATE_OPERATIONS, intent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.add_expense_button, pendingIntent);
Activity is opened, but there is no extra in the Intent.
The only way I was able to pass that extra was seting PendingIntent flag to PendingIntent.FLAG_ONE_SHOT but then widget button works only wonce, clicking it further takes no action.
How to do that so the extra is intercepted by Activity and the button works each time?
You're probably missing setAction() for your Intent ;) See this one for a better explanation: https://stackoverflow.com/a/3128271/515423

Cancelling a PendingIntent with unique requestCode

I'm having trouble with cancelling my pendingintent. Right now I create my pending intent like so:
Intent intent = new Intent(_self, NotificationService.class);
PendingIntent pi = PendingIntent.getService(this, task.getID, intent, 0);
task.getID is a unique int here. Later on in my app a user can edit a "task" and can decide to cancel the notifications (pendingintent). I try to cancel the pendingintent like so:
Intent intent = new Intent(_self, NotificationService.class); PendingIntent pIntent = PendingIntent.getBroadcast(_self, task.getID, intent , PendingIntent.FLAG_NO_CREATE);
pIntent.cancel();
But it doens't work! The notifications still shows up. In this case, task.getID refers to the unique id that was created before.
I've tried several different parameters, PendingIntent.FLAG_NO_CREATE returns null, FLAG_UPDATE_CURRENT doens't work and FLAG_CANCEL_CURRENT neither. Can somebody please help me with this and see what it is I am doing wrong?
You are trying to create a service with your PendingIntent and are trying to cancel a Broadcast. It will never work.
You need to getService with the PendingIntent you are trying to cancel.
You need to recreate your pending intent THE EXACT SAME WAY you created the first one when you want to cancel it.
take a look : Cancelling a PendingIntent

Again PendigIntent in notification

I'm notifying user about some events (in my case SMS receiving) and hanging PendingIntent like:
intent = new Intent(context, ConversationActivity.class);
intent.setAction(Constants.ACTION_SMS_RECEIVED);
intent.putExtra(MessageDAO.CONVERSATION_ID, message.getConversationId());
intent.putExtra(MessageDAO._ID, message.getId());
intent.putExtra(MessageDAO.ADDRESS, message.getAddress());
contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT );
My purpose is to start new ConversationActivity if there's no one, either just reuse old one (refreshing its content). But in fact my PendingIntent just use old one not refreshing it's content. I have checked that old extras still send to my ConversationActivity
What is the problem? I'm really stuck with it and can't understand what to do...
Update
I'm extracting extras in target ConversationActivity.onCreate() like:
Bundle bundle=this.getIntent().getExtras();
if(bundle!=null) {
conversationId=bundle.getString(MessageDAO.CONVERSATION_ID);
address=bundle.getString(MessageDAO.ADDRESS);
}
If you want to reuse an existing activity, you need to do the following. When creating the notification, add this:
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Then you will need to override onNewIntent() in ConversationActivity. This will be called (instead of onCreate() if the user clicks on a notification and there is already an active ConversationActivity. You will need to extract the "extras" from the Intent in onNewIntent() and replace the content with this new data.

Intent's flags and PendingIntent.getBroadcast

I get this exception in my code:
...IllegalArgumentException...Cant use FLAG_RECEIVER_BOOT_UPGRADE here...
Looking into the android source code seems like you can't set flags to an Intent that will be fired through:
PendingIntent.getBroadcast(...);
Here the Android source code:
...
if (type == INTENT_SENDER_BROADCAST) {
if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
throw new IllegalArgumentException("Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
}
}
...
Here my code:
Intent myIntent = new Intent(context, MyReceiver.class);
//myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if i remove the comment it doesn't work
PendingIntent pending = PendingIntent.
getBroadcast(context, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
The reason is not clear to me, anyone could clarify it for me please?
When you get a PendingIntent using getBroadcast(), this Intent will be broadcast to BroadcastReceivers. It will NOT be used to start an Activity. So you cannot set any of the Activity-related flags. They wouldn't make any sense in that context anyway.
Why would you want to set FLAG_ACTIVITY_NEW_TASK in an Intent that will be broadcast? That makes no sense.
Android uses Intents for 3 completely different purposes:
Starting/Communicating with Activity
Starting/Communicating with Service
Broadcast to BroadcastReceiver
The PendingIntent class offers 3 different methods to get a PendingIntent for each of these different purposes:
getActivity()
getService()
getBroadcast()
You need to make sure that you use the right method for the right purpose.
And yes, you can can set Activity-related Intent flags in a PendingIntent, as long as you call getActivity() to get the PendingIntent.

Categories

Resources