Xamarin.Essentials:權限
Permissions 類別能提供檢查及要求執行階段權限的能力。
開始使用
若要開始使用此 API,請閱讀 入門指南Xamarin.Essentials,以確保連結庫已正確安裝並設定在您的專案中。
此 API 會在 Android 上使用執行時間許可權。 請確定 Xamarin.Essentials 已完全初始化,且已在您的應用程式中設定許可權處理。
在 Android 專案的 MainLauncher
或任何 Activity
啟動時 Xamarin.Essentials ,必須在 方法中 OnCreate
初始化:
protected override void OnCreate(Bundle savedInstanceState)
{
//...
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
//...
}
若要處理 Android 上的執行時間權限, Xamarin.Essentials 必須接收任何 OnRequestPermissionsResult
。 將下列程式碼新增到所 Activity
類別:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
使用權限
在類別中新增 的 Xamarin.Essentials 參考:
using Xamarin.Essentials;
檢查權限
若要檢查某個權限的目前狀態,請搭配特定的權限使用 CheckStatusAsync
方法來取得其狀態。
var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
如果所需的權限未宣告,便會擲回 PermissionException
。
最好先檢查許可權的狀態,再要求許可權。 如果用戶從未收到提示,則每個操作系統都會傳回不同的默認狀態。 iOS 會傳 Unknown
回 ,而其他則傳回 Denied
。 如果狀態為 Granted
,則不需要進行其他呼叫。 在 iOS 上,如果狀態為 Denied
,您應該提示使用者變更設定中的許可權,並在 Android 上呼叫 ShouldShowRationale
,以偵測使用者是否已經拒絕過去的許可權。
要求權限
若要從使用者要求權限,請搭配特定的權限使用 RequestAsync
方法來要求。 如果使用者先前已授與許可權且尚未撤銷許可權,則此方法會立即傳回 Granted
,而不會顯示對話方塊。
var status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
如果所需的權限未宣告,便會擲回 PermissionException
。
請注意,在某些平台上,權限要求只能單次啟動。 開發人員必須處理進一步的提示,以檢查許可權是否處於 Denied
狀態,並要求使用者手動開啟。
權限狀態
使用 CheckStatusAsync
或 RequestAsync
PermissionStatus
時會傳回 ,可用來判斷後續步驟:
- Unknown:權限處於未知的狀態
- Denied:使用者已拒絕權限要求
- Disabled:裝置上已停用該功能
- Granted:使用者已授與權限,或是系統已自動授與權限
- Restricted:處於受限制的狀態
說明需要許可權的原因
最佳做法是說明應用程式為何需要特定許可權。 在 iOS 上,您必須指定向使用者顯示的字串。 Android 沒有這項功能,也預設為 [已停用] 的許可權狀態。 這會限制使用者是否拒絕許可權或第一次提示使用者的能力。 ShouldShowRationale
方法可用來判斷是否應該顯示教育UI。 如果方法傳 true
回,這是因為用戶過去已拒絕或停用許可權。 呼叫此方法時,其他平臺一律會傳回 false
。
可用的權限
Xamarin.Essentials 嘗試盡可能擷取盡可能多的許可權。 不過,每個作業系統都有一組不同的運行時間許可權。 此外,針對某些許可權提供單一 API 時也有差異。 以下是目前可用權限的指南:
圖示指南:
- -支援
- - 不支援/必要
權限 | Android | iOS | UWP | watchOS | tvOS | Tizen |
---|---|---|---|---|---|---|
CalendarRead | ||||||
CalendarWrite | ||||||
相機 | ||||||
ContactsRead | ||||||
ContactsWrite | ||||||
Flashlight | ||||||
LocationWhenInUse | ||||||
LocationAlways | ||||||
媒體 | ||||||
麥克風 | ||||||
電話 | ||||||
相片 | ||||||
提醒 | ||||||
感應器 | ||||||
Sms | ||||||
語音 | ||||||
StorageRead | ||||||
StorageWrite |
如果許可權標示為 一律會在核取或要求時傳回 Granted
。
一般使用方式
下列程式代碼會呈現一般使用模式,以判斷是否已授與許可權,並在未授與許可權時要求許可權。 此程式代碼使用 1.6.0 版或更新版本可用的 Xamarin.Essentials 功能。
public async Task<PermissionStatus> CheckAndRequestLocationPermission()
{
var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
if (status == PermissionStatus.Granted)
return status;
if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
{
// Prompt the user to turn on in settings
// On iOS once a permission has been denied it may not be requested again from the application
return status;
}
if (Permissions.ShouldShowRationale<Permissions.LocationWhenInUse>())
{
// Prompt the user with additional information as to why the permission is needed
}
status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
return status;
}
每個權限類型都可以建立其自己的執行個體,以用來直接呼叫方法。
public async Task GetLocationAsync()
{
var status = await CheckAndRequestPermissionAsync(new Permissions.LocationWhenInUse());
if (status != PermissionStatus.Granted)
{
// Notify user permission was denied
return;
}
var location = await Geolocation.GetLocationAsync();
}
public async Task<PermissionStatus> CheckAndRequestPermissionAsync<T>(T permission)
where T : BasePermission
{
var status = await permission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
status = await permission.RequestAsync();
}
return status;
}
延伸權限
許可權 API 已建立為彈性且可延伸的應用程式,這些應用程式需要其他驗證或未包含在 中 Xamarin.Essentials的許可權。 建立繼承自 BasePermission
的新類別,並實作必要的抽象方法。
public class MyPermission : BasePermission
{
// This method checks if current status of the permission
public override Task<PermissionStatus> CheckStatusAsync()
{
throw new System.NotImplementedException();
}
// This method is optional and a PermissionException is often thrown if a permission is not declared
public override void EnsureDeclared()
{
throw new System.NotImplementedException();
}
// Requests the user to accept or deny a permission
public override Task<PermissionStatus> RequestAsync()
{
throw new System.NotImplementedException();
}
}
在特定的平台上實作權限時,便可以繼承自 BasePlatformPermission
類別。 這會提供額外的平臺協助程式方法來自動檢查宣告。 建立進行群組的自定義許可權時,這可有所説明。 例如,您可以使用下列自定義許可權,要求對 Android 上的記憶體進行讀取和寫入存取。
public class ReadWriteStoragePermission : Xamarin.Essentials.Permissions.BasePlatformPermission
{
public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
{
(Android.Manifest.Permission.ReadExternalStorage, true),
(Android.Manifest.Permission.WriteExternalStorage, true)
}.ToArray();
}
然後,您可以從 Android 專案呼叫新的許可權。
await Permissions.RequestAsync<ReadWriteStoragePermission>();
如果您想要從共用程式代碼呼叫此 API,您可以建立介面並使用 相依性服務 來註冊並取得實作。
public interface IReadWritePermission
{
Task<PermissionStatus> CheckStatusAsync();
Task<PermissionStatus> RequestAsync();
}
然後在您的平台項目中實作 介面:
public class ReadWriteStoragePermission : Xamarin.Essentials.Permissions.BasePlatformPermission, IReadWritePermission
{
public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
{
(Android.Manifest.Permission.ReadExternalStorage, true),
(Android.Manifest.Permission.WriteExternalStorage, true)
}.ToArray();
}
然後,您可以註冊特定的實作:
DependencyService.Register<IReadWritePermission, ReadWriteStoragePermission>();
然後,從您的共享專案,您可以解析並使用它:
var readWritePermission = DependencyService.Get<IReadWritePermission>();
var status = await readWritePermission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
status = await readWritePermission.RequestAsync();
}
平台實作特性
權限必須擁有在 Android 資訊清單檔中設定的相符屬性。 許可權狀態預設為 [拒絕]。
請在 Xamarin.Android 中的權限 \(英文\) 文件中深入閱讀。