這篇文章的說明範例專案,可以從 這裡 取得
了解更多關於 [Xamarin.Android] 的使用方式
了解更多關於 [Xamarin.iOS] 的使用方式
了解更多關於 [Xamarin.Forms] 的使用方式
了解更多關於 [Hello, Android:快速入門] 的使用方式
了解更多關於 [Hello, iOS – 快速入門] 的使用方式
了解更多關於 [Xamarin.Forms 快速入門] 的使用方式
當我們在進行 Xamarin.Android 專案建置的時候,我們可以從 Android 專案內的 Properties 中,也就是這個專案的屬性視窗內,看到關於這三個名詞:最低的 Android 版本 / 目標 Android 版本 / 目標 Framework。若您想要更進一步的瞭解這三者的差異,可以參考 了解 Android API 層級 ,底下根據這篇文章內容,列出這三者的說明
- 目標 Framework (也稱為 compileSdkVersion)是在建置階段編譯您的應用程式特定的 Android 架構版本 (API 層級)
- 最低的 Android 版本 (也稱為 minSdkVersion)是 Android OS (亦即,最低 API 層級),可以安裝和執行應用程式的舊版本
- Android 的版本為目標 (也稱為 targetSdkVersion)是應用程式開發介面層級的 Android 裝置,應用程式預期執行。
由於 從 2018年 8 月之後 ,Google Play Console 將會需要新的應用程式目標應用程式開發介面層級 26 (Android 8.0) 或更高版本,這裡所指的是
目標 Android 版本
。 現有的應用程式必須以 API 層級 26 或更高版本。如需詳細資訊,請參閱 改善應用程式安全性和效能。
因此,在這裡,我們要來做些小測試,了解如何進行執行時期的權限檢查與請求使用者授予使用這些權限的程式設計方法。
建立測試專案
- 首先,使用 Xamarin.Forms for Prism 建立一個專案
- 滑鼠雙擊 Android 專案內的 Properties 節點,此時,這個專案的屬性視窗會顯示出來
- 請切換到 應用程式 標籤頁次,點選
使用下列 Android 版本編譯: (目標 Framework)
下拉選單,確定選擇的是 使用最新平台,這裡是會設定 compileSdkVersion - 這裡是英文版的 Visual Studio 2017 看到的內容,我們可以看到這個欄位名稱為
Compile using Android version: (Target Framework)
- 請切換到 Android 資訊清單 (Manifest) 標籤頁次,點選
目標 Android 版本
下拉選單,根據文件建議,請在這裡選擇最新的 SDK 版本,這裡是會設定 targetSdkVersion - 這裡是英文版的 Visual Studio 2017 看到的內容,我們可以看到這個欄位名稱為
Target Android version
- 請打開 Android 專案內的 MainActivity.cs 檔案,在組件層級,也就是命名空間之外,輸入底下程式碼,我們在這宣告了這個 Android 應用程式,需要使用這四種權限 Permission
[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)]
- 現在,請開始執行這個專案,您可以使用 Android SDK 6.0 以上的模擬器或者是實體手機來進行測試。
- 當這個應用程式執行完成後,請中止執行,並且在 Android 裝置或模擬器上,打開設定中的應用程式頁面,請在清單中找到您剛剛執行成功的應用程式名稱,並且點選它
- 當這個應用程式打開之後,您會看到這個應用程式明細頁面中,有個 Permissions 選項,請點選它,接著您就會發現到,這裡有三個 Permissions,不過,他們都是沒有被啟用的。
- 此時,若您的應用程式中,剛好有執行與使用到這三個權限相關的 API,不幸的是,您的應用程式,就會造成閃退的問題。
加入執行時期的所需權限檢查
- 建立一個 RuntimePermissionEvent 類別,用來定義 事件聚合器需要訂閱的事件類別
public class RuntimePermissionEvent : PubSubEvent<RuntimePermissionPayload>
{
}
public class RuntimePermissionPayload
{
}
- 請將測試頁面的 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="XFRunPermission.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>
- 請將該頁面的 ViewModel,修改成為底下 C# 程式碼
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XFRunPermission.Events;
namespace XFRunPermission.ViewModels
{
public class MainPageViewModel : ViewModelBase
{
private readonly IEventAggregator _eventAggregator;
public DelegateCommand CheckPermissionCommand { get; set; }
public MainPageViewModel(INavigationService navigationService,
IEventAggregator eventAggregator)
: base (navigationService)
{
_eventAggregator = eventAggregator;
CheckPermissionCommand = new DelegateCommand(() =>
{
_eventAggregator.GetEvent<RuntimePermissionEvent>().Publish(
new RuntimePermissionPayload());
});
Title = "Main Page";
}
}
}
- 在 Android 專案內找到 MainActivity.cs 節點,將這個檔案內的內容,使用底下程式碼來替換
using Android.App;
using Android.Content.PM;
using Android.OS;
using Prism;
using Prism.Events;
using Prism.Ioc;
using XFRunPermission.Events;
[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 XFRunPermission.Droid
{
[Activity(Label = "XFRunPermission", Icon = "@mipmap/ic_launcher", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
IEventAggregator fooIEventAggregator;
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App(new AndroidInitializer()));
var fooContainer = ((App.Current) as Prism.Unity.PrismApplication).Container;
fooIEventAggregator = fooContainer.Resolve<IEventAggregator>();
fooIEventAggregator.GetEvent<RuntimePermissionEvent>().Subscribe(x =>
{
CheckPermissions();
});
}
void CheckPermissions()
{
if ((int)Build.VERSION.SdkInt < 23)
{
return;
}
var fooRead = CheckSelfPermission(Android.Manifest.Permission.ReadExternalStorage);
var fooWrite = CheckSelfPermission(Android.Manifest.Permission.WriteExternalStorage);
if ((fooRead == (int)Permission.Granted) && (fooWrite == (int)Permission.Granted))
{
var foo = 0;
}
else
{
Android.Support.V4.App.ActivityCompat.RequestPermissions(this,
new string[] { Android.Manifest.Permission.ReadExternalStorage, Android.Manifest.Permission.WriteExternalStorage,
Android.Manifest.Permission.CallPhone, Android.Manifest.Permission.Camera}, 4);
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
var foo = 1;
}
}
public class AndroidInitializer : IPlatformInitializer
{
public void RegisterTypes(IContainerRegistry container)
{
// Register any platform specific implementations
}
}
}
開始進行測試
- 請再度執行這個專案,這個時候,首頁會看到這個畫面,請點選螢幕上的按鈕
- 當按鈕按下去之後,您將會看到了下圖畫面,系統將會要求您同意授權給予三種應用程式使用權限,在這裡,請在第一個權限使用授權點選 DENY,另外兩個,可以點選 ALLOW
- 完成後,您就可以關閉這個應用程式,回到 設定 > 應用程式,來查看這個應用程式可以使用權限的說明,現在,我們可以看到這個應用程式,經過使用者授權,已經可以使用 Camera & Phone 兩種 Permission 了。