Xamarin.Essentials: Berechtigungen

Die Permissions-Klasse bietet die Möglichkeit, Laufzeitberechtigungen zu prüfen und anzufordern.

Erste Schritte

Lesen Sie zum Einstieg in die Verwendung dieser API den Leitfaden mit ersten Schritte für Xamarin.Essentials, um sicherzustellen, dass die Bibliothek ordnungsgemäß installiert und in Ihren Projekten eingerichtet ist.

Diese API verwendet Laufzeitberechtigungen unter Android. Stellen Sie sicher, dass Xamarin.Essentials vollständig initialisiert und die Verarbeitung von Berechtigungen in Ihrer App eingerichtet ist.

Im MainLauncher-Element des Android-Projekts bzw. in einem beliebigen Activity-Element, das gestartet wird, muss Xamarin.Essentials in der OnCreate-Methode initialisiert werden:

protected override void OnCreate(Bundle savedInstanceState) 
{
    //...
    base.OnCreate(savedInstanceState);
    Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
    //...
}    

Um Laufzeitberechtigungen unter Android zu verwalten, muss Xamarin.Essentials ein beliebiges OnRequestPermissionsResult-Element erhalten. Fügen Sie allen Activity-Klassen den folgenden Code hinzu:

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
    Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

    base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

Verwenden von Berechtigungen

Fügen Sie in Ihrer Klasse einen Verweis auf Xamarin.Essentials hinzu:

using Xamarin.Essentials;

Überprüfen von Berechtigungen

Um den aktuellen Status einer Berechtigung zu prüfen, verwenden Sie die CheckStatusAsync-Methode zusammen mit der jeweiligen Berechtigung, um den Status abzurufen.

var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();

Eine PermissionException wird ausgelöst, wenn die erforderliche Berechtigung nicht deklariert ist.

Sie sollten den Status der Berechtigung vor der Anforderung zu überprüfen. Jedes Betriebssystem gibt einen anderen Standardstatus zurück, wenn dem Benutzer noch keine Eingabeaufforderung angezeigt wurde. iOS gibt Unknown zurück, während andere Denied zurückgeben. Wenn der Status Granted lautet, müssen keine weiteren Aufrufe durchgeführt werden. Wenn der Status unter iOS Denied lautet, sollten Sie den Benutzer auffordern, die Berechtigung in den Einstellungen zu ändern. Unter Android können Sie ShouldShowRationale aufrufen, um zu ermitteln, ob der Benutzer die Berechtigung in der Vergangenheit bereits verweigert hat.

Anfordern von Berechtigungen

Um eine Berechtigung von den Benutzern anzufordern, verwenden Sie die RequestAsync-Methode zusammen mit der spezifischen anzufordernden Berechtigung. Wenn der Benutzer zuvor eine Berechtigung erteilt und diese nicht widerrufen hat, gibt diese Methode sofort Granted zurück, ohne ein Dialogfeld einzublenden.

var status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();

Eine PermissionException wird ausgelöst, wenn die erforderliche Berechtigung nicht deklariert ist.

Beachten Sie, dass auf einigen Plattformen eine Berechtigungsanforderung nur einmalig aktiviert werden kann. Weitere Aufforderungen müssen vom Entwickler behandelt werden, um zu prüfen, ob sich eine Berechtigung den Status Denied hat, und den Benutzer aufzufordern, sie manuell zu aktivieren.

Berechtigungsstatus

Bei Verwenden von CheckStatusAsync oder RequestAsync wird ein PermissionStatus zurückgegeben, der zur Festlegung der nächsten Schritte verwendet werden kann:

  • Unbekannt: Die Berechtigung hat einen unbekannten Status.
  • Verweigert: Der Benutzer hat die Berechtigungsanforderung verweigert.
  • Deaktiviert: Das Feature ist auf dem Gerät deaktiviert.
  • Erteilt: Der Benutzer hat die Berechtigung erteilt, oder sie wird automatisch erteilt.
  • Eingeschränkt: eingeschränkter Status.

Erläutern der Gründe für eine Berechtigung

