Android onKeyDown being called when service is running - android

My application is essentially a gps tracker. It binds a service to the GPSActivity which creates a thread to calculate distance, speed and things like that.
Before I had the gps thread in the service it was in the GPSActivity and worked fine. I'm switched it to a service so it would be able to persist in the background if the user needed to use another application.
However sometimes at the beginning of the gps tracking peroid the onKeyDown method in GPSActivity is being called with out me actually pressing the button.
Does this mean that onDestroy is trying to be called and that I'm using too much memory?
Any help to explain this behavior is greatly appreciated.

I solved my problem by adjusting my onKeyDown method as follows:
if(keyCode!=KeyEvent.KEYCODE_BACK){
return super.onKeyDown(keyCode, event);
}else{
//must be back button

Related

Android how to stop timer when app go to background

I know there are ton of questions as this have been asked in stackoverflow. Most of those suggest to implement onResume and onPause to control how the app behaves when it goes to background/foreground. But I couldn't actually use that method in my case.
I have a timer that will run when my application start (or after user login). So it is not dependent on any activity in my app. What I want to do is to stop the timer (to save power resource) when app goes to background and restart it when app come back to foreground. By implementing onResume and onPause will stop and start the timer when user switch between the activities (because I implemented in all the activities), and this is not what I wanted.
Please give advice how this to be done in better way.
You can use cancel() method in onPauso() so when the app are in background you stop the timmer
In the method onResume() you launch other time your Timer.
you can see method in:
http://developer.android.com/reference/java/util/Timer.html
extend the Application class and add a public static counter on it. On every onPause() and OnResume(), increment or decrement it, when the counter is zero you app is in background.

The GPS updates won't turn off after closing application

I have created an application that has a 'geolocation' feature responsible for spotting a user on the Google map like many other applicatons. I used "LocationManager.NETWORK_PROVIDER" to locate the user and at the same time I instantiate and start "MyLocationOverlay" (in the onLocationChanged() method) to get the location. Because of the second one, the GPS turns on (blinking on the top) which is OK.
The problem is, after the application is closed (back button or through task manager), the GPS feature is still hanging there, trying to get the updates.
How to turn it off after the user leaves the activity? I tried suggestions from here and other forums like putting locationManager.removeUpdates(this); and locationManager.removeUpdates(mMyLocationOverlay); within the methods onPause(), onStop(), onDestroy(). The method OnPause looks like this:
#Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
locationManager.removeUpdates(mMyLocationOverlay);
}
('this' references my class that implements LocationListener)
Please, can someone help me to turn off GPS updates after leaving the activity (it's a class that extends MapActivity) but not turn off the GPS feature on the phone itself?
Interesting thing is that when I remove the part with MyLocationOverlay, GPS will not start of course and therefore no problem. So I'm pretty sure that mMyLocationOverlay is the listener that "won't stop" and producing a problem.
googleMap.setMyLocationEnabled(false); in onPause() solved my issue. And I'm setting that to true in OnCreate(). Hope this may help others.
If you want to close (or end) the application you can use
System.exit(0);
so when the application is closed, all the services you use will close.
Set your LocationListener equal to null and re-instantiate onResume()

MyLocationOverlay won't disable location requests

Original:
Is there a way to kill a child activity of a TabActivity. I have a very simple tab setup. There are two tabs. One of the tabs contains a MapActivity. When I switch to the MapActivity the GPS turns on. When I press back, the TabActivity exits, but the GPS is still on. The gps doesn't turn off until I explicitly kill the app. Is there a way to kill the MapActivity from the TabActivity? I would like to kill it when TabActivity exits/onBackPressed.
Edit:
I do attempt to stop location requests in onDestroy and onPause in my MapActivity. I am using the MyLocationOverlay class an calling disableCompass and disableMyLocation in the onDestroy method. These methods are called, but the GPS remains on. If I call enableMyLocation and immediately call disableMyLocation (during onCreate), the gps will turn off.
Edited title to reflect the answer:
Turns out the problem is unexpected behavior with MyLocationOverlay's enable*/disable*. These functions do not appear to be idempotent. Multiple calls to enable and disable do not turn it on once or off once as one might expect. Ensuring one call to enable (in onResume) and one call to disable (in onPause) will disable location requests when exiting an activity.
The location service cannot be killed by stopping an activity, you should read up more on location services and how they operate:
http://android-developers.blogspot.com/2011/06/deep-dive-into-location.html
Specifically, when you request location updates from the providers (in your case the GPS provider) you should only request it for a certain period of time, and then you need to make a call to stop the requests.
Also see:
http://developer.android.com/reference/android/location/LocationManager.html
The best thing to do would be to override onStop() or onBackPressed() to stop the GPS. When you are in one of the activities, you have the option of calling getParent() to return the tab activity, as a side note.
It turns out that calling MyLocationOverlay.enable*() multiple times (I was calling it twice) makes the GPS stay on even if you call MyLocationOverlay.disable*() as many times. At least, this is the behavior I observed. I expected enable and disable to be idempotent, but they are not.
Related problem

Strange lifecycle behavior in my Screen Saver App

I just developed a screen saver app and I found a strange behavior in its lifecycle.
My work flow is like this:
start my RegisterService, where I call registerReceiver method to register a BroadcastReceiver, which can receive ACTION_SCREEN_OFF.
2.In the onReceive method of this BroadcastReceiver, I start an activity as the screensaver.
3.In the activity, I write Log.i() statement to track its running.
My question is:
When the screen times out, or when I press the POWER key, the screen turns off, and the system will send ACTION_SCREEN_OFF message. As I expect, my receiver starts the screen saver activity. However, I find this Activity calls onCreate(), onResume(), onPause(), onResume() sequentially according to the output in logcat.
It seems as if some a activity comes at front of my screensaver and finishes immediately, so my screensaver calls onPause() and then onResume().
Any idea? This problem handicaps me in programming, please help. Thanks!
Well based on a brief study of the PowerManagerService.java source code, when it's time to turn the screen off, the system initiates an animation (look at line 2183 for the class source) to do that. That means that your activity will pause and then will resume after the animation has ended.
I cannot be 100% sure for this, since I haven't tested it in my environment but this is the only logical explanation I found for your situation.
Hope this helps...
I can recommend you something very easy that might work for you, if you do not want the pause behavior why don't you try to Override the method onPause() and just do nothing :P don't call super.onPause() and that will terminate the behavior of it.
Other thing that might work for you, declare a static variable, add 1 on the "onResume()" method and return to "0" when "onStop()" is called. now just evaluate when the "onResume()" is called and if the variable is "0" then is the first time, anything else do nothing.
I hope this helps cause there is no much information on your question to be more specific.

Android : when to unregister the listener - onStop() or onDestroy()

I have basic question regarding when to unregisterListener for sensor manager. Should it be done in onStop() or onDestroy().
Usecase :
I want to record accelorometer on click of start button and stop when user clicks stop button. the frequency of data is every minute. So I have started a timer.
But the issue is every time the orientation changes as per Android architecture, onStop() gets called. In onStop() I am cancelling the timer and unregistering the listener.
SO again if I start timer/register listener in onResume() the frequency won't remain 1 minute and also the data gets recorded without user pressing the start button.
Can someone help me resolve this issue.
Thanks.
You may want to use a Service to run the accelerometer data collecting in the background, communicating with it using basic intents is not too complicated.
Or, if you only want to 'survive' the rotation, when the activity gets destoryed and then rebuilt, try overriding in your Activity the onRetainNonConfigurationInstance() and getLastNonConfigurationInstance() methods (read more about it here)
OnDestroy() isn't guaranteed to be called. So you should do it in either onPause or onStop
But the issue is every time the orientation changes as per Android architecture
There's a way to prevent this from happening in the manifest. I'm sure someone else will post how.

Categories

Resources