Uprawnienia na platformie Xamarin.Android

Omówienie

Aplikacje systemu Android działają we własnej piaskownicy i ze względów bezpieczeństwa nie mają dostępu do niektórych zasobów systemowych ani sprzętu na urządzeniu. Użytkownik musi jawnie udzielić uprawnień aplikacji, zanim będzie mógł korzystać z tych zasobów. Na przykład aplikacja nie może uzyskać dostępu do GPS na urządzeniu bez jawnego uprawnienia użytkownika. System Android zrzuci Java.Lang.SecurityException wyjątek , jeśli aplikacja spróbuje uzyskać dostęp do chronionego zasobu bez uprawnień.

Uprawnienia są deklarowane wAndroidManifest.xml przez dewelopera aplikacji podczas jej opracowań. System Android ma dwa różne przepływy pracy w celu uzyskania zgody użytkownika na te uprawnienia:

  • W przypadku aplikacji, które były ukierunkowane na system Android 5.1 (poziom interfejsu API 22) lub niższy, żądanie uprawnień wystąpiło podczas instalacji aplikacji. Jeśli użytkownik nie przyznał uprawnień, aplikacja nie zostałaby zainstalowana. Po zainstalowaniu aplikacji nie ma możliwości odwołania uprawnień z wyjątkiem odinstalowania aplikacji.
  • Począwszy od systemu Android 6.0 (poziom interfejsu API 23), użytkownicy mieli większą kontrolę nad uprawnieniami; mogą udzielić lub odwołać uprawnień, o ile aplikacja jest zainstalowana na urządzeniu. Ten zrzut ekranu przedstawia ustawienia uprawnień dla aplikacji Kontakty Google. Wyświetla listę różnych uprawnień i umożliwia użytkownikowi włączanie lub wyłączanie uprawnień:

Ekran Przykładowe uprawnienia.

Aplikacje systemu Android muszą sprawdzać w czasie rzeczywistym, czy mają uprawnienia dostępu do chronionego zasobu. Jeśli aplikacja nie ma uprawnień, musi wykonać żądania przy użyciu nowych interfejsów API dostarczonych przez Android SDK, aby użytkownik przyznał uprawnienia. Uprawnienia są podzielone na dwie kategorie:

  • Normalne uprawnienia – Są to uprawnienia, które stanowią niewielkie zagrożenie dla bezpieczeństwa lub prywatności użytkownika. System Android 6.0 automatycznie udzieli normalnych uprawnień w czasie instalacji. Zapoznaj się z dokumentacją systemu Android, aby uzyskać pełną listę normalnych uprawnień.
  • Niebezpieczne uprawnienia – W przeciwieństwie do normalnych uprawnień niebezpieczne uprawnienia to te, które chronią bezpieczeństwo lub prywatność użytkownika. Muszą one zostać jawnie przyznane przez użytkownika. Wysyłanie lub odbieranie wiadomości SMS jest przykładem akcji wymagającej niebezpiecznego uprawnienia.

Ważne

Kategoria, do której należy uprawnienie, może z czasem ulec zmianie. Istnieje możliwość, że uprawnienie, które zostało skategoryzowane jako "normalne", może zostać podwyższone w przyszłych poziomach interfejsu API do niebezpiecznego uprawnienia.

Niebezpieczne uprawnienia są dodatkowo podzielone na grupy uprawnień. Grupa uprawnień będzie przechowywać uprawnienia, które są logicznie powiązane. Gdy użytkownik udziela uprawnień jedneowi członkowskiowi grupy uprawnień, system Android automatycznie udziela uprawnień wszystkim członkom tej grupy. Na przykład grupa STORAGE uprawnień zawiera zarówno uprawnienia , jak i WRITE_EXTERNAL_STORAGE READ_EXTERNAL_STORAGE . Jeśli użytkownik udziela uprawnień do , uprawnienie jest przyznawane automatycznie READ_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE w tym samym czasie.

Przed zażądaniem co najmniej jednego uprawnienia najlepszym rozwiązaniem jest uzasadnienie tego, dlaczego aplikacja wymaga uprawnień przed żądaniem uprawnień. Gdy użytkownik zrozumie uzasadnienie, aplikacja może zażądać uprawnień od użytkownika. Po zrozumieniu zasad użytkownik może podjąć świadomą decyzję, jeśli chce udzielić uprawnień, i zrozumieć konsekwencje, jeśli tego nie zrobią.

Cały przepływ pracy sprawdzania i żądania uprawnień jest nazywany sprawdzaniem uprawnień w czasie wykonywania i można go podsumować na poniższym diagramie:

Wykres blokowy sprawdzania uprawnień w czasie rzeczywistym.

Biblioteka pomocy technicznej systemu Android zaimportuje niektóre nowe interfejsy API w celu uprawnień do starszych wersji systemu Android. Te przyniesiene do tyłu interfejsy API będą automatycznie sprawdzać wersję systemu Android na urządzeniu, więc nie trzeba za każdym razem sprawdzać poziomu interfejsu API.