Eine bewährte Methode besteht darin zu erläutern, warum Ihre Anwendung eine bestimmte Berechtigung benötigt. Unter iOS müssen Sie eine Zeichenfolge angeben, die dem Benutzer angezeigt wird. Android bietet diese Möglichkeit nicht, außerdem lautet der Standardstatus von Berechtigungen „Deaktiviert“. Dadurch ist es nicht möglich zu erkennen, ob der Benutzer die Berechtigung verweigert hat oder ob er zum ersten Mal eine Aufforderung erhält. Mithilfe der ShouldShowRationale-Methode können Sie bestimmen, ob auf der Benutzeroberfläche Hinweise angezeigt werden sollen. Wenn die Methode true zurückgibt, hat der Benutzer die Berechtigung in der Vergangenheit bereits verweigert oder deaktiviert. Auf anderen Plattformen wird bei einem Aufruf dieser Methode immer false zurückgegeben.

Verfügbare Berechtigungen

Xamarin.Essentials versucht, so viele Berechtigungen wie möglich zu abstrahieren. Jedoch hat jedes Betriebssystem eine andere Gruppe von Laufzeitberechtigungen. Darüber hinaus gibt es Unterschiede, wenn eine einzelne API für einige Berechtigungen bereitgestellt wird. Es folgt eine Übersicht über die derzeit verfügbaren Berechtigungen:

Symbole und ihre Bedeutung:

  • Full Support – Unterstützt
  • Not Supported – Nicht unterstützt/erforderlich
Berechtigung Android iOS UWP watchOS tvOS Tizen
CalendarRead Android supported iOS supported UWP not supported watchOS supported tvOS not supported Tizen not supported
CalendarWrite Android supported iOS supported UWP not supported watchOS supported tvOS not supported Tizen not supported
Kamera Android supported iOS supported UWP not supported watchOS not supported tvOS not supported Tizen supported
ContactsRead Android supported iOS supported UWP supported watchOS not supported tvOS not supported Tizen not supported
ContactsWrite Android supported iOS supported UWP supported watchOS not supported tvOS not supported Tizen not supported
Taschenlampe Android supported iOS not supported UWP not supported watchOS not supported tvOS not supported Tizen supported
LocationWhenInUse Android supported iOS supported UWP supported watchOS supported tvOS supported Tizen supported
LocationAlways Android supported iOS supported UWP supported watchOS supported tvOS not supported Tizen supported
Medien Android not supported iOS supported UWP not supported watchOS not supported tvOS not supported Tizen not supported
Mikrofon Android supported iOS supported UWP supported watchOS not supported tvOS not supported Tizen supported
Telefonnummer Android supported iOS supported UWP not supported watchOS not supported tvOS not supported Tizen not supported
Fotos Android not supported iOS supported UWP not supported watchOS not supported tvOS supported Tizen not supported
Mahnungen Android not supported iOS supported UWP not supported watchOS supported tvOS not supported Tizen not supported
Sensoren Android supported iOS supported UWP supported watchOS supported tvOS not supported Tizen not supported
SMS Android supported iOS supported UWP not supported watchOS not supported tvOS not supported Tizen not supported
Speech Android supported iOS supported UWP not supported watchOS not supported tvOS not supported Tizen not supported
StorageRead Android supported iOS not supported UWP not supported watchOS not supported tvOS not supported Tizen not supported
StorageWrite Android supported iOS not supported UWP not supported watchOS not supported tvOS not supported Tizen not supported

Wenn eine Berechtigung als not supported markiert ist, wird bei einer Anforderung oder Überprüfung immer Granted zurückgegeben.

Allgemeine Verwendung

Der folgende Code stellt das allgemeine Verwendungsmuster dar, mit dem ermittelt wird, ob eine Berechtigung erteilt wurde, und stellt eine Anforderung, wenn dies nicht der Fall ist. In diesem Code werden Features verwendet, die mit Xamarin.Essentials Version 1.6.0 oder höher verfügbar sind.

public async Task<PermissionStatus> CheckAndRequestLocationPermission()
{
    var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
    
    if (status == PermissionStatus.Granted)
        return status;        
    
    if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
    {
        // Prompt the user to turn on in settings
        // On iOS once a permission has been denied it may not be requested again from the application
        return status;
    }
    
    if (Permissions.ShouldShowRationale<Permissions.LocationWhenInUse>())
    {
        // Prompt the user with additional information as to why the permission is needed
    }   

    status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();

    return status;
}

