Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android location service availability improvement for work profile #1183

Closed
1 of 2 tasks
vlazdra opened this issue Dec 15, 2022 · 0 comments
Closed
1 of 2 tasks

Android location service availability improvement for work profile #1183

vlazdra opened this issue Dec 15, 2022 · 0 comments

Comments

@vlazdra
Copy link
Contributor

vlazdra commented Dec 15, 2022

🏗 Enhancement Proposal

The problem I came across has to do with the location service availability check not working correctly when the app is installed via work profile on an Android device.
The reason being is that the code never actually resolves that scenario correctly, it's missing an else statement for the check.

I've managed to make it work, per say, but I think it can be improved even further by enabling the plugin to actually popup the dialog for enabling the location service.

Pitch

Not sure about the contributors part, but will improve the quality of the plugin, and will patch one issue at leat.

Platforms affected (mark all that apply)

  • 📱 iOS
  • 🤖 Android

Proposal 1 - Adding the else statement

Right now, if the app is installed via the work profile on the device, the isLocationServiceEnabled is not going to work, if the location service is not turned on for the work profile part.

  @Override
  public void isLocationServiceEnabled(LocationServiceListener listener) {
    LocationServices.getSettingsClient(context)
        .checkLocationSettings(new LocationSettingsRequest.Builder().build())
        .addOnCompleteListener(
            (response) -> {
              if (response.isSuccessful()) {
                LocationSettingsResponse lsr = response.getResult();
                if (lsr != null) {
                  LocationSettingsStates settingsStates = lsr.getLocationSettingsStates();
                  boolean isGpsUsable = settingsStates != null && settingsStates.isGpsUsable();
                  boolean isNetworkUsable =
                      settingsStates != null && settingsStates.isNetworkLocationUsable();
                  listener.onLocationServiceResult(isGpsUsable || isNetworkUsable);
                } else {
                  listener.onLocationServiceError(ErrorCodes.locationServicesDisabled);
                }
              }
            });
  }

It's missing the else statement here, because a call towards the checkLocationSettings is resulting in an unsuccessful call.
So by just adding the else statement, you can cover the use case where the app is installed via work profile and the service is not enabled, like so:

if (response.isSuccessful()) {
   // ...
} else {
    listener.onLocationServiceError(ErrorCodes.locationServicesDisabled);
}

Proposal 2 - Asking the user to enable location

There is a way to ask the user to enable the location, it applies for either the work profile or the regular personal profile.
In order to ask the user to enable the location service for the specific profile, you would need call startResolutionForResult((Activity) context, 123);

Now with this call, the entire request would look something like this:

 @Override
    public void isLocationServiceEnabled(LocationServiceListener listener) {
        LocationServices.getSettingsClient(context)
                .checkLocationSettings(new LocationSettingsRequest.Builder().build())
                .addOnCompleteListener(
                        (response) -> {
                            if (response.isSuccessful()) {
                               // ...
                            } else {
                                if (response.getException() instanceof ResolvableApiException) {
                                    final ResolvableApiException exception = (ResolvableApiException) response.getException();

                                    switch (exception.getStatusCode()) {
                                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                            // Location settings are not satisfied. But could be fixed by showing the
                                            // user a dialog.
                                            try {
                                                // Cast to a resolvable exception.
                                                // Show the dialog by calling startResolutionForResult(),
                                                // and check the result in onActivityResult().
                                                exception.startResolutionForResult((Activity) context, 123123);
                                                listener.onLocationServiceError(ErrorCodes.error0);
                                            } catch (IntentSender.SendIntentException e) {
                                                // Ignore the error.
                                                listener.onLocationServiceError(ErrorCodes.error1);
                                            } catch (ClassCastException e) {
                                                // Ignore, should be an impossible error.
                                                listener.onLocationServiceError(ErrorCodes.error2);
                                            }
                                            break;
                                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                            // Location settings are not satisfied. However, we have no way to fix the
                                            // settings so we won't show the dialog.
                                            listener.onLocationServiceError(ErrorCodes.error3);
                                            break;
                                    }
                                }
                            }
                        });
    }

Source of the code example above is from Google Play Services - Settings Client docs
The example above would trigger a popup that would ask the user to turn on the service.
It will look something like this:
Location popup

Now there is a catch with this one, it depends on the onActivityResult, where it actually reports the result of the request if the user allowed or disallowed the location service. And in order for it to work, the end developer would need to implement it in their MainActivity (I'm not aware that a plugin can register that kind of a callback).

It took me some time to investigate this one fully (I might have missed something), to better understand why the location check was failing if the app was installed via the work profile where the location was turned off. And I'm still digesting all of the things I uncover, so if you have any questions, please feel free to ask, I will do my best to answer them if I can.

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

No branches or pull requests

1 participant