Uploaded image for project: 'Titanium SDK/CLI'
  1. Titanium SDK/CLI
  2. TIMOB-28120

Android: Add Ti.Geolocation.allowsBackgroundLocationUpdates support

    Details

      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() and Ti.Android.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 property. When set true, then the next time you call the Ti.Geolocation.hasLocationPermissions() and Ti.Geolocation.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:

      1. 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.
      2. 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.

        Attachments

          Activity

            People

            • Assignee:
              jquick Joshua Quick
              Reporter:
              jquick Joshua Quick
            • Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:

                Backbone Issue Sync

                • Backbone Issue Sync is enabled for your project, but we do not have any synchronization info for this issue.

                  Git Integration