Usługi Google Play i uprawnienia czasu działania

Od wersji Androida 6.0 Marshmallow system używa model uprawnień, który upraszcza instalację aplikacji automatycznych aktualizacji. Uprawnienia są wysyłane w czasie działania, a nie przed instalacja aplikacji. Oprócz tego użytkownicy mogą odmówić przyznania określonych uprawnień. Aby zapewnić użytkownikom tę elastyczność, musisz zadbać o to, aby Twoja aplikacja działała który jest oczekiwany, gdy użytkownik włączy lub wyłączy określone uprawnienie.

Same Usługi Google Play mają uprawnienia w czasie działania, które użytkownicy mogą wybrać odmówić przyznania uprawnień oddzielnie od tych, o które prosi aplikacja aplikacji. Usługi Google Play automatycznie uzyskują wszystkie potrzebne uprawnienia do obsługi swoich interfejsów API. Aplikacja nadal powinna jednak sprawdzać czas działania i wysyłać prośby o jego działanie uprawnień i odpowiednio reagować na błędy, gdy użytkownik odmówiono Usługom Google Play uprawnień wymaganych do korzystania z interfejsu API, którego używa Twoja aplikacja.

Warto radzić sobie z oczekiwaniami użytkownika dotyczącymi ustawiania uprawnień, które może być wymagane w środowisku wykonawczym. Te sprawdzone metody pomogą Ci uniknąć potencjalnych problemów.

Wymagania wstępne

W pliku AndroidManifest.xml musisz zadeklarować uprawnienia. Na przykład:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Wytyczne

Przed wywołaniem interfejsów API sprawdź uprawnienia

Po zadeklarowaniu interfejsów API, których chcesz używać, AndroidManifest.xml, sprawdź, czy masz wymagane uprawnienia. przed wywołaniem interfejsu API. Można to zrobić za pomocą metody checkSelfPermission z ActivityCompat lub ContextCompat.

Jeśli wywołanie zwraca wartość false (fałsz), oznacza to, że uprawnienia nie zostały przyznane i możesz powinien użyć w tym celu dodatku requestPermissions. Odpowiedź na to pytanie to: zwracany w wywołaniu zwrotnym, co zobaczysz w następnym kroku.

Na przykład:

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
    != PackageManager.PERMISSION_GRANTED) {
  // Check Permissions Now
  ActivityCompat.requestPermissions(this,
      new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
      REQUEST_LOCATION);
} else {
  // permission has been granted, continue as usual
  Task<Location> locationResult = LocationServices
      .getFusedLocationProviderClient(this /** Context */)
      .getLastLocation();
}

Wdróż wywołanie zwrotne dotyczące uprawnienia do prośby

Jeśli użytkownik nie przyznał potrzebnych uprawnień aplikacji, komponent Należy wywołać metodę requestPermissions, aby przesłać żądanie użytkownika w celu ich przyznania. Odpowiedź użytkownika jest zapisywana w onRequestPermissionsResult – wywołanie zwrotne. Aplikacja powinna należy go zaimplementować i zawsze sprawdzać zwracane wartości, ponieważ żądanie może być odrzucone lub anulowane. Możesz również poprosić o różne uprawnienia i sprawdzić je na stronie raz – ta przykładowa próbka sprawdza tylko 1 uprawnienie.

public void onRequestPermissionsResult(int requestCode,
                                       String[] permissions,
                                       int[] grantResults) {
    if (requestCode == REQUEST_LOCATION) {
        if(grantResults.length == 1
           && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // We can now safely use the API we requested access to
            Task<Location> locationResult = LocationServices
                .getFusedLocationProviderClient(this /** Context */)
                .getLastLocation();
        } else {
            // Permission was denied or request was cancelled
        }
    }
}

Pokaż uzasadnienie przyznania uprawnień

Jeśli uprawnienia, o które prosi aplikacja, są niezbędne do działania podstawowych funkcji i użytkownik wcześniej odrzucił prośbę o przyznanie uprawnień, aplikacja powinna wyświetli dodatkowe wyjaśnienie, zanim ponownie poprosisz o uprawnienie. Użytkownicy chętniej przyznają uprawnienia, gdy rozumieją, dlaczego warto je przyznać i zapewniają im natychmiastowe korzyści.

W takim przypadku przed wywołaniem requestPermissions wywołaj metodę shouldShowRequestPermissionRationale Jeśli się zwróci true, należy utworzyć interfejs użytkownika, aby wyświetlić dodatkowy kontekst dla uprawnienia.

Twój kod może na przykład wyglądać tak:

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
    != PackageManager.PERMISSION_GRANTED) {
    // Check Permissions Now
    private static final int REQUEST_LOCATION = 2;

    if (ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.ACCESS_FINE_LOCATION)) {
        // Display UI and wait for user interaction
    } else {
        ActivityCompat.requestPermissions(
            this, new String[]{Manifest.permission.LOCATION_FINE},
            ACCESS_FINE_LOCATION);
    }
} else {
    // permission has been granted, continue as usual
    Task<Location> locationResult = LocationServices
        .getFusedLocationProviderClient(this /** Context */)
        .getLastLocation();
}

Obsługa błędów połączeń

Jeśli Twoja aplikacja używa wycofanego GoogleApiClient, podczas wywoływania connect(), Usługi Google Play sprawdzają, czy mają wszystkie niezbędnych uprawnień. connect() kończy się niepowodzeniem, gdy jakiekolwiek grupy uprawnień wymaganych przez usługi Google Play.

Jeśli wywołanie funkcji connect() się nie powiedzie, upewnij się, że aplikacja obsługuje błąd połączenia. Jeśli Usługi Google Play nie ma uprawnień, możesz wywołać funkcję startResolutionForResult() zainicjuj wzorzec przeglądania, aby go rozwiązać.

Na przykład:

@Override
public void onConnectionFailed(ConnectionResult result) {
    if (mResolvingError) {
        // Already attempting to resolve an error.
        return;
    } else if (result.hasResolution()) {
        try {
            mResolvingError = true;
            result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
        } catch (SendIntentException e) {
            // There was an error with the resolution intent. Try again.
            mGoogleApiClient.connect();
        }
    } else {
        // Show dialog using GooglePlayServicesUtil.getErrorDialog()
        showErrorDialog(result.getErrorCode());
        mResolvingError = true;
    }
}

Nowsze wywołania interfejsu API oparte na GoogleApi automatycznie wyświetlają albo klient został utworzony za pomocą powiadomienia Activity lub w obszarze powiadomień (jeśli klient tworzy instancję za pomocą funkcji Context), którą użytkownik może kliknąć, aby uruchomić intencja związana z rozpoznawaniem uprawnień. Połączenia zostaną dodane do kolejki i będą ponawiane, gdy przyznano odpowiednie uprawnienia.