2

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();
Community
  • 1
  • 1
Allen Edwards
  • 1,488
  • 1
  • 27
  • 44

2 Answers2

1

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.

David Wasser
  • 93,459
  • 16
  • 209
  • 274
0

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).

Chris Stratton
  • 39,853
  • 6
  • 84
  • 117
  • I was about to answer this question but this pretty much covers it. Just want to add that the OP might find the Navigation app as a useful guide in implementing this behavior. – Alex Lockwood Jul 08 '12 at 17:22
  • That was easy. Obviously my exit button can turn the GPS and handlers off and after that I follow with HOME intent using this code. `code` Intent startMain = new Intent(Intent.ACTION_MAIN); startMain.addCategory(Intent.CATEGORY_HOME); startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(startMain); – Allen Edwards Jul 08 '12 at 17:23
  • @AllenEdwards and one last thing... the "back button" will end the task if you back out of your app's main activity... so I really think that if you want your app's navigation to be consistent with other Android apps, you should have it disable GPS (i.e. disable GPS in your main activity's `onDestroy` method). You can provide a confirmation dialog by overriding `onBackPressed` so that the user knows the task will be killed. Again, you can look at the navigation app for guidance. – Alex Lockwood Jul 08 '12 at 17:29
  • I just tested this solution more and find that when I call the program after exiting I go back to the exit screen. That is not good. – Allen Edwards Jul 08 '12 at 17:36
  • @AlexLockwood to be consistent with other applications of this type I do not want the back arrow to turn the GPS off. This is not really a navigation application so much as a speed, time, and distance application. – Allen Edwards Jul 08 '12 at 17:39
  • @AllenEdwards that is because when you launch the new activity with `FLAG_ACTIVITY_NEW_TASK`, a new task is started but the previous task still exists. So when you attempt to start the application again, it will return you to the old task (i.e. the top activity on the stack: the EXIT screen). This is another reason why it is not typically a good idea to mess around with the "back" behavior... it leads to un-intuitive navigation. – Alex Lockwood Jul 08 '12 at 17:40
  • @AllenEdwards (and sorry, I would help suggest a solution but I'm 100% certain about the behavior is you want). – Alex Lockwood Jul 08 '12 at 17:43
  • @AllenEdwards call the addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY) method of the Intent object you use to go to the EXIT screen, so it doesn't become part of the task history. – Chris Stratton Jul 08 '12 at 17:45
  • @AlexLockwood I removed the FLAG_ACTIVITY_NEW_TASK and it works the same. Exits to the home screen but returns to the EXIT screen. Adding finish(); after startActivity does the trick at least so far. – Allen Edwards Jul 08 '12 at 17:46
  • @AllenEdwards don't attempt to `finish` the Activity just after the new `Activity` has been launched. Use the `FLAG_ACTIVITY_NO_HISTORY` flag as suggested by Chris :) – Alex Lockwood Jul 08 '12 at 17:50
  • @AlexLockwood I removed the finish() and added this line startMain.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); it didn't work. Still goes back to the exit manu on resume. Obviously I did something wrong. – Allen Edwards Jul 08 '12 at 17:56
  • @ChrisStratton I just noticed your comment. Sorry. I am not sure what to do. The menu, which I must admit is a bunch of code I copied from an example, automatically creates the menus and there is no code that I write to call the EXIT screen. Also, I want a back arrow from my EXIT screen to return to the main menu. Maybe I am missing something in your reply but I do think that I will get in trouble once I put the real code in if I use the finish() command. It runs the menu OK but I am afraid it will run code that I don't want run. Maybe I don't understand your comment. – Allen Edwards Jul 08 '12 at 18:01
  • @AllenEdwards you need to find the code which uses an Intent to launch the EXIT screen and set this extra flag on the intent. – Chris Stratton Jul 08 '12 at 21:06