Skip to content
This repository has been archived by the owner on Apr 23, 2023. It is now read-only.

LocationServices.SettingsApi seems to be broken #140

Closed
westnordost opened this issue Nov 26, 2016 · 3 comments
Closed

LocationServices.SettingsApi seems to be broken #140

westnordost opened this issue Nov 26, 2016 · 3 comments
Assignees

Comments

@westnordost
Copy link
Contributor

westnordost commented Nov 26, 2016

Description

The location settings api seems to be broken or at least does not work as documented nor as documented for the Google Play Api (since it should mirror the behavior).
Following points:

  1. If the location settings are already on and checkLocationSettings is called, the status code returned is Status.SETTINGS_CHANGE_UNAVAILABLE instead of Status.SUCCESS
  2. If the location settings are off and the user is led to the settings activity to turn on the location via status.startResolutionForResult, it seems to be unachievable to return to this activity via onActivityResult with result code Activity.RESULT_OK (see reproduction below)
  3. If the location settings are off, the Google Maps app shows a dialog "To continue, let your device turn on location using Google's location service." in which the user can directly turn it on without being led to the settings activity. I am just assuming here that this is done with the Google Play Apis, I never used them before so the assumption could be wrong and this point invalid then. In LOST, calling status.startResolutionForResult leads the user directly to the settings, without asking first. Since LOST should mirror Google Play Apis, the expectation is that this call works the same.

Steps to Reproduce

Have the below code in your activity. Then,...

  • turn location off, start the activity. The app will log "The location settings are off, let's ask the user to turn them on!" and immediately show the location settings activity. However, the user is not led back to your activity after he turned it on. If he goes back manually (by pressing back), this is interpreted as Activity.RESULT_CANCELED and "Oh no, user did not turn location on!" is logged. It seems to be unachievable to get a Activity.RESULT_OK
  • turn location on, start the activity. The app will log "Oh no, cannot change location settings!", even though they are already on. The status should have been Status.SUCCESS but is Status.SETTINGS_CHANGE_UNAVAILABLE
private static final int REQUEST_CHECK_SETTINGS = 1;

private LostApiClient lostApiClient;

@Override public void onStart()
{
	super.onStart();
	lostApiClient = new LostApiClient.Builder(this).build();
	lostApiClient.connect();
	requestLocationSettingsToBeOn();
}

@Override public void onStop()
{
	super.onStop();
	lostApiClient.disconnect();
}

private void requestLocationSettingsToBeOn()
{
	LocationRequest locationRequest = LocationRequest.create().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
	PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(
			lostApiClient, new LocationSettingsRequest.Builder().addLocationRequest(locationRequest).build());
	result.setResultCallback(new ResultCallback<LocationSettingsResult>()
	{
		@Override public void onResult(@NonNull LocationSettingsResult result)
		{
			final Status status = result.getStatus();
			switch (status.getStatusCode())
			{
				case Status.SUCCESS:
					Log.i("LOST","Location settings are on, continue!");
					break;
				case Status.RESOLUTION_REQUIRED:
					Log.i("LOST","The location settings are off, let's ask the user to turn them on!");
					status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
					break;
				case Status.SETTINGS_CHANGE_UNAVAILABLE:
					Log.i("LOST","Oh no, cannot change location settings!");
					break;
			}
		}
	});
}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
	super.onActivityResult(requestCode, resultCode, data);
	switch (requestCode)
	{
		case REQUEST_CHECK_SETTINGS:
			switch (resultCode) {
				case Activity.RESULT_OK:
					Log.i("LOST","Hooray, user turned location on!");
					break;
				case Activity.RESULT_CANCELED:
					Log.i("LOST","Oh no, user did not turn location on!");
					break;
			}
			break;
	}
}

Lost & Android Version

2.1.1 on Android 6

@sarahsnow1
Copy link
Contributor

Thank you for your detailed report.

  1. What is logged from this code snipped when you run it from a demo activity on your device?
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
PackageManager packageManager = getPackageManager();
boolean gpsUsable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean gpsPresent = packageManager.hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS);
boolean networkUsable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
boolean networkPresent =
          packageManager.hasSystemFeature(PackageManager.FEATURE_LOCATION_NETWORK);
boolean blePresent = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
Log.d("LOST", "gpsUsable:"+gpsUsable + " gpsPresent:" + gpsPresent + " networkUsable:" +
          networkUsable + " networkPresent:" + networkPresent + " blePresent:" + blePresent);
  1. Unfortunately we cannot return back to the activity with result code Activity.RESULT_OK because we are limited by the system apis (which do not return this information). In the meantime, you should instead check that the request code matches your app's code when onActivityResult is called. We will update our documentation to make this more clear. We could potentially add an intermediate activity of our own to handle receiving this callback from the system and then send the proper result code to the calling activity however we will need to think more about this.

  2. Nice catch, we've got an open PR to add a dialog before sending the user to settings: Display alert to optionally fire location settings activity #150

@westnordost
Copy link
Contributor Author

westnordost commented Dec 13, 2016

I tested the issue with an Android 6 emulator actually. Anyhow, the output of 1. is:
gpsUsable:true gpsPresent:false networkUsable:true networkPresent:true blePresent:false
When I turn off location, it is
gpsUsable:false gpsPresent:false networkUsable:false networkPresent:true blePresent:false

  1. & 3.: Cool, looking forward to it :-)

@westnordost
Copy link
Contributor Author

Very cool! Thank you for your efforts, @sarahlensing and @ecgreb

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants