Xamarinでデバイスの許可をアプリのダイアログで行う方法

Xamarinでデバイスの許可をアプリのダイアログで行う方法をご紹介します。
例としてカメラの許可を扱います。

条件

  • Xamarin.Forms
  • Visual Studio 2019
  • SHARP SH-M12(Android 9.0 – API 28)

プロジェクトの作成

Visual Studio 2019を起動し、新しいプロジェクトの作成で「モバイルアプリ(Xamarin.Forms)」を選択し次へボタンを押します。

プロジェクト名に任意の名前を入力して、作成ボタンを押します。
(ここではPermissionTestとしました。)

テンプレートの選択で、空白を選択してOKボタンを押します。

以上で空のXamarin.Formsプロジェクトが作成されます。

デバイス許可処理の実装

パッケージのインストール

作成したプロジェクトのソリューションエクスプローラーで、依存関係 > NuGetパッケージの管理を選択します。

NuGetパッケージマネージャーで、Plugin.Permissionsを検索してインストールします。

インストール時に、変更のプレビューが表示された場合、OKボタンを押します。

同様に、ソリューションエクスプローラー(Android)で、依存関係 > NuGetパッケージの管理を選択します。

NuGetパッケージマネージャーで、Plugin.CurrentActivityを検索してインストールします。

以上で必要なパッケージのインストールは完了です。

ソース修正

Androidソース

AndroidのMainActivity.csを修正します。

ポイントは以下の2つです。

  1. OnCreate()にデバイス許可の初期化処理を追記
    • CrossCurrentActivity.Current.Init(this, savedInstanceState);
  2. OnRequestPermissionsResult()にコードを追加
    • PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.OS;
using Plugin.Permissions;
using Plugin.CurrentActivity;

namespace PermissionTest.Droid
{
    [Activity(Label = "PermissionTest", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            CrossCurrentActivity.Current.Init(this, savedInstanceState); // デバイスの許可を行うための初期化処理

            base.OnCreate(savedInstanceState);

            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            //Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
            PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

共通ソース

共通ソースのMainPage.xamlを以下のように記述します。
「許可」というボタンを1つだけ表示します。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="PermissionTest.MainPage">

    <StackLayout>
        <!-- Place new controls here -->
        <Button x:Name="permissionButton" Text="許可" Clicked="PermissionButton_Clicked" 
                VerticalOptions="CenterAndExpand" />
    </StackLayout>

</ContentPage>

共通ソースのMainPage.xaml.csを以下のように記述します。
「許可ボタンが押された際、対象デバイスのPermissionをチェックして、許可されていない場合はリクエストを表示します。

using Plugin.Permissions;
using Plugin.Permissions.Abstractions;
using System;
using System.ComponentModel;
using System.Diagnostics;
using Xamarin.Forms;

namespace PermissionTest
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private async void PermissionButton_Clicked(object sender, EventArgs e)
        {
      Debug.WriteLine("許可ボタンが押されました。");

      try
      {
        // Permission状態を取得
        var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
        if (status != PermissionStatus.Granted)
        {
          // 許可されていなければユーザーに許可してもらうためにPermissionのリクエストを行う。
          status = (await CrossPermissions.Current.RequestPermissionsAsync(Permission.Camera))[Permission.Camera];
        }

        if (status == PermissionStatus.Granted)
        {
          Debug.WriteLine("許可されました。");
        }
        else
        {
          Debug.WriteLine("許可されていません。");
        }
      }
      catch (Exception ex)
      {
        Debug.WriteLine("PermissionButton_Clicked Error = " + ex.Message);
      }
    }
    }
}

マニフェスト設定

Androidプロジェクトを右クリック > プロパティを選択します。

プロパティ画面が開くので、「Androidマニフェスト」の必要なアクセス許可で「CAMERA」にチェックを入れます。

実行結果

アプリを起動すると「許可」ボタンのみが表示されます。

「許可」ボタンを押すと、許可するかどうかのダイアログが表示されます。

許可を選択すると、対象機能が許可されます。
今回はカメラの許可を行ったので、アプリの権限でカメラが許可されていることがわかります。

その他の例

位置情報アクセス許可

同様に、位置情報のアクセス許可を行う場合、以下のようにします。

「Androidマニフェスト」の必要なアクセス許可で「ACCESS_COARSE_LOCATION」と「ACCESS_FINE_LOCATION」にチェックを入れます。

MainPage.xaml.csの許可処理を以下のように変更します。

// Permission状態を取得
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (status != PermissionStatus.Granted)
{
  // 許可されていなければユーザーに許可してもらうためにPermissionのリクエストを行う。
  status = (await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location))[Permission.Location];
}

実行結果

位置情報アクセス許可するかどうかのダイアログが表示されます。

許可ボタンを押すと、位置情報アクセスも許可になります。

よくある不具合例

AndroidソースのMainActivity.csにおける、OnCreateで以下の記述をしないと、許可確認ダイアログが表示されません。

CrossCurrentActivity.Current.Init(this, savedInstanceState);

以下の箇所で、statusに「Plugin.Permissions.Abstractions.PermissionStatus.Unknown」が返ります。

status = (await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location))[Permission.Location];

参考

Plugin.Permissions

https://github.com/jamesmontemagno/PermissionsPlugin

Plugin.CurrentActivity

https://github.com/jamesmontemagno/CurrentActivityPlugin

Xamarinでデバイスの許可をアプリのダイアログで行う方法” に対して1件のコメントがあります。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です