I'm working on android app that lets users switch to google navigation.
I've been asked to get users a solution to get back to the app without scrolling through list of open apps. I found the way to draw a button on top of everything but am struggling to get nice flow with activity life-cycle.
If user gets back to the app through manually selecting my app in list of existing apps - my app starts with onResume,
However if i force my app to get back via service button it is starting with onCreate and all unsaved data i had withing my activity is getting lost.
This is the code i use to call activity back via service and button
Intent myIntent = new Intent ( getApplicationContext(), PhoneView.class );
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
myIntent.addFlags(Intent.FLAG_FROM_BACKGROUND);
getApplicationContext().startActivity(myIntent);
I think i can putExtra bool in this call from Service and before i let user off my activity - i can save all the fields and recreate it back, but it feels like to much of extra work..
Is there a way to call my app from service and have it use existing activity, rather than to go through onCreate again assuming i know that my activity is running?
Related
I have two apps, click the button in app A will jump to app B due to deeplink. And in app B, there are two activities including SplashActivity and MainActivity, where I set the intent filter in SplashActivity that deeplink will bring it to in app B when the button in app A is clicked. And it worked fine for most time.
However, here is the situation. I open app A, click the button, and jump to app B's SplashActivity, which start MainActivity in a while and then finish itself. Till now it works fine, however, when I switch front app to app A, which means app B is in background now, and then I click the button again in the app A. This time it doesn't jump to SplashActivity(onCreate() and onResume() of app B are not called), but to MainActivity by calling it's onResume() callback, and the intent.data, which is sent from app A, is find to be null.
So why the deeplink didn't bring the app to the expected activity in the situation above? Begging for any answer!
When opening the deeplink while app is in background, doesn't launch the new app instead it open the current instance of the app. This is to avoid multiple instances of the same app.
In the manifest file, you need to add the follow to your main activity.
android:launchMode="singleTask"
With this, if an instance of activity already exists at the top of the current task, no new instance will be created because it will fire off an onNewIntent() method instead of creating a new object.
You can fetch and handle your intent data in onNewIntent()
I am making an application that will in fact contain two activities.
One will allow the user to log in and if done successfully will launch a web browser (MenuActivity).
The other takes a picture and uploads it to a server (PhotoActivity).
That web browser will have a link that when pressed will load my application in picture taking mode.
The flow is usually something like this:
MenuActivity->web browser->PictureActivity and then the last two steps repeat.
I have done this so far by setting my launcher activity as the MenuActivity and then putting using this code in the OnCreate override:
Intent mine = getIntent();
if (mine.getData() != null && !mine.getData().getPathSegments().isEmpty()) {
//retrieve the data here that I need
Intent i = new Intent(this, typeof(PhotoActivity));
i.PutExtra(//add here the data I received);
StartActivityForResult(i, START_PHOTO_INTENT);
}
after that I override OnActivityResult and send finish() if the requestCode is START_PHOTO_INTENT
This works correctly
my problem is that when I start the PhotoActivity from the web browser, if the user (while this is open) opens the application, then the MenuActivity shows (which it should) but when the user pressed back on it, it goes back to the PhotoActivity instead of exiting.
Is there a way to change this behaviour so that , even if the PhotoActivity is open, if the application is started manually, the PhotoActivity will not remain on the backstack ?
Thanks in advance for any help you can provide
Edit:
After reading the linked article at the solution and the answers to this question I came to the conclusion that in order to do what I want I had to set LaunchMode as singleTask in androidmanifest, and override MenuActivity's OnStop and send finish() after it was executed (if I didn't and the activity was in the backstack then it wouldn't be fired with the intent data when launched from a web page)
thanks for the help all of you
Look at the Handling affinities chapter in Tasks and Back Stack documentation. It is described how to handle this.
please do
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
This will start a new task for your application
i have 3 activities A-B-C .Lets say i am on activity B and from a listview there i launch activity C now if a notification comes which has an intent of launching activity C.
So the problem is I am getting multiple instances of activity C
When i use launchMode singleTop or instance or task the problem of multiple activity instance is solved but the newly launced activity does not work properely as it is desired to be.
Please help me out tired of using flags and stuff but not able to overcome this problem.
The scenario is Just like whatsapp , if u r talking to person one and a message of person 2 come as notification ,when u click on that notification the activity relaunches and works properely. This is exactly what i want. Please help me out how to achieve this . :(
Thanxx in advance
What Flags did you try and what exactly is not working, means, how does the Activity behave?
What you describe with WhatsApp could be achieved with two steps:
Use the FLAG_ACTIVITY_SINGLE_TOP for the Activity.
Overwrite the Actvity.onNewIntent(Intent intent) method in the Activity. This method is called instead of creating a new Activity and gives you the new Intent. I assume that the Intent contains all necessary information in the extras.
The user experience should be as follows:
User chooses from the list, which opens the new Activity
He/she can press home or back button from here. This brings the home screen or the list back.
If, for any reason, somebody else calls startActivity for your Activity while it is running, the onNewIntent is called. There you can add code to refresh the content, maybe have an Alert that tells the user that the content has changed, and shows all that to the user.
If the user presses back or home now, he/she will get to the list or home screen
If that is, what you're looking for, then the flag and the method is what you need
I am building an Android app, which starts a service that keeps running in the background. When the user uses the Home button to close one of the activities (which communicate with the service), and then navigates to the app again, they get the last activity. This is correct behaviour.
However, when I explicitly stop the service (via an option in the menu), the app should "Quit". Currently, that works like this:
stopService(new Intent(this, MyService.class));
finish();
// just go to to the home screen, as it is intended in Android
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
and that works fine. But when I now navigate to the app again, it starts the previously opened Activity. What I want is that it starts the starting activity again (the launcher).
How could I accomplish that?
System.exit(0);
But you should have only one Activity in stack.
If you look at the description of android:excludeFromRecents it says:
Whether or not the task initiated by this activity should be excluded from the list of recently used applications ("recent apps").
isn't this what you are looking for ? Once the user hits exit, this app won't be in the recently used apps and hence will be completely removed from memory ? :)
I think that removing 'the app completely from memory on exit' is not the issue. Even if you stop your service the process is likely to remain in memory - that is the systems' decision.
You want an explicit, custom behaviour - user chooses your 'exit' option from menu --> next app launch starts at main activity - so you will need to handle this explicitly.
The default behaviour is that the user returns to their last activity when they re-launch. So they only return to the main activity if they exit by 'backing out' through your activities. Your use of an 'exit' menu option is non-standard (not to say it is bad).
One option would be to do the backing out through your activities yourself. Perhaps now you are just finishing the current activity and you should instead finish all the activities in the back stack.
Another option is that you could save a flag, and when the UI is launched again you could read that flag and launch the appropriate activity (but again be careful with the backstack). The easiest way to set that flag is probably by overriding onSaveInstanceState(Bundle) and then reading the bundle in onCreate (or use sharedpreferences).
Have you tried setting the clearTaskOnLaunch to true for your main activity (in your manifest).
From the documentation:
When the value is "true", every time users start the task again, they are brought to its root activity regardless of what they were last doing in the task and regardless of whether they used the Back or Home button to leave it.
This seems to describe what you want to do. I have never tried this personally, but it seems worth investigating for your purpose.
I am calling one activity on click of status bar notification which is having a Complete button. on click of btn. i have folllowing code -
public void completeTask(){
taskDBAdapter.deleteReminder(rowId);
taskDBAdapter.close();
Intent intent = new Intent(this, TaskManagerActivity.class);
startActivity(intent);
finish();
}
whhen i click complete btn new activity (TaskManagerActivity) gets opened properly.But if i reopen my application it still tries to open this activity and not my default landing activity. Any help on this.??
EDIT -
I have tried repositioning my finish() statement . Still its not working.
EDIT 1.1 -
Ok I will provide some details here. Assume my app has two activities
Main Activity
Notification Activity
My app create some notification to display on Status bar. So as soon as i click on status bar Notification actvty will open. Now there is a button called Complete on click of which the code given will fire and main activity (in the code TaskManagerActivity.class) will open. But after I press back button in my app and again reopen it , it opens the notification activity when it should have fired the main activity (as it is launching activity).
Thanks,
Ray
That's the default way android functions. If you press the home button and then open your app again, it will restore the apps previous state (unless it has killed the apps processes and activities due to memory constraints). So you are not actually restarting your app but only restoring it.
If you wanna quit the app, then press the back button. Now when you re-open the app, the original activity will be launched.
Do not modify this behavior. It is the default system behavior and users expect it to work this way. Your app is fine :-)
- First of all the behavior which you are experiencing is the way Android is made to function, moreover when a user gets a call while this app is open, after finishing the app he will definitely want to get back to the state where he left the application.
Still if you want it that way, here it is.....
- Make sure your application has only single instance of it running, by using android:launchMode="singleTask", or android:launchMode="singleInstance"
- Then finish() your Activity at onPause().
#Override
void onPause()
{
super.onPause();
finish();
}