Od Androida 6.0 Marshmallow system ten korzysta z modelu uprawnień, który upraszcza proces instalacji aplikacji i automatycznej aktualizacji. Uprawnienia są wymagane w czasie działania aplikacji, a nie przed jej instalacją. Użytkownicy mogą też odrzucić konkretne uprawnienia. Aby zapewnić użytkownikom taką elastyczność, musisz zadbać o to, aby aplikacja działała zgodnie z oczekiwaniami, gdy użytkownik włącza lub wyłącza określone uprawnienie.
Usługi Google Play mają własne uprawnienia w czasie działania, które użytkownicy mogą odrzucić niezależnie od uprawnień wymaganych przez Twoją aplikację. Usługi Google Play automatycznie uzyskują wszystkie uprawnienia potrzebne do obsługi interfejsów API. Aplikacja powinna jednak w razie potrzeby sprawdzać uprawnienia w czasie działania i o nie prosić oraz odpowiednio obsługiwać błędy w przypadkach, gdy użytkownik odmówi usługom Google Play uprawnienia wymaganego przez interfejs API używany przez aplikację.
Warto zarządzać oczekiwaniami użytkownika podczas ustawiania uprawnień, których może wymagać środowisko wykonawcze. Te sprawdzone metody pomogą Ci uniknąć potencjalnych problemów.
Wymagania wstępne
Uprawnienia musisz zadeklarować w pliku AndroidManifest.xml
.
Na przykład:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Wytyczne
Sprawdzanie uprawnień przed wywołaniem interfejsów API
Po zadeklarowaniu interfejsów API, których chcesz używać w pliku AndroidManifest.xml
, przed wywołaniem interfejsu API sprawdź, czy masz wymagane uprawnienia. Możesz to zrobić za pomocą metody checkSelfPermission
w przypadku ActivityCompat
lub ContextCompat
.
Jeśli wywołanie zwraca wartość false, oznacza to, że uprawnienia nie zostały przyznane i należy użyć funkcji requestPermissions
, aby o nie poprosić. Odpowiedź na to żądanie jest zwracana w wywołaniu zwrotnym, które zobaczysz w następnym kroku.
Na przykład:
Kotlin
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Request Permissions Now ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_LOCATION_PERMISSION_CODE) } else { // permission has been granted, continue as usual val locationResult = LocationServices .getFusedLocationProviderClient(this /* Context */) .lastLocation }
Java
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Request Permissions Now ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION_CODE); } else { // permission has been granted, continue as usual TasklocationResult = LocationServices .getFusedLocationProviderClient(this /** Context */) .getLastLocation(); }
Zaimplementuj wywołanie zwrotne prośby o uprawnienia
Jeśli użytkownik nie przyznał uprawnień, których potrzebuje Twoja aplikacja, należy wywołać metodę
requestPermissions
, aby poprosić użytkownika o ich przyznanie. Odpowiedź użytkownika jest rejestrowana w wywołaniu zwrotnym onRequestPermissionsResult
. Aplikacja powinna to zaimplementować i zawsze sprawdzać zwracane wartości, ponieważ żądanie może zostać odrzucone lub anulowane. Możesz też poprosić o kilka uprawnień naraz i sprawdzić, czy zostały przyznane. Poniższy przykład sprawdza tylko jedno uprawnienie.
Kotlin
fun onRequestPermissionsResult( requestCode: Int, permissions: Array, grantResults: IntArray ) { if (requestCode == REQUEST_LOCATION_PERMISSION_CODE) { if (grantResults.singleOrNull() == PackageManager.PERMISSION_GRANTED) { // We can now safely use the API we requested access to val locationResult: Task = LocationServices .getFusedLocationProviderClient(this /* Context */) .lastLocation // Request the last known location. } else { // Permission was denied or request was cancelled } } }
Java
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == REQUEST_LOCATION_PERMISSION_CODE) { if(grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // We can now safely use the API we requested access to TasklocationResult = LocationServices .getFusedLocationProviderClient(this /** Context */) .getLastLocation(); // Request the last known location. } else { // Permission was denied or request was cancelled } } }
Wyświetlanie uzasadnienia uprawnień
Jeśli uprawnienia, o które prosi aplikacja, są niezbędne do działania jej podstawowych funkcji, a użytkownik wcześniej odrzucił prośbę o przyznanie uprawnień, przed ponownym wysłaniem prośby aplikacja powinna wyświetlić dodatkowe wyjaśnienie. Użytkownicy chętniej przyznają uprawnienia, gdy rozumieją, dlaczego są one potrzebne i jakie korzyści z nich wynikają.
W takim przypadku przed wywołaniem funkcji requestPermissions
należy wywołać funkcję shouldShowRequestPermissionRationale
. Jeśli zwróci wartość „true”, musisz utworzyć interfejs, który będzie wyświetlać dodatkowy kontekst uprawnień.
Twój kod może na przykład wyglądać tak:
Kotlin
private const val REQUEST_LOCATION_PERMISSION_CODE = 2 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Check Permissions Now if ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.ACCESS_FINE_LOCATION ) { // Display UI and wait for user interaction } else { ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_LOCATION_PERMISSION_CODE) } } else { // Permission has already been granted, continue as usual val locationResult: Task= LocationServices .getFusedLocationProviderClient(this /* Context */) .lastLocation }
Java
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Check Permissions Now private static final int REQUEST_LOCATION_PERMISSION_CODE = 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}, REQUEST_LOCATION_PERMISSION_CODE); } } else { // permission has been granted, continue as usual TasklocationResult = LocationServices .getFusedLocationProviderClient(this /** Context */) .getLastLocation(); }
Wywołania interfejsu API Usług Google Play będą automatycznie wyświetlać okno (jeśli klient jest tworzony za pomocą Activity
) lub powiadomienie na pasku systemowym (jeśli klient jest tworzony za pomocą Context
), które użytkownik może kliknąć, aby uruchomić intencję rozwiązania problemu z uprawnieniami. Po przyznaniu uprawnień połączenia zostaną umieszczone w kolejce i ponowione.