W tym dokumencie omówiono sposób dodawania uprawnień do aplikacji platformy Xamarin.Android oraz sposób, w jaki aplikacje dla systemu Android 6.0 (poziom interfejsu API 23) lub wyższego powinny wykonywać sprawdzanie uprawnień w czasie wykonywania.

Uwaga

Istnieje możliwość, że uprawnienia do sprzętu mogą mieć wpływ na sposób filtrowania aplikacji według Google Play. Jeśli na przykład aplikacja wymaga uprawnień do aparatu, Google Play nie będzie wyświetlać aplikacji na ekranie Sklep Google Play na urządzeniu, na których nie zainstalowano aparatu fotograficznego.

Wymagania

Zdecydowanie zaleca się, aby projekty Xamarin.Android zawierały pakiet Xamarin.Android.Support.Compat NuGet pakiet. Ten pakiet zaimportuje interfejsy API specyficzne dla uprawnień do starszych wersji systemu Android, zapewniając jeden wspólny interfejs bez konieczności ciągłego sprawdzania wersji systemu Android, na których działa aplikacja.

Żądanie uprawnień systemowych

Pierwszym krokiem podczas pracy z uprawnieniami systemu Android jest zadeklarowanie uprawnień w pliku manifestu systemu Android. Należy to zrobić niezależnie od poziomu interfejsu API, na który jest ukierunkowana aplikacja.

Aplikacje dla systemu Android w wersji 6.0 lub wyższej nie mogą zakładać, że ponieważ użytkownik przyznał uprawnienia w pewnym momencie w przeszłości, uprawnienie będzie prawidłowe następnym razem. Aplikacja dla systemu Android 6.0 musi zawsze sprawdzać uprawnienia środowiska uruchomieniowego. Aplikacje dla systemu Android w wersji 5.1 lub niższej nie muszą wykonywać sprawdzania uprawnień w czasie wykonywania.

Uwaga

Aplikacje powinny żądać tylko wymaganych uprawnień.

Deklarowanie uprawnień w manifeście

Uprawnienia są dodawane do AndroidManifest.xml z uses-permission elementem . Jeśli na przykład aplikacja ma zlokalizować pozycję urządzenia, wymaga to uprawnień i uprawnień do lokalizacji kursu. Do manifestu dodawane są następujące dwa elementy:

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

Istnieje możliwość zadeklarowania uprawnień przy użyciu obsługi narzędzi wbudowanych w Visual Studio:

  1. Kliknij dwukrotnie pozycję Właściwości w Eksplorator rozwiązań i wybierz kartę Manifest systemu Android w okno Właściwości:

    Wymagane uprawnienia na karcie Manifest systemu Android.

  2. Jeśli aplikacja nie ma jeszcze AndroidManifest.xml, kliknij pozycję Nie AndroidManifest.xml znaleziono. Kliknij, aby dodać jeden z nich, jak pokazano poniżej:

    Brak AndroidManifest.xml komunikatu.

  3. Wybierz wszystkie uprawnienia wymagane przez aplikację z listy Wymagane uprawnienia i zapisz:

    Wybrane przykładowe uprawnienia APARATU.

Xamarin.Android automatycznie doda niektóre uprawnienia w czasie kompilacji do debugowania kompilacji. Ułatwi to debugowanie aplikacji. W szczególności istnieją dwa niesłychane INTERNET uprawnienia: i READ_EXTERNAL_STORAGE . Te automatycznie ustawione uprawnienia nie będą widoczne na liście Wymagane uprawnienia. Kompilacje wydania używają jednak tylko uprawnień, które są jawnie ustawione na liście Wymagane uprawnienia.

W przypadku aplikacji dla systemu Android 5.1 (poziom interfejsu API 22) lub niższego nie trzeba nic więcej robić. Aplikacje, które będą działać w systemie Android 6.0 (interfejs API 23 poziom 23) lub wyższym, powinny przejść do następnej sekcji dotyczącej sposobu przeprowadzania kontroli uprawnień w czasie wykonywania.

Sprawdzanie uprawnień środowiska uruchomieniowego w systemie Android 6.0

Metoda (dostępna z biblioteką pomocy technicznej systemu Android) służy do sprawdzania, czy udzielono ContextCompat.CheckSelfPermission określonego uprawnienia. Ta metoda zwróci Android.Content.PM.Permission wylicie, które ma jedną z dwóch wartości:

  • Permission.Granted–Określone uprawnienie zostało przyznane.
  • Permission.Denied–Określone uprawnienie nie zostało przyznane.

Ten fragment kodu to przykład sposobu sprawdzania uprawnień aparatu w działaniu:

if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) == (int)Permission.Granted) 
{
    // We have permission, go ahead and use the camera.
} 
else 
{
    // Camera permission is not granted. If necessary display rationale & request.
}

Najlepszym rozwiązaniem jest poinformowanie użytkownika o tym, dlaczego uprawnienie jest niezbędne dla aplikacji, aby można było podjąć świadomą decyzję o udzieleniu uprawnienia. Przykładem może być aplikacja, która robi zdjęcia i tagami geograficznymi. Dla użytkownika jest jasne, że uprawnienia aparatu są niezbędne, ale może nie być jasne, dlaczego aplikacja również potrzebuje lokalizacji urządzenia. Uzasadnienie powinno pomóc użytkownikowi zrozumieć, dlaczego uprawnienie do lokalizacji jest pożądane i że wymagane jest uprawnienie aparatu.

