XAML in Xamarin.Forms 基礎篇 電子書

XAML in Xamarin.Forms 基礎篇 電子書
XAML in Xamarin.Forms 基礎篇 電子書

Xamarin.Forms 快速入門 電子書

Xamarin.Forms 快速入門 電子書
Xamarin.Forms 快速入門 電子書

2018/06/01

Xamarin.Android 執行時期的權限處理說明 2 使用 Plugin.Permissions

這篇文章的說明範例專案,可以從 這裡 取得

了解更多關於 [Xamarin.Android] 的使用方式
了解更多關於 [Xamarin.iOS] 的使用方式
了解更多關於 [Xamarin.Forms] 的使用方式
了解更多關於 [Hello, Android:快速入門] 的使用方式
了解更多關於 [Hello, iOS – 快速入門] 的使用方式
了解更多關於 [Xamarin.Forms 快速入門] 的使用方式
在上一篇文章 Xamarin.Android 執行時期的權限處理說明 1 最低的 Android 版本 / 目標 Android 版本 / 目標 Framework ,我們透過了事件聚合器 Event Aggregator 來呼叫 Android 原生的執行時期的權限檢查與授權工作,不過,這樣的處理方式會有些麻煩,因為,我們同時也需要時做出 iOS 上的相關動態權限檢查與請求授權,因此,在這篇文章中,我們將會透過了 Plugin.Permissions 這個 NuGet 套件,讓我們可以在 Xamarin.Forms 的 .NET Standard 專案中,來進行相關的權限檢查與授權需求。而更多關於這個套件的說明與使用注意事項,可以參考 GitHub Plugin.Permissions 文章說明

準備測試專案

  • 首先我們先使用 Prism Template Pack 幫助我們建立一個 Xamarin.Forms 的專案
  • 接著,請在 SCL .NET Standard 專案中,加入這個 Plugin.Permissions 套件
  • 滑鼠窗擊 Xamarin.Android 專案中的 Properties 節點,並且切換到 Android 資訊清單 標籤頁次,找到 目標 Android 版本,在此下拉選單中,選擇任何一個 API 層級大於 23 的版本
  • 打開 Android 專案中的 MainActivity.cs 檔案,使用底下程式碼取代
using Android.App;
using Android.Content.PM;
using Android.OS;
using Prism;
using Prism.Ioc;

[assembly: UsesPermission(Name = Android.Manifest.Permission.ReadExternalStorage)]
[assembly: UsesPermission(Name = Android.Manifest.Permission.WriteExternalStorage)]
[assembly: UsesPermission(Name = Android.Manifest.Permission.Camera)]
[assembly: UsesPermission(Name = Android.Manifest.Permission.CallPhone)]
namespace XFPermPlugin.Droid
{
    [Activity(Label = "XFPermPlugin", Icon = "@mipmap/ic_launcher", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(bundle);

            Plugin.CurrentActivity.CrossCurrentActivity.Current.Init(this, bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App(new AndroidInitializer()));
        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [Android.Runtime.GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    public class AndroidInitializer : IPlatformInitializer
    {
        public void RegisterTypes(IContainerRegistry container)
        {
            // Register any platform specific implementations
        }
    }
}
  • 在此,我們使用了 [assembly: UsesPermission(Name = Android.Manifest.Permission.WriteExternalStorage)] 宣告我們需要進行外部記憶卡的寫入需求
  • 接著 我們要在 OnCreate 方法中,使用 Plugin.CurrentActivity.CrossCurrentActivity.Current.Init(this, bundle); 方法呼叫,進行這個套件初始化的動作。
  • 另外,我們也需要在 MainActivity 類別中,加入 OnRequestPermissionsResult 的方法覆寫。
  • 打開 MainPage.xaml 檔案,填入底下的 XAML 宣告
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XFPermPlugin.Views.MainPage"
             Title="{Binding Title}">

    <StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
        <Label Text="Welcome to Xamarin Forms and Prism!" />
        <Button Text="Permission 檢查與授權" Command="{Binding CheckPermissionCommand}" />
    </StackLayout>

</ContentPage>
  • 在這個頁面中,宣告的 UI 相當的簡單,只有一個按鈕
  • 打開 MainPageViewModel.cs,填入底下的 C# 程式碼
using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using Prism.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace XFPermPlugin.ViewModels
{
    public class MainPageViewModel : ViewModelBase
    {
        public DelegateCommand CheckPermissionCommand { get; set; }
        public readonly IPageDialogService _dialogService;
        public MainPageViewModel(INavigationService navigationService,
            IPageDialogService dialogService) 
            : base (navigationService)
        {
            _dialogService = dialogService;
            Title = "Main Page";
            CheckPermissionCommand = new DelegateCommand(async () =>
            {
                var fooStatus = await Plugin.Permissions.CrossPermissions
                .Current.CheckPermissionStatusAsync(Plugin.Permissions.Abstractions.Permission.Storage);
                if (fooStatus != Plugin.Permissions.Abstractions.PermissionStatus.Granted)
                {
                    if (await Plugin.Permissions.CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync
                    (Plugin.Permissions.Abstractions.Permission.Storage))
                    {
                        await _dialogService.DisplayAlertAsync("Need Storage", "Gunna need that Storage", "OK");
                    }

                    var results = await Plugin.Permissions.CrossPermissions.Current.RequestPermissionsAsync
                    (Plugin.Permissions.Abstractions.Permission.Storage);
                    //Best practice to always check that the key exists
                    if (results.ContainsKey(Plugin.Permissions.Abstractions.Permission.Storage))
                        fooStatus = results[Plugin.Permissions.Abstractions.Permission.Storage];
                }

                if (fooStatus == Plugin.Permissions.Abstractions.PermissionStatus.Granted)
                {
                    await _dialogService.DisplayAlertAsync("Storage Allow", "You can continue to call any storage API.", "OK");
                }
                else if (fooStatus != Plugin.Permissions.Abstractions.PermissionStatus.Unknown)
                {
                    await _dialogService.DisplayAlertAsync("Storage Denied", "Can not continue, try again.", "OK");
                }
            });
        }
    }
}
  • 在這個 ViewModel 中,我們使用了 Plugin.Permissions.CrossPermissions.Current 取得了 IPermissions 這個實作物件,並且使用了 Plugin.Permissions.CrossPermissions.Current.CheckPermissionStatusAsync(Plugin.Permissions.Abstractions.Permission.Storage) 敘述,來檢查現在正在執行的應用程式,是否已經取得使用者授權可以使用 Storage 的使用權限。
    若使用這已經授權使用 Storage 這個使用權限,則您會得到 Plugin.Permissions.Abstractions.PermissionStatus.Granted 值
    若使用者尚未授權,對於 Android 平台,我們需要顯示一段訊息,告知使用者我們需要這樣的權限,如此,應用程式方可正常運作。
    Android Permission
    接下來,我們使用了 Plugin.Permissions.CrossPermissions.Current.RequestPermissionsAsync(Plugin.Permissions.Abstractions.Permission.Storage) 方法,請求使用者授權這個應用程式,可以使用 Storage 的權限。
    Android Permission
    一旦此次請求授權的結果為 Plugin.Permissions.Abstractions.PermissionStatus.Granted ,您就可以開始進行相關 API 呼叫,否則,就不應該呼叫這些尚未授權 API 的呼叫。

1 則留言: