cordova-plugin-background-geolocation
cordova-plugin-background-geolocation copied to clipboard
Android location access: User cannot choose "Allow all the time"
First I want to thank you for providing this plugin!
Environment
Android API level 29
Context
When the user is asked how the device is allowed to access the location, no option "Allow all the time" is shown.
Expected Behavior
The following location access options should be shown to the user:
- Allow all the time
- Allow only while using the app
- Deny & don't ask again
Actual Behavior
The following location access options are currently shown to the user:
- Allow only while using the app
- Deny
- Deny & don't ask again
Possible Fix
Update array PERMISSIONS inside file BackgroundGeolocationFacade.java
public static final String[] PERMISSIONS = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION
};
Also see Android docs. "If your app targets Android 10 or higher, you must declare the ACCESS_BACKGROUND_LOCATION permission ...".
Steps to Reproduce
Use plugin with Android API level 29 and check location access dialog.
Yes, that appears to be the fix. See:
https://stackoverflow.com/questions/61909313/allow-all-the-time-location-prompt-not-coming-in-android-sdk-29
The possible correction of speckro in combination with the comment of spinninghamster solved the problem for us. However, it only worked for Android 10. Android <= 9 also requested permission, but can no longer start the background process. EDIT: After applying the fix of speckro the backgroundgeolocation plugin throws following after giving permissions on Android 9: I/com.marianhello.bgloc.BackgroundGeolocationFacade: User denied requested permissions I think the plugin now checks for the ACCESS_BACKGROUND_LOCATION although it is not present on Android 9.
The possible correction of speckro in combination with the comment of spinninghamster solved the problem for us. However, it only worked for Android 10. Android <= 9 also requested permission, but can no longer start the background process. EDIT: After applying the fix of speckro the backgroundgeolocation plugin throws following after giving permissions on Android 9: I/com.marianhello.bgloc.BackgroundGeolocationFacade: User denied requested permissions I think the plugin now checks for the ACCESS_BACKGROUND_LOCATION although it is not present on Android 9.
What if you target API level 28 instead of 29?
The problem remained the same. However we were able to resolve the issue by adding following lines inside of BackgroundGeolocationFacade.java :
public static final String[] PERMISSIONS10 = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION
};
private String[] PERMISSIONSNEW = PERMISSIONS;
... and by changing the public void start() function in the same file to :
public void start() {
if(android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
PERMISSIONSNEW = PERMISSIONS;
}else {
PERMISSIONSNEW = PERMISSIONS10;
}
logger.debug("Starting service");
PermissionManager permissionManager = PermissionManager.getInstance(getContext());
permissionManager.checkPermissions(Arrays.asList(PERMISSIONSNEW), new PermissionManager.PermissionRequestListener() {
@Override
public void onPermissionGranted() {
logger.info("User granted requested permissions");
// watch location mode changes
registerLocationModeChangeReceiver();
registerServiceBroadcast();
startBackgroundService();
}
@Override
public void onPermissionDenied() {
logger.info("User denied requested permissions");
if (mDelegate != null) {
mDelegate.onAuthorizationChanged(BackgroundGeolocationFacade.AUTHORIZATION_DENIED);
}
}
});
}
We also added following in the AndroidManifest.xml file:
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Hi guys,
thanks for that fix !
But now I have the notification "Background Tracking ENABLED" which is always there, like https://github.com/mauron85/cordova-plugin-background-geolocation/issues/699
Do you know how to clear it ?
Hi Guys,
thanks too. It also fixed it for me.
@dabaaaz If I "swipe" my app (close complete). My notification disappears (if stopOnTerminate: true).
Cheers
There's also the service type that this docs describe:
https://developer.android.com/training/location/permissions
Have any of you implemented the type=location thing?
@DominikMair do you have a fork with your fix by any chance? Also API level 29 is now required for new apps so this fix is mandatory I guess...
Sent a PR, I hope it will be merged... https://github.com/mauron85/background-geolocation-android/pull/58
@DominikMair thanks for your fix. Work as I expected
@OstapBO @DominikMair does this code still working fine ? I mean, does the app a wake up when the user is walking/driving ?!
After deeply looking into this subject and looking for info I found this great lecture:
https://www.youtube.com/watch?v=L7zwfTwrDEs&feature=youtu.be
I'm using the plugin in service foreground mode so I basically don't really need the allow all the time.
Having said that, I probably need the location type to one of the services.
I'm guessing that this is the relevant service:
<service android:enabled="true" android:exported="false" android:name="com.marianhello.bgloc.service.LocationServiceImpl"/>
I still don't have most of the answers as this still requires testing...
Reading the plugin info, and Android description for permissions (https://developer.android.com/training/location/permissions?hl=fr) i think no need background persimission. Android said: When de app is in background, but one services is running, and one notification is showing you need Foreground location permissions only...
This is only in the case where you set forgroundService: true in the settings - this way the app is not considered as running in the background per say...
The lecture I linked is great in order to understand the differences between background and foreground.
@chacabuk: You are right. When your app enters the background and you start a foreground service with a notification, your app is considered to be in the foreground and you don't need permission ACCESS_BACKGROUND_LOCATION. An exception is when you use the geofence service. Then you need permission ACCESS_BACKGROUND_LOCATION as noted here.
@HarelM can you extend your comment? how and where do you set "forgroundService: true"? I'm not using geofence service, but in Android 10 only work if set ACCESS_BACKGROUND_LOCATION permissions...
Part of the configuration API is this flag - where you define the provider, interval, distance etc. Let me know if you can't find it and I'll send you a link to my project...
@HarelM But there no one property with the name "forgroundService".. Thanks a lot!!
My mistake, the name of the property is: startForeground - set it to true to use foreground service. Read about it in the repo's readme file.
@HarelM, Thanks for your time. I assumed you speak to another property. I was try this (and a lot of other thiks) and there are no way... On Android 10 only work if set ACCESS_BACKGROUND_LOCATION permission... You can add this permission on config file, or you can omit this and tell each user to allow this manualy.
My source code is realy simple:
import { Component } from '@angular/core';
import { Platform } from '@ionic/angular';
import {
BackgroundGeolocation,
BackgroundGeolocationEvents,
BackgroundGeolocationLocationProvider
} from '@ionic-native/background-geolocation/ngx';
import { HTTP } from '@ionic-native/http/ngx'; // ionic cordova plugin add cordova-plugin-advanced-http
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent {
url = 'https://xxxxxx';
token = 'xxxxxxxxxx';
constructor(
private platform: Platform,
private http: HTTP,
private backgroundGeolocation: BackgroundGeolocation,
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.backgroundGeolocation.configure({
startForeground: true,
locationProvider: BackgroundGeolocationLocationProvider.RAW_PROVIDER,
desiredAccuracy: 10,
stationaryRadius: 0,
distanceFilter: 0,
interval: 60000,
notificationTitle: 'app Work.',
notificationText: '',
debug: false,
stopOnTerminate: true
});
this.backgroundGeolocation.on(BackgroundGeolocationEvents.location).subscribe((location) => {
this.backgroundGeolocation.startTask().then(taskKey => {
this.http.post(this.url, location, { Authorization: this.token }).then(() => {
this.backgroundGeolocation.endTask(taskKey);
})
});
});
});
}
}
Two comments:
- The plugging already has the ability to send location to the server, no need to re-implement this (I'm not using it, but it's there I believe)
- I forked the plugin to add an attribute to the service to mark it as a foreground location service. I forgot I did it and so I don't need the background permission... I'm using my fork which is in my github repos... My bad...
@HarelM Ohhh!!! I see!. I knew I was not crazy. Ok, you talk about the line 161 in plugin.xml ? https://github.com/mauron85/cordova-plugin-background-geolocation/compare/master...HarelM:master I can modify that file manually, but I use Ionic's Appflow to build and deploy ... so I will use the original one ...
The link doesn't work, but yes: android:foregroundServiceType="location"
You can use my fork instead of this repo, I'm not planning on changing it soon and this repo is pretty abandoned so I don't expect it to split much from this code base...
hello ;it's still not working for me ,
I have android 10 device system
Someone can help me about the foreground service ( what shall i put ?)