Metoda ActivityCompat.ShouldShowRequestPermissionRationale służy do określania, czy uzasadnienie powinno być widoczne dla użytkownika. Ta metoda zwróci, jeśli powinna zostać wyświetlona uzasadnienie true danego uprawnienia. Na tym zrzucie ekranu przedstawiono przykład paska z wytłaniakiem wyświetlanym przez aplikację, który wyjaśnia, dlaczego aplikacja musi znać lokalizację urządzenia:

Uzasadnienie lokalizacji.

Jeśli użytkownik udziela uprawnień, ActivityCompat.RequestPermissions(Activity activity, string[] permissions, int requestCode) metoda powinna zostać wywołana. Ta metoda wymaga następujących parametrów:

  • działanie – Jest to działanie, które żąda uprawnień i ma zostać powiadomione przez system Android o wynikach.
  • uprawnienia – Lista żądanych uprawnień.
  • requestCode – Wartość całkowita, która jest używana do dopasowania wyników żądania uprawnień do RequestPermissions wywołania. Ta wartość powinna być większa od zera.

Ten fragment kodu jest przykładem dwóch metod, które zostały omówione. Najpierw należy sprawdzić, czy należy określić, czy należy określić uzasadnienie uprawnień. Jeśli uzasadnienie ma zostać przedstawione, zostanie wyświetlony pasek z uzasadnieniem. Jeśli użytkownik kliknie przycisk OK na pasku Nawiązce, aplikacja zażąda uprawnień. Jeśli użytkownik nie zaakceptuje uzasadnienie, aplikacja nie powinna kontynuować żądania uprawnień. Jeśli uzasadnienie nie jest wyświetlane, działanie zażąda uprawnienia:

if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.AccessFineLocation)) 
{
    // Provide an additional rationale to the user if the permission was not granted
    // and the user would benefit from additional context for the use of the permission.
    // For example if the user has previously denied the permission.
    Log.Info(TAG, "Displaying camera permission rationale to provide additional context.");

    var requiredPermissions = new String[] { Manifest.Permission.AccessFineLocation };
    Snackbar.Make(layout, 
                   Resource.String.permission_location_rationale,
                   Snackbar.LengthIndefinite)
            .SetAction(Resource.String.ok, 
                       new Action<View>(delegate(View obj) {
                           ActivityCompat.RequestPermissions(this, requiredPermissions, REQUEST_LOCATION);
                       }    
            )
    ).Show();
}
else 
{
    ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.Camera }, REQUEST_LOCATION);
}

RequestPermission Można ją nazwać, nawet jeśli użytkownik przyznał już uprawnienia. Kolejne wywołania nie są konieczne, ale zapewniają użytkownikowi możliwość potwierdzenia (lub odwołania) uprawnienia. Po wywołaniu sterowanie jest odbierane do systemu operacyjnego, który wyświetla interfejs użytkownika RequestPermission do akceptowania uprawnień:

Okno dialogowe permssion (Permssion).

Po zakończeniu pracy użytkownika system Android zwróci wyniki do działania za pośrednictwem metody wywołania zwrotnego OnRequestPermissionResult . Ta metoda jest częścią interfejsu, ActivityCompat.IOnRequestPermissionsResultCallback który musi zostać zaimplementowany przez działanie. Ten interfejs ma jedną metodę , która zostanie wywołana przez system Android w celu poinformowania działania o OnRequestPermissionsResult wyborach użytkownika. Jeśli użytkownik przyznał uprawnienia, aplikacja może dalej korzystać z chronionego zasobu. Poniżej przedstawiono przykład OnRequestPermissionResult implementacji:

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
    if (requestCode == REQUEST_LOCATION) 
    {
        // Received permission result for camera permission.
        Log.Info(TAG, "Received response for Location permission request.");

        // Check if the only required permission has been granted
        if ((grantResults.Length == 1) && (grantResults[0] == Permission.Granted)) {
            // Location permission has been granted, okay to retrieve the location of the device.
            Log.Info(TAG, "Location permission has now been granted.");
            Snackbar.Make(layout, Resource.String.permission_available_camera, Snackbar.LengthShort).Show();            
        } 
        else 
        {
            Log.Info(TAG, "Location permission was NOT granted.");
            Snackbar.Make(layout, Resource.String.permissions_not_granted, Snackbar.LengthShort).Show();
        }
    } 
    else 
    {
        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

Podsumowanie

W tym przewodniku omówiono sposób dodawania i sprawdzania uprawnień na urządzeniu z systemem Android. Różnice dotyczące sposobu działania uprawnień między starymi aplikacjami systemu Android (poziom interfejsu API < 23) i nowymi aplikacjami systemu Android (poziom interfejsu API > 22). Omówiono w nim sposób sprawdzania uprawnień w czasie wykonywania w systemie Android 6.0.