I am trying to start my activity from the notification and it is working but instead of starting the same activity, another (copy) of my activity gets launched when i exit from it I find another copy of the activity beneath it.
NotificationCompat.Builder b = new NotificationCompat.Builder(this);
....
Intent intent = new Intent(this, MyActivity.class);
intent.putExtra("item", currentObj);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
....
b.setContentIntent(pIntent);
how can I fix this ??
you have to use TaskStackBuilder and add its parent
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
and you have add it in the notification
stackBuilder.addParentStack(MainActivity.class);
What it does is simple it just says android about the parent of the present class you have opened! This should slove your problem. I hope this is helpful. Thankyou
You can call finish(); before b.setContentIntent(pIntent);.
There is a flag you can set that starts the same activity instead of a new one each time:
Intent intent = new Intent(this, MyActivity.class);
intent.putExtra("item", currentObj);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
You can add this line to your Activity inside manifest to prevent from loading the same activity multiple times
android:launchMode = "singleInstance"
OR
Flag the intent before starting Activity like this
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Related
I try to use local notification and it's actions. I want to create a notification and handle multiple action types. My notification asks a question to the user. There are two options, yes or no. My implementation is below:
Intent yesReceive = new Intent(this, this.getClass());
yesReceive.setAction("YES");
PendingIntent pendingIntent = PendingIntent.getActivity(this, CODE, yesReceive, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.addAction(R.drawable.icon1, "Yes", pendingIntent);
It recreates the activity. But old activity already alive. When I press back button, I can see it. How can I replace the new activity?
You can use "finish()" to close down the activity before you move onto the next one.
Here is a simple example:
startActivity(intent); <- here I am telling the program to start the desired actitvity
finish(); <- Here I am asking the program to close the current activity before I move onto the next one.
Intent yesReceive = new Intent(this, this.getClass());
yesReceive.setAction("YES");
PendingIntent pendingIntent = PendingIntent.getActivity(this, CODE, yesReceive, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.addAction(R.drawable.icon1, "Yes", pendingIntent);
finish();
I solve this problem with below line
android:launchMode="singleTop"
I am currently facing the problem of setting pending action for two different activities to notification.
I have a ParentActivity and a ChildActivity. I want open ChildActivity on notification click if currently it is running or paused, otherwise start ParentActivity.
I tried this :
.........
Intent resultIntent = new Intent(this, ChildActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(ParentActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
.............
Above is not working for me. Everytime ChildActivity is starting on notification click.
And also as Faruk answered, I dont want this. Creating a notification's pending intent by checking ChildActivity's current state will not work.
Suppose notification created when ChildActivity was running but after creating the notification, user killed the app. So after killing the app, If user will click on notification then ChildActivity will start. I don't want that. I want if ChildActivity is not running or paused then ParentActivity should be started.
How can I achieve this?
Please help.
While there may be several ways to achieve this, following is the one I can think of.
First, you should get whether ChildActivity is active or not, through this link
Check whether activity is active
Store this in some variable childActive, then you can initialize different notificationIntents checking the value without using task TaskStackBuilder.
For example;
Intent notificationIntent = null;
if(childActive)
notificationIntent = new Intent(context, ChildActivity.class);
else
notificationIntent = new Intent(context, ParentActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context,
0, notificationIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
Have your Notification launch a simple dispatch Activity. This Activity does the following in onCreate():
super.onCreate(...);
if (ChildActivity.running) {
// ChildActivity is running, so redirect to it
Intent childIntent = new Intent(this, ChildActivity.class);
// Add necessary flags, maybe FLAG_ACTIVITY_CLEAR_TOP, it depends what the rest of your app looks like
childIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(childIntent);
} else {
// Child is not running, so redirect to parent
Intent parentIntent = new Intent(this, ParentIntent.class);
// Add necessary flags, maybe FLAG_ACTIVITY_CLEAR_TOP, it depends what the rest of your app looks like
parentIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(parentIntent);
}
finish();
In ChildActivity do this:
public static boolean running; // Set when this Activity is active
In ChildActivity.onCreate() add this:
running = true;
In ChildActivity.onDestroy() add this:
running = false;
The MainActivity in my app has a launchMode of singleTop defined in the manifest file. Whenever I click a notification my MainActivity is re-created and the old instance is destroyed. MainActivity is visible and in the foreground when the notification is clicked, so I would assume the intent would be passed to the current instance's onNewIntent(), but this never happens. Here is the intent I create:
Intent resultIntent = new Intent(App.getInstance(), MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(App.getInstance());
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = PendingIntent.getActivity(App.getInstance(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
I sometimes add the FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_SINGLE_TOP to the intent like so:
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
I have also tried using the singleTask launchMode also with those flags and the same behavior has happened. Could someone lend some insight on this behavior?
You don't need to create a new TaskStackBuilder. Try intent which acts like you want to restart the application, but singleTop will keep it from doing so:
Intent resultIntent = new Intent(App.getInstance(), MainActivity.class);
resultIntent.setAction(Intent.ACTION_MAIN);
resultIntent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent resultPendingIntent = PendingIntent.getActivity(App.getInstance(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
from Android Development, i implement a simple notification by the sample code, but in my app, i don't want to new intent and create the activity again, i just want to back to my last activity(it's a mediaplayer UI). if i use the sample code, it will create a new activity by
Intent resultIntent = new Intent(this, ResultActivity.class);
i comment relative code about new intent and got a notification, but didn't have idea how to back to my last activity...
back to my app from long press home key and touch my app is OK.
what i want is just like this behavior.
bleow is the sample code from Android Development, i comment the new intent portion.
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!");
/*Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(ResultActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);*/
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(mId, mBuilder.build());
[UPDATE]
i thought i need to set flag for intent and properity for activity.
therefore, for the activity i want to back to i set
android:launchMode="singleInstance"
and because, i don't want a new activity from intent, i just want my last activity, so i add
Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
from documentation i got that using Pendingintent.contentIntent it must include the FLAG_ACTIVITY_NEW_TASK flag and When using this flag, if a task is already running for the activity you are now starting, then a new activity will not be started; instead, the current task will simply be brought to the front of the screen with the state it was last in. so i also add
Intent.FLAG_ACTIVITY_NEW_TASK
but from logCat, i still saw that when i touch the notification for back to activity, the pendingintent still called onCreate() function rather than just show the last activity which still "alive".
If you want to call the Activity from background try this:
Intent intent = new Intent(this, YourLauncherActivity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
intent, 0);
mBuilder.setContentIntent(pendingIntent);
If you click the Notification while on Homescreen the last shown Activity of your App will be get to the foreground without starting it new. If the Activity was killed by the system you will get a new Activity.
I have used PendingIntent.getActivities instead of getActivity. This is working well in my project.
Intent backIntent = new Intent(this, HomeActivity.class);
backIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Intent notificationIntent = new Intent(this, NextActivity.class);
final PendingIntent pendingIntent = PendingIntent.getActivities(this, 1,
new Intent[] {backIntent, notificationIntent}, PendingIntent.FLAG_ONE_SHOT);
For me, this worked :
.setContentIntent(
PendingIntent.getActivity(
context,
0,
new Intent(context, YOUR_MAIN.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP ),PendingIntent.FLAG_ONE_SHOT))
FLAG_ONE_SHOT : DO NOT CREATE TWICE (associated with
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP)
In SingleTop mode, I use this method without define explicitly the root activity class:
Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
.setComponent(getPackageManager().getLaunchIntentForPackage(getPackageName()).getComponent());
and this to resume last activity from notification:
builder.setContentIntent(PendingIntent.getActivity(context, 0, intent, 0));
or this to resume last activity from a service:
try {
PendingIntent.getActivity(this, 0, intent, 0).send();
} catch (CanceledException e) {
e.printStackTrace();
}
Code hear
Intent resultIntent = new
Intent(getApplicationContext(),MainActivity.class);
resultIntent.putExtra("splash",2);
resultIntent.putExtra("message","test");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent notifyPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationCompatBuilder.setContentIntent(notifyPendingIntent);
Intent intent = this.getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
String extraValue = extras.getString("notificationType");
if(extraValue !=null){
int value = Integer.parseInt(extraValue);
if (value == 1) {
intent = new Intent(SplashActivity.this,MainActivity.class);
intent.putExtra("splash",value);
intent.putExtra("message", "fromsplash");
startActivity(intent);
finish();
} else
if (value == 2){
intent = new Intent(SplashActivity.this,MainActivity.class);
intent.putExtra("swip","2");
intent.putExtra("message", "test");
startActivity(intent);
finish();
}
}
}
}
I am trying to launch an activity from the notification.
I have activity A. The activity A is launched from clicking on the notification. Once the activity A is launched, I like to get back to MainActivity upon pressing the phone's back button. To happen like that I implement as follow. The code is implemented in the BroadcastReceiver. I am having the compilation error at this line Intent resultIntent = new Intent(MainActivity.this, theClass); Because MainActivity.this is not valid in the BroadcastReceiver class. How can I make it correct?
Class theClass = Class.forName("sg.SanThit.TrackMe.NotificationListActivity");
Intent resultIntent = new Intent(MainActivity.this, theClass);
resultIntent.putExtra("MOBILENUMBER", tel);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(MainActivity.this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(theClass);
// 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);