アクセス許可

Browse sample. サンプルを表示する

この記事では、.NET Multi-platform App UI (.NET MAUI) Permissions クラスを使用する方法について説明します。 このクラスを使用すると、実行時にアクセス許可を確認して要求できます。 Permissions 型は Microsoft.Maui.ApplicationModel 名前空間で使用できます。

使用可能なアクセス許可:

.NET MAUI では、可能な限り多くのアクセス許可を抽象化しようとします。 しかし、オペレーティング システムごとに、アクセス許可のセットは異なります。 API で共通のアクセス許可へのアクセスが許可されている場合でも、そのアクセス許可に関連するオペレーティング システム間に違いがある可能性があります。 次の表では、使用可能なアクセス許可について説明します。

以下の表では、✔️ はアクセス許可がサポートされていることを示し、❌ はアクセス許可がサポートされていない、または必要ないことを示します。

アクセス許可 Android iOS Windows tvOS
バッテリー ✔️
CalendarRead ✔️ ✔️
CalendarWrite ✔️ ✔️
カメラ ✔️ ✔️
ContactsRead ✔️ ✔️
ContactsWrite ✔️ ✔️
懐中電灯 ✔️
LocationWhenInUse ✔️ ✔️ ✔️
LocationAlways ✔️ ✔️
Media ✔️
マイク ✔️ ✔️
NetworkState ✔️
電話 ✔️ ✔️
Photos ✔️ ✔️
PhotosAddOnly ✔️ ✔️
アラーム ✔️
センサー ✔️ ✔️
SMS ✔️ ✔️
Speech ✔️ ✔️
StorageRead ✔️
StorageWrite ✔️
バイブレーション ✔️
アクセス許可 Android iOS Windows tvOS
バッテリー ✔️
Bluetooth ✔️
CalendarRead ✔️ ✔️
CalendarWrite ✔️ ✔️
カメラ ✔️ ✔️
ContactsRead ✔️ ✔️
ContactsWrite ✔️ ✔️
懐中電灯 ✔️
LocationWhenInUse ✔️ ✔️ ✔️
LocationAlways ✔️ ✔️
Media ✔️
マイク ✔️ ✔️
NearbyWifiDevices ✔️
NetworkState ✔️
電話 ✔️ ✔️
Photos ✔️ ✔️
PhotosAddOnly ✔️ ✔️
アラーム ✔️
センサー ✔️ ✔️
SMS ✔️ ✔️
Speech ✔️ ✔️
StorageRead ✔️
StorageWrite ✔️
バイブレーション ✔️

アクセス許可に ❌ マークが付いている場合は、確認または要求されたときに毎回 Granted が返されます。

アクセス許可の確認

アクセス許可の現在の状態を確認するには、状態を取得する特定のアクセス許可を指定して Permissions.CheckStatusAsync メソッドを使用します。 次の例では、LocationWhenInUse アクセス許可の状態をチェックします。

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

必要なアクセス許可が宣言されていない場合は、PermissionException がスローされます。

アクセス許可を要求する前に、状態を確認することをお勧めします。 ユーザーにメッセージが表示されない場合は、オペレーティング システムごとに異なる既定の状態を返します。 iOS は Unknown を返し、その他は Denied を返します。 状態が Granted の場合は、他の呼び出しを行う必要はありません。 iOS では、状態が Denied の場合、設定のアクセス許可を変更するようにユーザーに求めるメッセージが表示されます。 Android では、ユーザーが過去に既にアクセス許可を拒否したかどうかを検出するために ShouldShowRationale を呼び出すことができます。

アクセス許可の状態

CheckStatusAsync または RequestAsync を使用すると、PermissionStatus が返されます。これを使って次の手順を決定できます。

  • Unknown
    アクセス許可が不明な状態であるか、iOS での場合、ユーザーにメッセージが表示されることはありません。

  • Denied
    ユーザーがアクセス許可要求を拒否しました。

  • Disabled
    この機能はデバイス上で無効になっています。

  • Granted
    ユーザーがアクセス許可を付与したか、自動的に付与されます。

  • Restricted
    制限された状態です。

  • Limited
    限定的な状態です。 iOS のみがこの状態を返します。

アクセス許可の要求

ユーザーからのアクセス許可を要求するには、要求する特定のアクセス許可を指定して RequestAsync メソッドを使用します。 ユーザーが以前にアクセス許可を付与していて、まだ取り消していない場合は、このメソッドによって Granted が返され、ユーザーにダイアログは表示されません。 アクセス許可は、自分の MauiProgram または App クラスから要求するべきではなく、アプリの最初のページが表示された後にのみ要求する必要があります。

