I have this requirement to send my application background and then bring it to foreground on some key capture intents (not from application launcher offcourse) So How can I send the current tasks to background and bring the same to foreground ?
Use moveTaskToBack() to send the activity in the background and still running if the user presses the back key.
see :Activity for the way on how to do this. its quite simple.
so in order to do this you will also need to override the onBackPressed() method or onKeyPressed() and call this method if the back button was pressed (dont forget to return true on the back pressed methods so android is aware that you consumed the event and doesnt finish the activity).
For returning to this activity that you have moved to the background you can post a notification with a pending intent to launch it back and that will automatically bring the activity to foreground.
Hope this helps.
To send you application to background you should call moveTaskToBack() from your Activity class. When your Activity gets new intent (btw. the onNewIntent() method from your Activity will be called) your Activity gets into foreground by system (you don't have to do anything).
What do you mean by "background?" Activities are stacked one upon another as you create new Activities, then accessed in reverse order using the device's back button. Think of the push() and pop() methods, it's the same paradigm. Applications that need to have code running non-interactively should extend android.app.Service, but beware that you can do some real damage implementing a service. Rogue processes can drain battery life and reduce UI responsiveness.
I solve all the problem pertaining to notification start with fresh activity after moveTaskToBack(true) when back key is pressed by
adding to manifest android:launchMode="SingleTask" android:clearTaskOnLaunch="true"in the activity xml markup section
Related
I have a foreground service that calls StartActivity on ActivityA. If ActivityA is not in the foreground, it is displayed to the user. If the Activity is in the foreground, the service still calls StartActivity, and the activity receives a new Intent and updates itself accordingly.
The user may interact with ActivityA which will display ActivityB as a popup (Theme.Dialog), during which ActivityA is paused. Now if the service detects another event, it calls StartActivity again. This time though, I do not want to navigate to ActivityA. I want the user to still see the ActivityB popup and have ActivityA update itself in the background.
Is there any flags I could add to the intent which the service starts which will prevent navigation to ActivityA if it is Started but Paused?
Other Info :
1. If I have ActivityA bring ActivityB back to the foreground, ActiviyB end up flickering and just doesn't look good.
2. Have the service use ActivityManager to determine if ActivityB is displayed. If it is, broadcast an intent which will be listened to by ActivityA and force it to update, instead of calling StartService. But this couples the Service with two activites, needs more coding, and will force me to synchronize the service call onto the main thread to avoid timing issues.
I am really hoping there is something simple that I can do like set some flag on the intent. Or catch the intent within ActivityA, update the activity, but cancel the intent to prevent the screen navigation.
Any suggestions?
Note: Not using Android notification bar. Understand that starting activities from service is not recommended. We have a specific need for this.
Yes you can, if you are binding your service.. call bindService(mConn); in onResume() of your activity and unBindService(mConn); in onPause()..And in your service class, #Override the onUnbind() method and you can set the flag there.
I hope it was useful.
It sounds like you might want to use AtomicReference from java.util.concurrent.atomic to pass the right intent to start activity. I haven't actually tried this, but its probably a good place to start.
I have the following flow in my code:
Activity1 : startActivity(Activity2) --->
Activity2: startActivity(Activity3) --->
Activity3: startService(MyService) --->
MyService: startActivity(Activity4)
Each Activity above shows a single view and represents a step in a 4-step setup. The final Activity - Activity 4 - is started after some setup work is done inside MyService, which basically tells the user,
"The service has started, you can close the application by pressing Back or Home button"
When the user presses Back or Home, I want to destroy Activities 1-4 , and only have MyService running. Also, after stopping the Application as above, when the user navigates back to the Application via the menu and starts it, I'll be checking if MyService is already running. If it is already running, I don't want to show Activities 1-3, I want to show another Control Panel View (Another Activity), which says,
"Dude, the service is already running, do you want to Stop or Restart it?"
This view will have a Stop and Restart button, to do the appropriate tasks.
My Questions:
How do I stop Activities 1-4 from inside Activity 4 when Back or Home is pressed,safely? My thought was to add a static stopActivity() method to each Activity, and calling Activity[1-3].stopActivity() from onBackPressed() or onPause() of Activity4. Then inside each stopActivity(), I'll call finish(), thus ending each Activity. But is it safe and efficient to do it this way?
The flow I have illustrated above, is it the optimal way of doing things, or is there a cleaner way? I have BroadcastReceivers registered in these Activities, so I need to perform clean exits for each Activity, without leaked receivers, or worse, crashing the App or affect the User's phone due to unclean exit strategies.
Thanks for your suggestions.
You don't need to stop activities, Android will do it for you. Start your activities using intents with the flag FLAG_ACTIVITY_NO_HISTORY so they won't appear when the user presses back. Those activities will be stopped as soon as the user leaves them.
In the onStop method of each of your activities, write any code you want to deallocate memory if there is something you want to deallocate manually, although that wouldn't be necessary because Android will deallocate it for yourself when the device is short on memory. In those onStop methods unregister any BroadcastReceiverpreviously registered.
I have a callback inside an Activity which is called by a remote service. I fire a Toast when it gets called so, i know its getting called but its in the background, so I need a way from within the activity to make it go to the foreground. How can this be done. Also detect if I am in Foreground or not. How can this be done?
Using the Android Lifecycle you can detect if your Activity is in the background. To return your Activity to the foreground use a Notification in the Status Bar. You can forcibly move your Activity to the foreground by firing an Intent but that can cause frustration and annoyance to the user.
Just call startActivity with the right Intent.
Edit: Forgot to say, that it'a a very confusing behaviour, if an Activity brings itself to the front. The user could do something else and be disturbed. Set a notification instead.
I have an Android app. I have a main activity, that has a button. When the button is clicked, another activity comes to the foreground. The thing is, I want to run a background thread that polls updates from the server. However, I want it to run only when the app is in foreground (either the main activity or the second one), and to stop polling when the user clicks the Home button or clicks the Back button till it's going back from the main activity.
But how do I know if the app is still in the foreground? I can catch the onPause of the main activity, but it's called also when I'm launching the second activity.
So how do I know when the app is in background?
Thanks
You should make a Service for the work you are doing in the background.
For stopping it when you click the Home or Back button, just make a listener for them and stop the Service when either one is pressed.
Seems easiest to me that each activity polls. Is it super important that it can poll when it is between the two activities? Otherwise you will have problems about knowing who is in front or not.
You can have a singleton with reference counting.
You main activity should add the first reference on it's onResume and from now, upon calling for every new activity (startActivity for example) you should add a reference.
Each activity should decrease the reference counting on its onPause.
Another option is to use services: Services
I have a Service which tracks the location of the user. Currently, the Service boots when the application starts and stops when the application terminates. Unfortunately, if users keep the application in the background, the Service never stops and drains battery.
I would like the Service to stop when my application is not in the foreground. I was hoping the Application class would let me Override onPause and onResume handlers, but it does not have them. Is there another way I can accomplish this?
I haven't tested this yet, but it looks like if you use Context#bindService() (instead of Context#startService()), the service should stop when no more activities are bound to it. (see Service lifecycle).
Then use onPause()/onResume() in each activity to bind/unbind from the service.
Alternatively, you could add a pair of methods on your service which tell it to start/stop listening for location updates and call it from each activity's onResume()/onPause(). The service would still be running, but the location updates wouldn't be draining the battery.
Reading all the above answers I would suggest Simply add a boolean global flag for each activity & put it in your onResume & onPause & also while launching an Activity Something like this
public void onPause()
{
super.onPause();
activity1IsResumed = true;
}
&same for onResume
& similarly when launching a new Activity
startActivityForResult(myintent ,0);
activity2IsResumed = true;
activity1IsResumed = false;
then in your Service simply check
if(activity1IsResumed || activity2IsResumed || activity3IsResumed)
{
//your logic
}
else
{
//another logic
//or dont run location tracker
}
& you are done!
You should override the onPause and onResume methods on your Activity. If you have multiple activities you may want to have a common base class for them and put the start/stop logic into the base class.
I have not tried this approach but I think you can override the home key of android device by using KeyEvent.KEYCODE_HOME and you can use stopService(Intent) to stop your service and when again application resumes, you can write startService(Intent) in the onResume() method of your Activity.
This way I think your service will only stop when user explicitly presses home button to take application in the background and not when he switches from one activity to another.
What I would suggest is overriding the onPause/onReume methods as others have said. Without knowing more about the flow of your application and interactions between Activities, I can't give much more information beyond guesswork.
If your Activities are persistent, however, my recommendation would be to utilize the Intents better when switching between Activities.
For instance, each Activity should have a boolean "transition" flag. So, when you move from one Activity to the next, you set up an Intent extra:
intent.putExtra("transition",true);
Followed in the receiving Activity by: (in onCreate)
intent.getBooleanExtra("transition",false);
This way, for each Activity that launches, you can know whether it has come from another Activity, or if it has been launched from a home screen launcher. Thus, if it gets a true transition, then onPause should NOT stop the service--that means you will be returning to the previous Activity after it returns. If it receives no "transition" extra, or a false transition, then you can safely assume there is no Activity underneath it waiting to take over for the current one.
On the first Activity, you will simply need to stop the service if you are switching to another Activity, which you should be able to figure out programmatically if one Activity is started from another.
It sounds like the real problem is how to only stop the service when you go to an activity that isn't one of your own? One way would be to in your onPause method to stop the activity. Do this for all your activities. Then override your startActivity method. And in here do a conditional test to confirm that you are purposefully navigating to one of your own. If your are set a flag to true.
Now go back to your on pause overridden method. And only stop your service if the flag is not equal to true. Set the flag to false.
All events that navigate away will close your service. Navigating to your own will leave it intact.
Do the overriding in a base class that all your activities extend.
Writeen in my andolroid. Will post ezaple later.
Try using the Bound Services technique to accomplish this.
Bound Services | Android Developers
You can use bound services in a way such that the service will stop when no activities are bound to it. This way, when the app is not in the foreground, the service will not be running. When the user brings the app back to the foreground, the Activity will bind to the service and the service will resume.
Create methods registerActivity() and unRegisterActivity() in your Application object and implement first method in all you acts onResume() and second in acts onPause().
First method add activity to List<Activity> instance in your app object, unRegisterActivity() checks size of list in every call if==0 stopService();.