More than one instance of activity due to intent - android

For an App I am developing, I override the back button to make it act like the home button so that the state of the main activity is preserved even when the app is exited. Now, I also send a notification to the user from time to time using a service. When this notification is pressed I want to open the main activity again. I noticed though that this creates a second instance of the app, which creates major problems. I am trying to make the main activity go to the front again, without calling oncreate again like so:
Intent to launch main activity again:
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
This doesn't work though. I still end up with two instances of my main activity. Does anybody know how to fix this?
By the way, I already have android:launchMode="singleInstance" in my manifest.

There's a way to force the OS to create only one instance of an activity and thats using the tag launchMode in the Manifest as shown below:
<activity android:name="YourActivity"
android:launchMode="singleInstance"/>
Hope this Helps...
Regards

Try adding this flag to the intent .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP), works for me.

Related

how to start launcher activity after app goes to background?

I want to always start launcher activity after app goes to the background. I tried android:clearTaskOnLaunch="true" but it not work. How can i do this? For example i have A,B,C,D,E,F activity. A is launcher activity.
now i open app so A activity is called then A>B>C. now i minimize the application. Now i open application from the icon so app is start from C but i want it start from A so how can i do this? some said use onResume intent with Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK. but what if i press back button then onResume is called and my app start with A activity.... so it is not work..any solutions???
You can check the App is in foreground or is in background and when the application goes to the background state at the same time do some logic that when your application comes to foreground it will always show the root activity.
How you can identify application is in which state is well explained here
When you start Activity B, use these flags. That way Activity B and C will always be in a separate stack. That means that when someone starts Activity A from the home screen they will see Activity A always.
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
Intent intent = new Intent(context, B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(intent);
Also this might help, you can add this flag to your root Activity.
<activity
android:name=".ui.MainActivity"
android:clearTaskOnLaunch="true"/>
This does because device store data about application. For short time data are stored. if you want to start application from rot class. use service with application, so that whenever your application goes in background and pause then choose your action to do that will be easier.

How do I get my existing Activity to display?

How do I get my app to appear in on the screen after it has been replaced by some other screen/activity? Some network event occurs and my application wants to reappear in the foreground (presumably in a polite manner).
I think I need to do something like:
contxt.startActivity(myActivity);
I don't want to create another instance of my app or cause it to restart, but I want it to appear.
Use FLAG_ACTIVITY_NEW_TASK
Intent intent = new Intent(contxt, myActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
contxt.startActivity(intent);
In your myActivity onNewIntent is called. I assume myActivity is the top activity in your app current stack

android - launchMode=singleTask and Notifications?

I know there's been a few posts for what I'm about to ask but I can't find any with the right answer.
From my understanding, if your main activity's (let's call it A) launchMode is set to singleTask, and A has initiated activity B then a click to the home button will destroy the history stack and re-launching the application will take you back to A and not B.
I have launchMode set to singleTask because I have a persistent notification and I don't want to have multiple instances of the main activity to appear whenever the user clicks on the notification.
Is there something I'm missing that would allow me to cater for both?
So I'm asking if there's a way I can ensure that whenever the user wishes to launch the app, from the notification or not, to take him back to the last (current) activity.
If I change launchMode to singleTop it works but I get multiple instances of the main activity whenever I launch it.
Thanks
Andreas
Have you tried setting launchMode to singleTop to all the activities in your app?? Because what i get from your query is that the main activity isn't singleTop, so that might lead to another instance of the main activity being called once the main activity is launched from the activity that was launched from the notification activity.
Or you can specify the launchMode as an attribute to the application tag itself in the manifest.
I use the following code to avoid multiple instances of the activity
Intent intent=new Intent(this,RICO.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
Changing manifest doesn't look appropriate to me
I'm having issues with both the approches.
The notification works flawless only in this condition:
- using the back button in the main activity (with the history containing only the that activity)
- not using the Home button
- not using the notification IF the activity you are calling is on top and active
In any other case, the notification cannot anymore call on the foreground the activity by using "new Intent(...)"
I've found the alchemical combination of manifest options and intent's flags for getting what I needed:
Intent intent= new Intent(this, YaampActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
using these options
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true"
inside the element.
Now I've a notification which spawns the main activity (if that activity is not already in the foreground) and its behavior is correct even if the activity is "closed" by pressing the home button and/or the back one.

Android AppWidget Configuration - Start in new task

I've searched and searched and searched for this!
So I've got an app widget and it has a configuration activity that I can open when pressing a button on the app. The scenario is:
Had the app opened.
Closed the app with the home button.
Selected to add my widget
I have configured the widget.
Placed on my home screen
Then open the configuration activity again with the button on the widget.
Cancel the new config by pressing back will put me back into the app.
When pressing back I want to just return home.
Basically what I'm asking is. How do I start the configuration activity in it's own task/stack?
I've looked into intent filters but I'm just not quite sure, or maybe it's something to do with the package it's in, or maybe it's just not possible!
I suppose it may have something to do with the intent I use to launch the config activity
Intent configIntent = new Intent(this, Configuration.class);
configIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
remoteView.setOnClickPendingIntent(R.id.config, PendingIntent.getActivity(this, 0, configIntent, PendingIntent.FLAG_UPDATE_CURRENT));
Perhaps because I launch it with 'this' as the context, it will always start in my applications stack...
but the pending intent api is:
PendingIntent API 1
"Note that the activity will be started outside of the context of an existing activity"
So yeah I'll stop talking now as I just end up going in circles!
EDIT
So tried android:launchMode="singleInstance" in the manifest like was stated. This worked however it stops the 'startActivityForResult' behaviour working correctly. (which is the whole reason for a config activity) Get the error:
WARN/ActivityManager(59): Activity is launching as a new task, so cancelling activity result.
So still haven't found a solution.
Ok sorted it :-) needed:
android:taskAffinity=""
in the manifest, setting the task affinity to an empty string allows for the activity to start in it's own stack, as it is not 'affiliated' with the rest of the application.
UPDATE
I have changed the task affinity to:
android:taskAffinity="com.my.package.alternative.task"
as each time I launched the activity it was showing up multiple times in the 'history'. So it now starts in it's own stack but is shared with other instances of the same activity.
Also need to add the Flag Intent.FLAG_ACTIVITY_NO_HISTORY to your intent :-) this stops your getting your application multiple time's in the history when you 'press and hold' the home button.
UPDATE
I've noticed FLAG_ACTIVITY_NO_HISTORY wasn't doing what I wanted, I've removed it and added:
android:excludeFromRecents="true"
into the activity tag in the manifest as well. The activity now behaves like I want :-)
Got this answer from the following link trail:
Tasks & Back Stack |
Managing Tasks |
Affiliation Tag
Try to put android:launchMode="singleInstance" for an activity of the app in AndroidManifest.xml

