I asked this question (Why Does Map Marker Lurch Around The Map) yesterday. One thing I noticed today is that for an activity that uses LocationManager, but not a map I get the GPS icon (satalite dish beaming signals up) in the status tray. With the activity that has a map fragment and also uses LocationManager I do not get the GPS icon in the tray. I copied and pasted the location manager code from one activity to the other.
Why would the GPS come on some times and not others?
Greg
It depend on global GPS setting - if it's globally on, using LocationManager in your Activity\Fragment will fire "satellite dish". If GPS is globally switched off - using LocationManager will not fire.
The reason is that GPS is a huge power consumerist, and allowing it to run without clear user decision to switch it on will drain the device battery extremely quickly.
Related
I've searched for many answers, posts and articles about getting sensor data even when the screen was off, and most of them suggested to try and use a PARTIAL_WAKE_LOCK. I read the documentation, and from what I've understood, all it said was needed to do was to call:
val wakeLock: PowerManager.WakeLock =
(getSystemService(Context.POWER_SERVICE) as PowerManager).run {
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::MyWakelockTag").apply {
acquire()
}
}
I did this in the onCreate method of the activity that should trigger the wakelock, and I made sure that when the activity is closed the wakelock is released.
My goal is to let the user turn off the screen while in this activity that has a foreground service:
startService(Intent(this, ForegroundService::class.java))
that picks up data from the linear acceleration sensor. Currently though, the partial wakelock does not seem to do anything. As soon as the screen is turned off, the data from the sensor is stopped (as Android would normally do without a wakelock).
It is important that my foreground service analizes the sensor data continuously (so I don't think sensor batching could work for me), and that the user can turn the screen off (all the code works when the screen is on).
Any ideas on how to make this work?
Edit: The service does not stop when the screen is turned off. All the other tasks that the service has to do are correctly done. And that worked without the PARTIAL_WAKELOCK too. It’s just that Android stops getting sensor updates although I have added the Wakelock. That’s the issue.
I have an operational Android app which reports users location within a background service. I want to integrate a feature which will notify the user when GPS signal has been lost.
Our current implementation to commence location updates is:
mLocationListener = LocationListener(LocationManager.GPS_PROVIDER, gpsDeviceCallback)
if (handlerThread?.isAlive == true) {
handlerThread?.quit()
}
handlerThread = HandlerThread("GpsLocationHandler")
handlerThread!!.start()
mLocationManager?.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE.toFloat(),
mLocationListener, handlerThread!!.looper)
with LOCATION_INTERVAL set to 1000 ms and LOCATION_DISTANCE set to 10m.
We get the expected onLocationChanged callbacks under normal operation. However, I would appreciate advice on how to detect a situation where there is a loss of GPS or handset cannot obtain an adequate GPS signal.
We have implemented a solution where we run a time task and determine if onLocationChanged is called during the timer period. The problem with this solution is that if the user handset is stationary during this time then no onLocationChanged callbacks will happen. So this approach will not work as a means of detecting no\inadequate GPS signal.
The user of onStatusChanged as a method of LocationListener is now deprecated so this is not an option either.
Is there some standard solution to this problem ? Perhaps some method which could be called in the case where no onLocationChanged callbacks happen when our check timer expires to test current GPS status?
Thanks!
you can check the current connected satellites and approximate the accuracy see :https://stackoverflow.com/a/10589949
When the battery on my Android device dies what methods in the Activity and Fragment classes (if any) are called during the "Powering Off" stage of the device?
Also, if a user is currently looking at a screen in my app and they hold the power button and choose switch off, do the events called/not called coincide with when the battery is depleted and shuts down automatically?
OnPause?
OnStop?
OnDestroy?
OnDetach?
Bonus:
Will I have enough time to save a small amount of data to a web server?
To clarify "dies" when the device's battery is 'completely' dead, accepts no more input and a message box/loading screen pops up on the screen stating "Powering Off". Shortly there after the device switches off.
I just need enough time to save a forms state before the phone switches off, I have a strategy to clean the saved data should the phone not switch off, but I want to get as close to the phone switching off as possible (any more than a minute is pointless really).
onDestroy is called on everything when the battery reaches 0.5%
EDIT: There is no specified time that you have to do anything in the shutdown process resulting from low/dead battery, that would be dependent on the specific phone battery and not the system, so you may have enough time to save data to a web server on some phones but not others. Experimentally, I have only been able to write a short line to a file I was already writing to before onDestroy was called and nothing more.
The methods you have mentioned is activity life cycle callback, none of them will be called when battery is low. You need to use a broadcast receiver for this
See this How to detect when the Battery's low : Android?
I am using Google Play Services in my app so that I can make use of the Location features. I have read the docs, but it isn't clear what happens when I am running location updates and I leave the app.
Do location updates still occur in the background? If not, how do I do this?
Do location updates still occur in the background? If not, how do I do this?
What I did for my app was to continue to track the location with a service in the background. In addition, you may want to start and mark the service as Foreground so that user will be shown a notification that you are tracking the phone's location.
Make sure you remove the LocationListener when you leave your app, usually I put it in onPause() method of the Activity, otherwise, it's up to you to handle whether you should do it. Here is the example code:
#Override
protected void onPause() {
locationMananger.removeUpdates(this);
// with "this" is your Activity implementing the LocationListener
super.onPause();
}
Hope this helps.
How do you improve slow GPS signal acquisition on the Android platform?
I'm testing a simple GPS logger based on this open source code, and although it seems to work, it can take up to 10-15 minutes for it to first acquire a signal and start showing GPS coordinates. However, running the Google Maps app on the same device appears to acquire a signal almost instantly (it's even able to detect which direction I'm facing in realtime), while the GPS logger service still says it can't find a signal.
Why is Google Maps so fast at acquiring a GPS signal, while the standard GPS system service takes forever?
The specific code I have that starts the GPS service is:
private void startLoggerService() {
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new MyLocationListener();
lm.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
2000,
1,
locationListener);
}
There are a couple of things you should be aware of and definitely take into consideration when it comes to using positional data:
Don't rely on just the GPS sensor. Although GPS can potentially give you the most accurate result, it is relatively slow and quite the battery hog. In stead, also request location updates from the network provider: LocationManager.NETWORK_PROVIDER. In most cases this will give a result accurate enough to use in your app (most devices I've played with seem to yield a worst case accuracy of roughly 60~65m), but more importantly: it's much, much faster. Do note that just as with the GPS, users can enable and disable feature themselves in the system settings. For more details, see Using the Location Manager.
Think about how often you need a location update. If possible, prevent continuous updates (that'll drain the battery in no-time) and release the sensors as soon as you've received the data you require. Also, a good practice is to cache the location to some extend - even if it's not completely accurate, users do get feedback immediately. You can potentially combine this with some logic that takes the time stamp into account.
Use the resources that are already available on the Android Developer website. For example, there is a topic on Location Strategies that will be worth reading. Another good resource will be the blog post by Reto Meier and his open source project that implements his Android Protips for Location. If you have the time, also go over his Google I/O 2011 presentation that discusses best-practices for location-based/location-aware Android apps.
On a side note: the realtime indication of what direction you're facing has nothing to do with locations, but comes from either the magnetic field sensor (read: digital compass) or gyroscope. Both deal with the device's orientation, not position.
The 1 in your code means that the provider will only broadcast the location should your device move by 1 meter. Try setting this to 0.
The API documentation states:
"The frequency of notification may be controlled using the minTime and minDistance parameters. If minTime is greater than 0, the LocationManager could potentially rest for minTime milliseconds between location updates to conserve power. If minDistance is greater than 0, a location will only be broadcasted if the device moves by minDistance meters. To obtain notifications as frequently as possible, set both parameters to 0."
If google maps is showing your direction, it must be using a GPS fix. Google maps must be using the most recent gps fix which you can get using Location.getLastKnownLocation. Presumably if that location is not too old Google maps decides it is way better than nothing and shows it to you while you wait for new GPS fixes.
GPS fixes will often come really slowly or not at all when you are indoors. I assume as you develop you are trying to get GPS fixes? You may have to get up and walk outside.
Many phones have fairly lousy gps receivers. Even in clear outdoor sky I own phones which will take MANY minutes to get the first GPS fix. It sucks and its a rip-off, but its true.