onGpsStatusChanged alternatives? - android

Posted question recently about why my onGpsStatusChanged is called only once and not called anymore, got no answers so will assume solution is unknown (been trying it out for 2 days), so is there perhaps any alternative solution to detect if GPS signal was lost and no location updates are available?
I am running LocationListener in background service.
I need to detect when user lost GPS -> Start alarmManager for 5 minutes and if GPS appears online again -> cancel alarm.
The only problem I have detecting if gps was lost or not.

Loosing GPS just means that you will receive no more location updates.
So why not just setting the Alarm again with each location update you receive.
The set-Methods of the AlarmManager are automatically cancelling Alarms previously set with the same PendingIntent. So you will have only one Alarm set all the time. As soon as no new location is received for longer than 5 minutes your Alarm will be executed.
May be setting the Alarm again every second is too expensive (I have no idea about that). In this case, add a counter, that resets the AlarmManager only every n-th location update. The idea is still the same.

Related

Initiate periodic location updates using FusedLocationProviderApi or use AlarmManager instead

I'm developing an app that checks the weather based on the current location every 3 hours. I'm getting the location using the FusedLocationProviderApi and using a pendingIntent to a BroadCastReceiver that start up an IntentService.
In the FusedLocationProviderApi you can specify an interval period when you are creating the LocationRequest. So if I specify the interval to be 3 hours and the fastest interval as well to be 3 hours (I don't want to get updates before that), what happens if location is not available when it's time to do a location update?
Will I still get the location update intent at the scheduled time? I would like to use the last known location if the location is not available, but I need to be certain that I am still getting the PendingIntent at the scheduled time.
Or is it better to use an alarm manager to handle the periodic work and request the location update from within the IntentService instead?
Thanks
In the FusedLocationProviderApi you can specify an interval period when you are creating the LocationRequest. So if I specify the interval to be 3 hours and the fastest interval as well to be 3 hours (I don't want to get updates before that), what happens if location is not available when it's time to do a location update?
In this scnerio device must be awake to keep alive your location request. So it means you must have a non-stop(theoretically) background service, and partial wake lock as well. They sound not good.
Instead, you could refer AlarmManager approach which is set to wake up at each 3 hours. Then idea works like below
Device wakes up
Makes location request asap (set interval values to zero)
Continues to sleep after receiving location (and also doing your actual work)

Getting user location practice in service

I am once again facing a problem. I am having a alarmManager set up to start a Service which gets user's location every minute. My question is, is this the best practice? To recreate the service every minute, make and register new Location listener and wait for one OnLocationChanged callback ? Or is there a simpler, prettier way of doing it ? Also, don't forged, the screen will be turned off and the device asleep so I need to work with WakeLock too
You can simple start the service once, get a wake lock, and then poll for the location with a time interval of 60 seconds. This will remove the need to recreate the service every time. However, it will be possible for your service to be killed by Android if necessary. You can have it restarted automatically by returning START_STICKY in onStartCommand().
As a general rule, getting a location every minute is going to be very battery intensive, and should be avoided, especially for long periods of time.

Android LocationListener leave on while phone asleep

I set an alarm with the flag RTC_WAKEUP to run a IntentService every 30 seconds to transmit location updates to a server. I'm planning to change the flag to RTC so it won't wake up the phone and just run when another process wake ups the phone. If I leave a LocationListener registered, will it still listen for location updates while the phone is asleep?
Yes - working location service has it's own wake lock. However better approach is manually set proper wake lock in your broadcast receiver. Please consider some optimization - sending data over network every 30s will drain battery.
You have multiple problems here.
I set an alarm with the flag RTC_WAKEUP to run a IntentService every 30 seconds to transmit location updates to a server.
First, you may not even get your first fix within 30 seconds, particularly if you are using GPS. You need to take into account that you may never get a fix (e.g., the user is in an underground location).
Second, please allow this figure to be user-configurable, including an option for "I'll upload the data manually please". As #piotrpo indicates, this is a significant drain on the battery. In fact, if you're using GPS, I doubt the battery will last more than a couple of hours.
Third, an IntentService will not work well in this case, because the IntentService will shut down before your fix arrives. At best, you'll leak memory. At worst, you won't get your fix, because Android terminates your process.
A better solution for doing background location checks is to use a regular Service, not an IntentService. The regular Service would register the LocationListener in onStartCommand(), plus arrange for a timeout notification (e.g., AlarmManager and set()) in case a fix is not available. When the fix arrives, run an AsyncTask to do your upload. When the AsyncTask completes, or if the timeout arrives and you did not get a fix, unregister the listener and call stopSelf() to shut down the service. Along the way, you will need to maintain your own WakeLock, to keep the device awake while all of this is going on.
For an example of most of this (minus the server upload part), see my LocationPoller.
If you are dead-set on this occurring every 30 seconds or so, you may as well not bother with AlarmManager at all. You would have to have an everlasting service, running all the time, with a permanent WakeLock and a permanent LocationListener. When fixes arrive in onLocationChanged(), upload them if they are more than 30 seconds from the previous one. And, be sure to wear a flame-retardant suit when you release the app, as those who run it may not like the results much.

Android service with locationListener callbacks

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.

Question about getting current location in Android

I have few questions about getting current location of the device.
I believe only way to do that is using requestLocationUpdates(....).
if I subscribe to requestLocationUpdates... with duration set to 1 hour and after 1 hour if my phone is sleeping (or during that 1 hour I rebooted my phone), does the listener still work?
A. If yes - After 1 hour, when I get update about location, I want to change duration to 2 hours. Is there a way to do that? If not, can I call removeUpdates, and immediately call requestLocationUpdates with duration as 2 hours?
B. If No - I was planning to set an alarm to go off after 1 hour, and call removeUpdates & requestLocationUpdates in the alarm receiver. Is that right strategy.
I'm not 100% sure but If you reboot your phone service isn't started again, also as is written in a manual:
minTime - the minimum time interval for notifications, in milliseconds. This field is only used as a hint to conserve power, and actual time between location updates may be greater or lesser than this value.
This is only a hint for update time but it's not reliable.
Your practice should be to make a Service which should use Handler and postDelayed to set timed action within a runnable. I hope I helped.

Categories

Resources