I have developed a Android hybrid app that amongst other activities tracks the users location and displays it to the user showing where they have been recently. This works by invoking LocationServices.FusedLocationApi.requestLocationUpdates at a 10 second update rate.
Obviously this requires location permission and for ANDROID Marshmallow and above I check and request the necessary location privileges from the user before requesting location updates.
I have read many other StackOverflow question about the same topic but I have not found a satisfactory answer about preventing Android from terminating the app if location permission is revoked for the app by the user after initially granting it.
I would be more than happy for the app to stop displaying the user's location and track, after all the user has asked for it to be stopped, but I am far less happy for the app to be terminated, as I said earlier the app does many other things for the user whilst running in the background.
As far as I understand there is no callback that can be used to allow me to remove the location updates as soon as the location permission is revoked. How could I change my strategy to avoid the app crashing?
It is not that I am expecting users to do this very often, but I think it good practice to make the app as bulletproof as possible. Please do not remind me that Android can terminate any app in the background as that is not my question here.
Do I need to adopt a singular rather than a periodic approach to requesting the location so that I can re-check the permission exists each time.
Or is it better to try and catch the error. If so where do I do this? Would it be inside onLocationChanged?
What I mean by app crash is that the process is terminated (I have checked and this actually happens)
That's perfectly normal, when the user revokes a runtime permission.
What I would like to do is prevent the process terminating if there is any way I can do this.
Sorry, that is not possible.
Since I suspect that few users even know that they can revoke runtime permissions, this is not going to be a common occurrence, IMHO.
Blockquote
however why did the Android developers not just cause a callback to be generated to allow the app code base to react
You could register for the LocationManager.PROVIDERS_CHANGED_ACTION in the BroadcastReceiver.
When it is hit, you can check if the provider is still enabled and use that accordingly to prevent your app from crashing when someone revokes the location permission.
LocationManager locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
boolean enabled = locationManager != null && locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
Related
I have written a foreground service in my app and I am doing some API operation every 5 minutes once. My app is mainly used for location tracking and it always needs location permission. If user disable the location for my app by any chance then I just want to create a local notification from my service. My app users mostly don't bring my app to foreground. So I want to check whether the location permission is enabled or not. If not then I just want to show a notification which tells the user that the app needs location permission. Now I just manually went to android settings and disabled the location permission for my app. I have two services running in my app. Suddenly both stopped working. I just want to know the reason why it stopped? Will it be stopped always until I enable the permission? What can I do to intimate my user to enable the permission? As my app always runs in background, I want to handle it in service. Please give your opinion to solve my issue.
NullPointerException: Attempt to read from field'LanguageInitBean$Data LanguageInitBean.data' on a null object reference
When I change the storage permission, I can't read the data stored in memory
Ask for help
public static class LanguageInitCache{
public static LanguageInitBean languageInitBean;
}
private void startToNext(String response) {
languageInitBean = GsonUtils.json2Bean(response, LanguageInitBean.class);
}
I have a similar issue to this post How to make my Android app comply with the "Background Location Policy" but that post doesn't have an answer.
I have a web browser app, which on occasion will ask for location permissions if the user visits a website that requests that. App targets API 29. The app manifest has <uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" /> which is API 23 and higher because I didn't want to force location permission on older phones.
Today I got an email saying I have until March to fix this, but I don't understand what I have to do, I'm not requesting background location anywhere.
Anyone have any idea what I have to do?
Edit: I have read the help center, and I'm wondering if that my issue is the ACCESS_FINE_LOCATION, maybe something is accessing it on the background. I don't know how I would prevent ad networks from that if they do it. I already pause the WebViews the app is not on the foreground so websites should not be using it.
Edit2: Is there maybe a way I can log background location access so that I can monitor my app a few days to see if it happens?
I would like to answer my own question in case someone else is searching for this. I can't say that I know for certain this is correct but it has worked for me so far.
First, on this answer https://stackoverflow.com/a/65894488/704836 I was told to use AppOpsManager to log background location requests. After doing that I found a few places where that takes places. I will discuss those below:
Ad networks. I have ad network initialization on my Application.onCreate() and a lot of those accessed location. So when triggering a BroadcastReceiver, they would check location.
WifiManager.getConnectionInfo() - this will trigger a location request. Same deal as above, I had one of those on Application.onCreate().
After removing those calls the Play store stopped complaining.
I am verifying my location service compatibility with Android Q but I am a little unsure how my app is going to react since in my testing I have seen not difference when granting Background permission vs Only while app is running.
Coming off this statement from the Q migration documentation
An app is considered to be in the background unless one of its
activities is visible or the app is running a foreground service.
Since the location service is a foreground service does the difference in permission even matter in this case?
Well it's a bit of a tricky question.
When running location foreground service on Q you need "while app running" permission + to declare in the manifest this foreground service is of type location. Your app has no need of the background permission.
If your app do asks for background permission, the user can get suspicious and reject any location permission :( So it is not recommended to ask the user for permissions you don't need.
highly recommend to watch this video from the google IO: Updating Your Apps for Location Permission Changes in Android Q (Google I/O'19)
You can read more about t here: documantation
And you can see googles example project on GitHub for location updates on Q with foreground service here :LocationUpdatesForegroundService
You just need run foreground service instead of background. Otherwise your app will crash during background services start when there is no activity on the foreground
Using Xamarin Android, I need to be able to access location updates from within a service.
I have tried the native Android.LocationManager, Plugin.Geolocator, and Xamarin.Essentials.Geolocation, but none of them seem to provide location updates.
If I do it inside an activity, it works fine, but I have a requirement to post location updates from a service which launches at boot time.
Yeah, I know it's a "privacy violation" or whatever, but the app is only used on company devices for a specific internal use.
I saw somewhere that requesting permissions from a service "is tricky," so I know it's possible, but the guy didn't elaborate on how to do it.
I have an App that listens to android.location.PROVIDERS_CHANGED broadcast to stay aware of the phone's current location capabilities.
With Android M and the new App-runtime permissions, it works normally when the location is changed from the system/general panel. But if a user disables the location permission specifically for the App, the same broadcast is not fired.
So far I can test for location access with a regular AlarmManager, but it's quite odd and not very responsive.
Is there any other specific method, ideally a kind of BroadcastReceiver to register that keeps us informed of this location app-permission-change with Android M?
Sorry, but you are not directly notified about permission changes, for locations or other permissions, unless there's some undocumented hack that I'm not aware of.
If the user revokes a permission, your app's process will be terminated. The idea is that you will find out about the revoked permission when your app runs again and you call checkSelfPermission(). That flow is optimized for more conventional cases, where the permission checks are being conducted in an activity opened by the user. It doesn't handle your case very well (though, IMHO, location permissions shouldn't affect the broadcast as you describe).
In the N Developer Preview, you can now set up JobScheduler to monitor a Uri for changes and trigger your job as needed. This is a bit like registering a ContentObserver, except that you don't need the process running all the time — JobScheduler registers the observer and just invokes your JobService as needed. I think that the roster of enabled location sources is found in the Settings provider somewhere; if so, for Android 6.1/7.0/Turbo System 5000/whatever N turns into, you might be able to use JobScheduler to find out about the location source changes, instead of relying on the broadcast.
That doesn't help you for Android 6.0, though. You can use JobScheduler or AlarmManager or something to see if you lost the permission (via checkSelfPermission()), but that's kinda wasteful of battery life (and, as a result, will not work well given Doze mode and possibly app standby).