I have an android application. Based on the current geo location of user, I want to fetch some remote data in background and store it. My implementation is:
At specific interval a alarm fires up my service. Service uses an anonymous class to query current location and registers a locationListener callback. On call of onLocationChanged() I initiate the remote data fetch from server.
However once my service is done registering the location listener using anonymos class, it returns as expected; as it doesn't wait for callback to happen before finishing. Since callback takes some time and makes a call when service has already returned, it throws an error saying:
java.lang.RuntimeException: Handler{43e82510} sending message to a Handler on a dead thread
Which is quite understandable. One quick workaround for me now is that I can use getLastKnownLocation from locationManager as that doesn't respond back by callback; but what if I do want the latest location right now, in a service and not activity? How can I wait for callback to happen and stop my service from returning.
Also, at what point does lastKnownlocation gets updated? Everytime GPS registers a new location; does it update it? What I want to know is that if it's not latest can it still be closed to latest? As I didn't see an option in android emulator to configure the time period between subsequent updates.
Any help is much appreciated.
Cheers
but what if I do want the latest location right now, in a service and not activity?
Sorry, but that is not possible, in either a service or an activity. For example, if the GPS radio is off, and you are requesting location data from GPS, it will take tens of seconds just to get a fix, and that's if you are lucky. It might not get a fix at all.
How can I wait for callback to happen and stop my service from returning.
You don't. You do what you said you would do:
use getLastKnownLocation from locationManager as that doesn't respond back by callback
So, have your Service (which is hopefully an IntentService) check to see if getLastKnownLocation() happens to have a value. If it does, use it. Otherwise, registerLocationUpdates() using a PendingIntent that will pass control back to your IntentService. When you get that Intent, use the location and unregister for updates (assuming the alarm period is nice and long, like, say, once an hour).
Things get tricky if your alarm is a _WAKEUP alarm. You will then need to hold a WakeLock, so the device does not fall back asleep while you are trying to get a GPS fix. However, you need to release that WakeLock sometime, and if we cannot get a GPS fix...ummm...well, that's the tricky part. Trying to figure out a nice clean way of handling this, and implementing it as a reusable component (e.g., LocationAlarmService), is one of 18,000 items on my to-do list.
Also, at what point does lastKnownlocation gets updated? Everytime GPS registers a new location; does it > update it?
AFAIK, yes.
Related
I need to keep rough track of a users position, but not really in real time. It's sufficient to handle the location updates when the app is started. However, I still need to know where the user was when the app wasn't running.
Is there a way to get the location history in an app?
I don't really want to have a service just polling last known location all the time since that would be a waste of battery power.
However, I still need to know where the user was when the app wasn't running.
That is not possible.
I don't really want to have a service just polling last known location all the time since that would be a waste of battery power.
Then eliminate your requirement for location history. You only get the locations that you request.
Rough Track can mean you get location of the user (lastKnown or Fresh) after every n-hours. Doing this will not require a service, simply a recurring alarm and receiver will do. In the onReceive method of receiver, you can manage a stack of locations in your app.
You will have to reset the alarm though when the device re-boots. I guess this is an add-on, rest should work fine.
you can not get current location without running your app...
the second way is to make background service ..wich you don't wan't to make...
The other way is to run background service using Alarammanager whenever you want after getting location you can stop the service...like you can make call every hour or 2 times per day...
I am a beginner. I want to develop an application which can generate location based notifications. In android developer website I found in order to maintain a balance between battery life and data exchange one should consider
frequency of new updates
window in which you listen for location updates.
I know frequency can be controlled by calling requestLocationUpdates(). My question is how can I control the window in which I listen for updates ? Does it mean that once I acquire the location update from onLocationChanged() method of LocationListener class, I should stop listening for updates using removeUpdates() ??
Thanks
GPS device only start working (and consuming power) when you register for requestLocationUpdates().
Teoretically the GPS can switch off between updates if they are not very frequent. Let's say for example that you have requested updates every 5 minutes, then the GPS can switch off for 4 minutes and 30 secounds aprox. and switch on in time to acquire the next location. If you set the new locations requests for every 5 secounds, GPS will not switch off between updates.
I have one application that keeps GPS awake full time, recording the locations in a database. This application can also show a map and draw the track recorded. My experience is that the power used to draw the map with track changing in real time is much higher then the power used by the GPS.
good luck
I think you should stop listenting for updates only when you don't need anymore new locations. If you need only one new location, stop listenting right away is the best approach. For getting more locations(as the user moves) it's recommended to start listen for location updates in onResume and stop listenting in onPause. That means your onLocationChanged will be called only when your activity is in front of all others (is visible).
In conclusion, the activity that manages the window you need should have these calls as specified above.
I developing an app which tracks a user via GPS and reminds them if they cross a toll bridge.
I obviously need the GPS location listener to run in a service and I'll also need a partial-wakelock so it can run occasionaly when the phone is asleep.
I also want the GPS updates to vary in frequency depending on the distance from the toll bridge to save battery.
The cwac- WakefulIntent service seems ideal for what I'm trying to achieve.
However, there are a couple of problems I can see me having before I head down this route (if you pardon the pun ;-).
Does the WakefulIntent service exit and release the wakelock once doWakefulWork() completes even if I'm waiting for my locationlistener to return some GPS updates.
How can I prevent doWakefulWork for returning until I get a location update and cleanup my listener.
What happens if I'm still waiting for a GPS update when alarm manager starts the service again, i.e. before doWakefulWork() has completed?
How can I persist data between instanciations of the service. Can I stuff an array of GPS co-ords into SharedPrefs?
Finally, as I get closer to a toll bridge I need more GPS frequent updates. Do I manage that within doWakefulWork() or by altering scheduleAlarms() so that it uses setRepeating() with a number of minutes stored in SharedPrefs by the service. The idea here is to throttle GPS usage based on proximity to an area of interest.
While the demo app provides a template to work from, I haven't been able to find any solid examples of WakefulIntentService doing any asynchronous jobs.
The cwac- WakefulIntent service seems ideal for what I'm trying to achieve.
Not really. IntentService is not good for location tracking, because you cannot register a listener. The service will shut down once onHandleIntent() ends.
Personally, I would use addProxmityAlert() on LocationManager, rather than mess with any of this yourself.
Does the WakefulIntent service exit and release the wakelock once doWakefulWork() completes even if I'm waiting for my locationlistener to return some GPS updates.
Yes.
How can I prevent doWakefulWork for returning until I get a location update and cleanup my listener.
You don't. You use something else, such as LocationPoller, or, better yet, addProximityAlert().
What happens if I'm still waiting for a GPS update when alarm manager starts the service again, i.e. before doWakefulWork() has completed?
You ensure that you have appropriate timeout logic in place to prevent this, such as can be found in LocationPoller.
How can I persist data between instanciations of the service. Can I stuff an array of GPS co-ords into SharedPrefs?
Yes, or a database, or a file in a format of your choosing.
Finally, as I get closer to a toll bridge I need more GPS frequent updates. Do I manage that within doWakefulWork() or by altering scheduleAlarms() so that it uses setRepeating() with a number of minutes stored in SharedPrefs by the service.
You would change your alarm schedule.
I haven't been able to find any solid examples of WakefulIntentService doing any asynchronous jobs.
WakefulIntentService is the "asynchronous job". It does not execute other asynchronous jobs.
I have a service (with a wakelock) that must run continuously behind the scenes capturing user Geo Location. The Service implements the LocationListener methods (i.e. onLocationChanged()).
However it takes some time for onLocationChanged() to get invoked by the phone, so in the meantime my service has to do something. I thought of using Thread.sleep(), but will that prevent the phone from invoking onLocationChanged()? Or should I do polling: while(i < 1000,000) {++i;}?
I'm not getting such abundant GPS results using either of those ideas; wondering if anybody can give me a tip on how to accomplish this.
I think you can use wait(), and notify() with synchronize block with LocationListener instance.
search for samples using wait(), notify().
I guess you want to keep the service "alive" while it is waiting for location changed information. That is taken care of by the system and you do not have to add code for that. When location change information becomes available, the onLocationChanged() would be invoked in the context of your service.
I solved the problem by removing WakeLock (waste of battery), doing a 10-second busy wait/Thread Sleep (just in case one blocks the GPS invocation of onLoc()), and using AlarmManager to wake the device from sleep and start the service.
This: gets GPS during sleep AND doesn't drain battery power.
We needed a location service for our app that was available from anyplace.
We used s singletone with Application context for system services and more, and has two basic methods start and stop which listen to location providers and stop listening respectively.
We have getLastLocation method that retrieves the current most updated and accurate location we could find.
We have another method that gives me a headache :-)
Location getLocationWithWait(Class c) which supposed to get a location if available, if not it will return null and will create a Timer for 45 seconds.if the 45 seconds have passed and no location was found then the timer will broadcast to the class given in the parameter a 'no location' broadcast, otherwise if the location callbacks will be called they will cancel the timer and will send 'location found' broadcast to the class in the parameter.
So here are my questions:
i started to think the whole
architecture here is wrong, any
better way to implement a location
service to cater ANY Activity in my
application ?
i used a Timer an not Handler since
the singletone i use is NOT an
activity so i have no Looper an
creating a thread with looper looks
to me just as bad as creating
another Thread for the timer... i
did wanted to use the Activity
instead, but then... if the activity
pauses and resumes i need to keep
track of the timer's remaining time.
the broadcasts may also be of a
problem since if the activty pauses
it will miss the broadcast and then
i need to keep track in my
singletone after several states,
StickyBroadcast may solve it but
that one i can't send to specific
class but to the whole system only.
So finally will it be any advantage to make this class a Service ?(to be honest i thought of maybe one advantage but not much) i want a location service with timeout much like google do in their "My Location" in maps.
10x.
Wouldn't it be better to use a LocationListener, as described in Requesting Location Updates?
You can then use a 'FastFix' in onResume()
Without knowing a bit more about your requirements, it's difficult to make more specific suggestions.
Hope this helps,
Phil Lello