次の例では、LocationWhenInUse アクセス許可を要求します。

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

必要なアクセス許可が宣言されていない場合は、PermissionException がスローされます。

重要

一部のプラットフォームでは、アクセス許可要求をアクティブにできるのは 1 回だけです。 アクセス許可が Denied の状態かどうかを確認し、手動で有効にするようにユーザーに依頼するには、開発者がさらにプロンプトを処理する必要があります。

アクセス許可が必要な理由を説明する

アプリケーションに特定のアクセス許可が必要な理由をユーザーに説明することをお勧めします。 iOS では、ユーザーに表示される文字列を指定する必要があります。 Android にはこの機能がなく、アクセス許可の状態の既定値は Disabled です。 そのため、ユーザーがアクセス許可を拒否したかどうか、またはユーザーにプロンプトを表示するのが初めてかどうかはわかりません。 ShouldShowRationale メソッドを使用すると、情報量が多い UI を表示する必要があるかどうかを判断できます。 このメソッドが true を返す場合、ユーザーは、過去にアクセス許可を拒否または無効にしています。 このメソッドを呼び出すと、他のプラットフォームは常に false を返します。

次のコードは、アクセス許可が付与されているかどうかを判断し、付与されていない場合は要求するための一般的な使用パターンを示しています。

public async Task<PermissionStatus> CheckAndRequestLocationPermission()
{
    PermissionStatus 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;
}

アクセス許可の拡張

Permissions API は、.NET MAUI に含まれていない追加の検証やアクセス許可が必要なアプリケーションに対して、柔軟かつ拡張可能であるように作成されています。 Permissions.BasePermission を継承するクラスを作成し、必要な抽象メソッドを実装します。 次のコード例では、基本的な抽象メンバーを示していますが、実装はありません。

public class MyPermission : Permissions.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();
    }

    // Indicates that the requestor should prompt the user as to why the app requires the permission, because the
    // user has previously denied this permission.
    public override bool ShouldShowRationale()
    {
        throw new NotImplementedException();
    }
}

特定のプラットフォームでアクセス許可を実装する場合、Permissions.BasePlatformPermission クラスから継承することができます。 このクラスにより、アクセス許可の宣言を自動的に確認するための、追加のプラットフォーム ヘルパー メソッドが提供されます。 これは、Android 上のストレージへの読み取り書き込みの両方のアクセスを要求するなど、グループ化を行うカスタム アクセス許可を作成するときに役立ちます。 次のコード例は、ストレージの読み取り書き込みのアクセスを要求する方法を示しています。

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

次に、.NET MAUI で提供される他のアクセス許可の種類と同じ方法でアクセス許可を確認します。

PermissionStatus status = await Permissions.RequestAsync<ReadWriteStoragePerms>();

クロスプラットフォーム コードからこの API を呼び出す場合は、インターフェイスを作成し、カスタム アクセス許可を依存関係としてアプリのサービス コンテナーに登録できます。 次の例は、IReadWritePermission インターフェイスを示しています。

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

次に、カスタム アクセス許可にインターフェイスを実装します。

public class ReadWriteStoragePermission : 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();
}

次に、MauiProgram クラスで、インターフェイスやその具象型と、カスタム アクセス許可を使用する型をアプリのサービス コンテナーに登録する必要があります。

builder.Services.AddTransient<MyViewModel>();
builder.Services.AddSingleton<IReadWritePermission, ReadWriteStoragePermission>();

その後、カスタム アクセス許可の実装を解決し、ビューモデルなどの型の 1 つから呼び出すことができます。

public class MyViewModel
{
    IReadWritePermission _readWritePermission;

    public MyViewModel(IReadWritePermission readWritePermission)
    {
        _readWritePermission = readWritePermission;
    }

    public async Task CheckPermissionAsync()
    {
        var status = await _readWritePermission.CheckStatusAsync();
        if (status != PermissionStatus.Granted)
        {
            status = await _readWritePermission.RequestAsync();
        }
    }
}

プラットフォームによる違い

このセクションでは、プラットフォーム固有とアクセス許可 API との違いについて説明します。

アクセス許可には、Android マニフェスト ファイルに一致する属性が設定されている必要があります。 アクセス許可の状態の既定値は Denied です。