I am writing a GPS based application for Android. I want a button to exit the application which will turn GPS off but I do not want back arrorw or home to turn the processes off.
I have read This thread and many others that do a great job of explaining why I don't want to do what I want to do. The issue is that there are background processes and GPS is left running if I just back arrow out of the application. I understand that I can turn these off with OnStop() or OnPause() but I don't want back arrow or home to stop anything. I want all the GPS and handlers to continue running no matter what the user does unless he hits EXIT on my main screen which takes him to another screen that is to confirm the exit and do the cleanup. That way the user can back arrow out of the exit screen without actually exiting if it was hit by mistake.
Please understand that this application will be used in bright sunlight in adverse conditions with gloves on. It is very difficult to read anything so I use high contrast fonts 100 high. It cannot stop unless the user really wants it to stop. But just letting it run will kill the battery. I have no problem with the behavior of the system if I just let it run, just with the idea that the battery will run down and I don't want any simple button push, which may be accidental, to stop the services. I want it just as hard to kill this apps background processes as it is to turn the phone off, but I want to be able to do it.
I have tried finish(), which is just a back arrow, and every other method I have seen over the last three hours of Googling. I have thought of changing my EXIT button to a Turn GPS off button but then if the user uses back arrow to exit he gets to the main page and that turns GPS back on.
Just to be clear. My app has a menu based main screen. Any useful page will return to that menu if back arrow is hit. One of the menu items is EXIT. Hitting that menu item takes you to an exit screen that has a button that says EXIT. If the user got here by accident, he can back arrow back to the menu. If he hits the EXIT button on the exit page, I can turn off all the handlers and GPS and go to the phone or tablet home screen. At least that is what I want and can't figure out how to do.
I have used similar apps that use OnStop() or OnPause() to turn off the GPS and they are a pain. That is not what I want. Please don't tell me that is what I want to do. I know how to do that. That is not what I am asking.
Thanks.
UPDATE:
Thanks to Chris I have ALMOST solved this. I can turn my handlers and GPS off with my EXIT button and then run this code
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
UPDATE #2
The problem that I just found in further testing is that the application goes back to the EXIT screen when it is called for a second time.
UPDATE#3
Adding finish(); after startActivity(startMain) seems to work. The finish does a back arrow to the main menu. Hopefully once I get all my code installed it will still work. I removed the third line above so what I now have is this:
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startActivity(startMain);
finish();
There is a really simple way to resolve this. Your main problem is that you need the EXIT activity to not go back to the MAIN activity (ie: After the user EXITS, the activity stack should be empty) if the user wants to exit.
Have the MAIN activity call the EXIT activity using startActivityForResult(). The EXIT activity can then return RESULT_OK if the user really wants to exit, and it will returnRESULT_CANCELED if the user used the BACK button to go back.
The MAIN activity then gets the result in its onActivityResult() and can call finish() if the user really wanted to exit, or just do nothing if the user cancelled the exit.
This will result in the activity stack being completely cleared if the user wanted to exit, so that the next time the user starts the app, it will go to the MAIN activity.
I have thought of changing my EXIT button to a Turn GPS off button but then if the user uses back arrow to exit he gets to the main page and that turns GPS back on.
That is the root of a more proper solution than trying to "exit" the process - you just need to handle the accidental re-activation.
you could automatically send a HOME intent after disabling the GPS.
you could override the back button there, and send a HOME intent instead (if the GPS is off).
you could set a flag in shared preferences when you turn off the GPS to indicate that it is supposed to be off, then check that in any Activity where you would otherwise turn it on automatically. If you detect that the GPS is supposed to be off, instead of your usually choices just show a dialog that the GPS is off and ask if they want to turn it back on, or "quit" (ie Intent to the home screen).
Related
I'm working on a launcher app that basically launches other installed apps on the device with an explicit intent and I have a edge case scenario:
An Activity (Act) creates an intent of an application (App) and starts it by calling startActivity(intent).
App get launched, my Activity going to "stop" state.
After a while I want to get back to my application so I click on "back" hard button that closes App and bring my Application to foreground (resume state).
This is the wanted behaviour.
Here is the edge case:
If I click on the "recent applications" hard button (square icon) while on App is launched, history stack is lost, and when I return to App, and click on "back" hard button - App exists to the Launcher screen and onResume of my application is being called.
I searched the web for a solution for couple of hours now, maybe I'll find a solution here.
Thanks
It seems to me you should set android:alwaysRetainTaskState true in your root activity.
I would like to know the "idea / use" of the home versus the back button. I mean obviously the home button takes you to the home screen and the back button takes you to the previous screen. What I am trying to understand is what the users / development community expect.
In other words when a user hits home in my application should I handle that event and terminate the application? Is that what the user has grown to expect or just the opposite?
Same for the back button. Do users expect the screen being departed from to be lost much like a web page would be?
What I am getting at is trying to make sure my app behaves consistent with what the user community has grown to expect.
TIA
JB
Home Button will put application in onPause() -> onStop() , again when you relaunch application, the activity will execute the method: onRestart() -> onStart() -> onResume() -> i.e. activity life cycle
and
Back button finishes or kills the current Activity on click of back button and jump back to the previous Activity which is in stack.
Generally I'd say that pressing home is like minimising on a desktop. So I would expect the app to return to where it was.
If it acts like this then I can easily switch between apps if I need to get information from them.
Pressing back should take me backwards through the things I was doing in the app and when I reach the end of the stack it should close.
home button pressing causes an intent that is used by the the launcher app to show itself .
back button is a real event that can be caught within the current app .
in general , home button should hide all apps and go to the launcher , while back button should go back to the previous screen the user saw (finish the activity or dismiss the dialog) , and go to the previous app (task ) in case the current one doesn't have any more screens to show .
The community expects that if you press the home button, your app will go to the background and be resumeable from there. Multitasking is in the core of the Android OS. To finish your activity or app when home button is pressed is unusual to android users.
The back button is when you want to go one step back, like in the browser as you said. If you are know to IOS it will act like when you press the back button there in the top left corner.
Hope this helps
I would like to know the "idea / use" of the home versus the back
button
Let me Discuss for Back Button First.
The back button behavior is inconsistent.
for Users, it is very easy to use.
for Developer, to understand what actually pressing the back button does it isn't so easy.
The back button can perform any of the following actions as Officially said by Android site :
Go back to previous screen (activity)
Dismiss a popup
Terminate a long running process
Close on-screen keyboard
Go to previous page on browser
Exit the running app when on the last activity
Return to previous app when on the last activity and the app was launched through intent from another app
When Problem Occur with BACK button?
An added problem comes when trying to understand when the back button
cancels a running operation and when not. For example, when installing
apps from Android market tapping back takes users to previous screen
and leaves the installation process running in background. I know
there's a rule that back cancels operations that are presented users
as popup progress indicators and any other cases it is used to
navigate. But is that what users expect? Do users have to think before
pressing back to understand what is going to happen?
Home Button
Home button will take users to home screen and swiping in the
multitasking menu will kill the apps if needed. As on ICS on new
phones all the buttons are on-screen the back button could simply get
disabled when user reaches the last activity if the app was launched
from launcher icon. This would make some of the confusion to make away
but still wouldn't solve all the problems.
Finally , Don't Make Users Think Navigation is some what more important. Users should always know where they will endup without thinking.
I don't think there are easy answers for this problem but I think it may help you to find workaround for your problem according to your app.
What I do know is that the current activity get into the onPause() mode, and the home screen activity brought to front.
My confusion starts with situation you can re-open the application from the recent tasks menu.
so what exactly happening when I'm opening the application from the recent tasks manager?
Is the activity that was foreground when the home button pressed is still somewhere in the stack?
Is there more then one activity stack on the same time?
As far as I understand it, there is no real stack (of applications). Is just that your activity has states, so whenever you are pressing the HOME button your activity in your current application just "pauses" like if it was a stand-by state so multiple applications can be in this state as long as the system doesnt require memory and kill the tasks.
So whenever you open the activity from the recent tasks its just telling the application to wake up.
First of all, here is everything you need to know about the concept of the "Up Button":
Navigation with Back and Up and some of the implementation details: Providing Ancestral and Temporal Navigation.
Generally speaking, the Up button lets you navigate up in the application hierarchy, instead of just navigating back in the application(s) back-stack.
For example, if you work with some kind of app and you get the email notification, you can open the mail client by pressing the notification. Then you can go back to you application you were working with by pressing the Back button ( back-stack ) or you can press the Up button in order to go to the mail client's 'parent' activity ( for example from some EmailMessageActivity to EmailHomeActivity ) to work with the mail client application instead of the initial application ( the back-stack usually is cleared then, so you can only go back with the Back button as far as the the Android Home screen ).
The "Recent Tasks" factor is irrelevant and misleading, it's just another way of starting a new Activity.
My app is designed to run as a single instance and the Back button does not allow you to exit the app and return to the Start screen because it is used internally to navigate a hierarchy of screens where each screen can be an activity.
However, an external app can launch one of the app's internal activities. When the user is done with whatever the activity is designed for, the user's intuitive action is to hit the Back button to return back to the calling client. But because I prevent the Back button from exiting, the user cannot return.
I can add code to override this when the code detects that the activity is being launched by a client. The problem however is that if the app closes to return, the user might return to the app from where they left off. But since I closed the app to return to the calling client, the user cannot return back to the app as it was last opened. My app needs to remain as a single instance, so the activity that gets launched cannot be created more than once. Any suggestions on how to return back to the calling client but also keep the app running if it was running when the calling client used one of its activities?
In general, you can programmatically control the back navigation trail. Take a look at
TaskStackBuilder and the documentation for handling notifications Responding to Notifications. It seems that what you're trying to do is control the so-called "back stack". If you use TaskStackBuilder, the behavior will match the platform version you're on.
In pre 3.0 platforms, the Back button went all the way through the back stack to the first task the user did since the phone was turned on. Post 3.0, back does not traverse task boundaries; to get to other tasks, the user clicks the "Recent Items" icon. There's also the "up" icon in an app to navigate to the "beginning" of a task within an app. TaskStackBuilder will "do the right thing" for all versions.
In the current platform version, not allowing Back to exit your app is OK, because Back should only go to the first Activity in the current task. In versions previous to 3.0, not allowing Back to exit the app is more problematic, and I personally wouldn't do it that way, but it's up to you.
What happens when the user clicks Back after an Intent starts your app should be clear from the documentation I've cited. Basically, what you want to do is go back to the previous task.
When would you need an Intent that takes you to the home screen? Because doesn't that mean you no longer have control of the application?
For example, what could you, as a developer, do after the following code was executed:
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
That is a much trickier question that you probably think. First of all, in real life you would not normally do that. If you are finished your activity, you call its finish() method. The android system returns you to the activity you called your activity from, which if you launched it from the home screen would be your homescreen. But if you launched it from some other application, like looking at a map of the address of one of your contacts for example, you would be returned to your contact app when you "finish()" on the map activity.
When you launch an activity with an intent, depending on the exact nature of that activity, you may open a new instance of that activity in the process your activity is running in, or you might just bring to the front a different process already running that application/activity. In the case of the home screen, I don't know exactly what happens because I don't know how the home screen is programmed as an application/activity, and how it is declared in the manifest.
For giggles, I put your lines of code in the onCreate() of the main activity of one of my applications. I got fairly erratic behavior. The intent definitely threw me out of my app and seems to have destroyed the process my application was running in in the process. (At least in eclipse, it terminated the ADB connection so I could no longer see what was happening with it.) When I went back to my main activity from the homescreen, it would sometimes go back to the main screen of my app, sometimes to the secondary screen of my app, and sometimes just pop back to the homescreen again. I imagine the other lines of code calling intents for my secondary app were part of the "state" of my app somehow, that somehow going back it would somehow come in after launching the home activity.
Obviously I am waffling around here. I'll leave this to others who might put an answer in the context of something that would really benefit from calling an intent to launch a homescreen, rather than using "finish()" to get away from the activity.