Why does starting an activity from a widget cause my main activity to start as well?

When I start an activitiy from a widget I want the back button to go to the home screen but instead it goes to the app's main activity. After toying around I found that if I somehow close the main app activity, this problem doesn't occur. Strange.
I found a solution here that said to call finish(); in my main activity's onPause(). Obviously this is the wrong solution e.g. reorientation of the screen causes an onPause() so the will activity will die whenever the phone is rotated.
This is how I start my activity:
#Override
public void onReceive(Context context, Intent intent) {
[...]
//new Emergency().emDialog(context).show();
Intent myIntent = new Intent(context, EmergencyActivity.class);
// FLAG_ACTIVITY_NEW_TASK is needed because we're not in an activity
// already, without it we crash.
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(myIntent);
You can see the rest of the code at http://code.google.com/p/emergencybutton/source/browse
edit: I tried running the activity differently, but still it doesn't work correctly:
Intent myIntent = new Intent();
myIntent.setClassName("com.emergency.button", "com.emergency.button.EmergencyActivity");
Ok, so I'm not exactly sure what happened here but android:launchMode="singleInstance" in the activity in AndroidManifest.xml fixed it somehow.
<activity android:name=".EmergencyActivity"
android:launchMode="singleInstance"
#Octavian - I should have clarified that I start the activity from an onReceive in an AppWidgetProvider. I'm at the home screen, starting an activity titled B, but somehow both A and B are in the activity stack instead of just B.
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
Although I've never used widgets, I believe that when you click the widget you are resuming an existing task. Hence, when you are in that task, you will return to the latest activity in that task (instead of Home).
See this link and choose the proper launch mode for your widget
http://developer.android.com/guide/topics/fundamentals.html#lmodes
The behavior is not strange it is just the way Android works. The activity stack just keeps track of the all the activities. Now when you start an activity A which starts another activity B then your stack looks like (B, A). If you press the back key then activity B is going to get popped off the stack and A is going to be brought to foreground again.
The right solution is to just call finish() right after firing off the Intent.
Sometimes it's not possible to use launchMode singleInstance in application for some reasons.
In this case, you should start your activity and clear activity stack. You can archive this using flags. There is an example:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

Categories

Resources