Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-28120] Android: Add Ti.Geolocation.allowsBackgroundLocationUpdates support

GitHub Issuen/a
TypeImprovement
PriorityLow
StatusOpen
ResolutionUnresolved
Affected Version/sn/a
Fix Version/sn/a
ComponentsAndroid
Labelsandroid, background, geolocation, parity, permission
ReporterJoshua Quick
AssigneeJoshua Quick
Created2020-09-10T05:28:12.000+0000
Updated2021-02-22T19:01:03.000+0000

Description

*Summary:* We currently already support location data collection in the background, but you have to request the end-user for "android.permission.ACCESS_BACKGROUND_LOCATION" on Android 10 and above or else it'll stop reporting data. This can only be done via the [Ti.Android.hasPermission()](https://docs.appcelerator.com/platform/latest/#!/api/Titanium.Android-method-hasPermission) and [Ti.Android.requestPermissions()](https://docs.appcelerator.com/platform/latest/#!/api/Titanium.Android-method-requestPermissions) methods, which makes it more difficult to write cross-platform code between Android and iOS. *Current Solution:* This is how you would request background permission today on Android 10 and above.
const ACCESS_COARSE_LOCATION = 'android.permission.ACCESS_COARSE_LOCATION';
const ACCESS_FINE_LOCATION = 'android.permission.ACCESS_FINE_LOCATION';
const ACCESS_BACKGROUND_LOCATION = 'android.permission.ACCESS_BACKGROUND_LOCATION';
const permissionArray = [ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION];
if (Ti.Platform.Android.API_LEVEL >= 29) {
	permissionArray.push('android.permission.ACCESS_BACKGROUND_LOCATION');
}
if (!Ti.Android.hasPermission(permissionArray)) {
	Ti.Android.requestPermissions(permissionArray, (e) => {
		// Android 11 allows you to deny background permission and grant other location permissions separately.
		// Event object's "success" property will be false in this case. So, we must check individual permissions.
		if (!Ti.Android.hasPermission([ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION])) {
			alert('Location permission denied.');
		} else if ((Ti.Platform.Android.API_LEVEL >= 29) && !Ti.Android.hasPermission(ACCESS_BACKGROUND_LOCATION)) {
			alert('Background location access denied.');
		} else {
			Ti.Geolocation.addEventListener('location', onLocationDataReceived);
		}
	});
} else {
	Ti.Geolocation.addEventListener('location', onLocationDataReceived);
}
*Better Solution:* Add support for the [Ti.Geolocation.allowsBackgroundLocationUpdates](https://docs.appcelerator.com/platform/latest/#!/api/Titanium.Geolocation-property-allowsBackgroundLocationUpdates) property. When set true, then the next time you call the [Ti.Geolocation.hasLocationPermissions()](https://docs.appcelerator.com/platform/latest/#!/api/Titanium.Geolocation-method-hasLocationPermissions) and [Ti.Geolocation.requestLocationPermissions()](https://docs.appcelerator.com/platform/latest/#!/api/Titanium.Geolocation-method-requestLocationPermissions) methods, they will automatically add the "android.permission.ACCESS_BACKGROUND_LOCATION" permission to the check/request for you, making the code much more portable.
Ti.Geolocation.allowsBackgroundLocationUpdates = true;
if (!Ti.Geolocation.hasLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE)) {
	Ti.Geolocation.requestLocationPermissions(Ti.Geolocation.AUTHORIZATION_WHEN_IN_USE, () => {
		if (e.success) {
			Ti.Geolocation.addEventListener('location', onLocationDataReceived);
		}
	});
} else {
	Ti.Geolocation.addEventListener('location', onLocationDataReceived);
}
*Notes:*

You will still need to start an Android foreground service set up for FOREGROUND_SERVICE_TYPE_LOCATION to make this work. There is no way to make this cross-platform since it involves posting a notification to the status bar.

On iOS, the "allowsBackgroundLocationUpdates" property only applies the first time you add your "location" event... versus on Android it only applies when doing the location permission checks.

Comments

No comments

JSON Source