読者です 読者をやめる 読者になる 読者になる

ぴよぴよエンジニアの日記

クラウドベンダーに勤める見習いSEの日記です。発言は私自身の見解であり、必ずしも所属組織の立場、戦略、意見を代表するものではありません。

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

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


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

f:id:Santea:20160329194909j:plain
Target Android versionをAPI Level 23にすると,


f:id:Santea:20160329194404j:plain
エラーを吐きます.


原因はPermission.

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


Xamarin.Plugins/PermissionsでRuntime Permissionを実装

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


変更箇所は以下の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<IDialer>();
                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<IDialer>();
                if (dialer != null)
                    dialer.Dial(translatedNumber);
            }*/
        }
    }
}

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

実装結果

f:id:Santea:20160329200504p:plain

Runtime Permissionを実装できました.

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


f:id:Santea:20160329200708p:plain
2回目以降のリクエストでは表示が変化します.

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

  • Denied
  • Disabled
  • Granted
  • Restricted
  • Unknown



以上です.