Von jedem Berechtigungstyp kann eine Instanz so erstellt werden, dass die die Methoden direkt aufgerufen werden können.

public async Task GetLocationAsync()
{
    var status = await CheckAndRequestPermissionAsync(new Permissions.LocationWhenInUse());
    if (status != PermissionStatus.Granted)
    {
        // Notify user permission was denied
        return;
    }

    var location = await Geolocation.GetLocationAsync();
}

public async Task<PermissionStatus> CheckAndRequestPermissionAsync<T>(T permission)
            where T : BasePermission
{
    var status = await permission.CheckStatusAsync();
    if (status != PermissionStatus.Granted)
    {
        status = await permission.RequestAsync();
    }

    return status;
}

Erweitern von Berechtigungen

Die Permissions-API wurde mit Blick auf Flexibilität und Erweiterbarkeit für Anwendungen entwickelt, die eine zusätzliche Überprüfung oder Berechtigungen erfordern, die nicht in Xamarin.Essentials enthalten sind. Erstellen Sie eine neue Klasse, die von BasePermission erbt, und implementieren Sie die erforderlichen abstrakten Methoden.

public class MyPermission : BasePermission
{
    // This method checks if current status of the permission
    public override Task<PermissionStatus> CheckStatusAsync()
    {
        throw new System.NotImplementedException();
    }

    // This method is optional and a PermissionException is often thrown if a permission is not declared
    public override void EnsureDeclared()
    {
        throw new System.NotImplementedException();
    }

    // Requests the user to accept or deny a permission
    public override Task<PermissionStatus> RequestAsync()
    {
        throw new System.NotImplementedException();
    }
}

Bei Implementierung einer Berechtigung auf einer bestimmten Plattform kann die BasePlatformPermission-Klasse von dieser geerbt werden. Dies ermöglicht zusätzliche Plattformhilfsmethoden zur automatischen Überprüfung der Deklarationen. Dies kann beim Erstellen benutzerdefinierter Berechtigungen zum Vornehmen von Gruppierungen hilfreich sein. Beispielsweise können Sie mit der folgenden benutzerdefinierten Berechtigung Lese- und Schreibzugriff auf Speicher unter Android anfordern.

public class ReadWriteStoragePermission : Xamarin.Essentials.Permissions.BasePlatformPermission
{
    public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
    {
        (Android.Manifest.Permission.ReadExternalStorage, true),
        (Android.Manifest.Permission.WriteExternalStorage, true)
    }.ToArray();
}

Anschließend können Sie Ihre neue Berechtigung über das Android-Projekt aufrufen.

await Permissions.RequestAsync<ReadWriteStoragePermission>();

Wenn Sie diese API über Ihren freigegebenen Code aufrufen möchten, könnten Sie eine Schnittstelle erstellen und einen Abhängigkeitsdienst verwenden, um die Implementierung zu registrieren und abzurufen.

public interface IReadWritePermission
{        
    Task<PermissionStatus> CheckStatusAsync();
    Task<PermissionStatus> RequestAsync();
}

Implementieren Sie die Schnittstelle dann in Ihrem Plattformprojekt:

public class ReadWriteStoragePermission : Xamarin.Essentials.Permissions.BasePlatformPermission, IReadWritePermission
{
    public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
    {
        (Android.Manifest.Permission.ReadExternalStorage, true),
        (Android.Manifest.Permission.WriteExternalStorage, true)
    }.ToArray();
}

Anschließend können Sie die spezifische Implementierung registrieren:

DependencyService.Register<IReadWritePermission, ReadWriteStoragePermission>();

Dann können Sie diese über Ihr freigegebenes Projekt auflösen und verwenden:

var readWritePermission = DependencyService.Get<IReadWritePermission>();
var status = await readWritePermission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
    status = await readWritePermission.RequestAsync();
}

Besonderheiten bei der plattformspezifischen Implementierung

Die Berechtigungen müssen in der Android-Manifestdatei über die entsprechenden Attribute verfügen. Der Standardberechtigungsstatus ist „Verweigert“.

Weitere Informationen finden Sie in der Dokumentation zu Berechtigungen in Xamarin.Android.

API

Auf Channel 9 und auf YouTube finden Sie weitere Videos zu Xamarin.