Android の Runtime Permission を Xamarin.Plugins/Permissions でやってみた

先週参加させて頂いたXamarinハンズオンのアプリにXamarin.Plugins/Permissionsを使ってRuntime Permissionを実装してみました.

Target Android version を API Level 23にすると…

Target Android version を API Level 23にすると,

エラーを吐きます.

原因はPermission.

Xamarin.Plugins/Permissionsが使えるとな!?

Xamarin.Plugins/PermissionsでRuntime Permissionを実装

Xamarin.Plugins/Permissions を使って Runtime Permission を実装します.

変更箇所は以下の2つ.

namespace Phoneword.Droid
{
    [Activity(Label = "Phoneword", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
        {
            Console.WriteLine("OnRequestPermissionsResult called ...");

            PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

MainActivity に OnRequestPermissionsResult を追加.

using Plugin.Permissions;
using Plugin.Permissions.Abstractions;
using System;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Phoneword
{
    public partial class MainPage : ContentPage
    {
        string translatedNumber;

        public MainPage()
        {
            InitializeComponent();
        }

        void OnTranslate(object sender, EventArgs e)
        {
            translatedNumber = Core.PhonewordTranslator.ToNumber(phoneNumberText.Text);
            if (!string.IsNullOrWhiteSpace(translatedNumber))
            {
                callButton.IsEnabled = true;
                callButton.Text = "Call " + translatedNumber;
            }
            else {
                callButton.IsEnabled = false;
                callButton.Text = "Call";
            }
        }

        async void OnCall(object sender, EventArgs e)
        {
            await this.DisplayAlert(
                    "Dial a Number",
                    "Would you like to call " + translatedNumber + "?",
                    "Yes",
                    "No");

            var status = PermissionStatus.Unknown;
            // Permissionを取得しているかを確認
            status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Phone);

            // 持っていなかったらPermissionをリクエスト
            if (status != PermissionStatus.Granted)
                status = (await CrossPermissions.Current.RequestPermissionsAsync(Permission.Phone))[Permission.Phone];

            // Permissionを取得できたらIntentに投げる
            if (status == PermissionStatus.Granted)
            {
                var dialer = DependencyService.Get();
                if (dialer != null)
                    dialer.Dial(translatedNumber);
            }

            
            /*if (await this.DisplayAlert(
                    "Dial a Number",
                    "Would you like to call " + translatedNumber + "?",
                    "Yes",
                    "No"))
            {
                var dialer = DependencyService.Get();
                if (dialer != null)
                    dialer.Dial(translatedNumber);
            }*/
        }
    }
}

MainPage.xaml.cs の OnCall を上記のように修正.
電話を掛けるごとに Permission を確認します.

実装結果

Runtime Permission を実装できました.

今のコードだと「許可しない」を選んだ場合でも毎回 Permissionをリクエストしてくるので、



2回目以降のリクエストでは表示が変化します.

PermissionStatus は以下の5つが用意されているので,Permission の状態で分岐させることも可能です.

  • Denied
  • Disabled
  • Granted
  • Restricted
  • Unknown

以上です.