Xamarin.Essentials: Permissions
The Permissions class provides the ability to check and request runtime permissions.
Get started
To start using this API, read the getting started guide for Xamarin.Essentials to ensure the library is properly installed and set up in your projects.
This API uses runtime permissions on Android. Please ensure that Xamarin.Essentials is fully initialized and permission handling is setup in your app.
In the Android project's MainLauncher or any Activity that is launched Xamarin.Essentials must be initialized in the OnCreate method:
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
//...
}
To handle runtime permissions on Android, Xamarin.Essentials must receive any OnRequestPermissionsResult. Add the following code to all Activity classes:
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);
}
Using Permissions
Add a reference to Xamarin.Essentials in your class:
using Xamarin.Essentials;
Checking Permissions
To check the current status of a permission, use the CheckStatusAsync method along with the specific permission to get the status for.
var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
A PermissionException is thrown if the required permission is not declared.
It's best to check the status of the permission before requesting it. Each operating system returns a different default state if the user has never been prompted. iOS returns Unknown, while others return Denied.
Requesting Permissions
To request a permission from the users, use the RequestAsync method along with the specific permission to request. If the user previously granted permission and hasn't revoked it, then this method will return Granted immediately and not display a dialog.
var status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
A PermissionException is thrown if the required permission is not declared.
Note, that on some platforms a permission request can only be activated a single time. Further prompts must be handled by the developer to check if a permission is in the Denied state and ask the user to manually turn it on.
Permission Status
When using CheckStatusAsync or RequestAsync a PermissionStatus will be returned that can be used to determine the next steps:
- Unknown - The permission is in an unknown state
- Denied - The user denied the permission request
- Disabled - The feature is disabled on the device
- Granted - The user granted permission or is automatically granted
- Restricted - In a restricted state
Available Permissions
Xamarin.Essentials attempts to abstract as many permissions as possible. However, each operating system has a different set of runtime permissions. In addition there are differences when providing a single API for some permissions. Here is a guide to the currently available permissions:
Icon Guide:
- Supported
- Not supported/required
| Permission | Android | iOS | UWP | watchOS | tvOS | Tizen |
|---|---|---|---|---|---|---|
| CalendarRead | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| CalendarWrite | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Camera | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| ContactsRead | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| ContactsWrite | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Flashlight | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| LocationWhenInUse | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| LocationAlways | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Media | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Microphone | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Phone | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Photos | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Reminders | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Sensors | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Sms | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Speech | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| StorageRead | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| StorageWrite | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
If a permission is marked as
it will always return Granted when checked or requested.
General Usage
Here is a general usage pattern for handling permissions.
public async Task<PermissionStatus> CheckAndRequestLocationPermission()
{
var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
if (status != PermissionStatus.Granted)
{
status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
}
// Additionally could prompt the user to turn on in settings
return status;
}
Each permission type can have an instance of it created that the methods can be called directly.
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;
}
Extending Permissions
The Permissions API was created to be flexible and extensible for applications that require additional validation or permissions that aren't included in Xamarin.Essentials. Create a new class that inherits from BasePermission and implement the required abstract methods. Then
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();
}
}
When implementing a permission in a specific platform, the BasePlatformPermission class can be inherited from. This provides additional platform helper methods to automatically check the declarations. This can help when creating custom permissions to do grouping. For example, you can request both Read and Write access to storage on Android using the following custom permission.
Create a new permission in your project that you're calling permissions from.
public partial class ReadWriteStoragePermission : Xamarin.Essentials.Permissions.BasePlatformPermission
{
}
In your Android project, extend the permission with permissions you would like to request.
public partial 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();
}
Then you can call your new permission from shared logic.
await Permissions.RequestAsync<ReadWriteStoragePermission>();
Platform Implementation Specifics
Permissions must have the matching attributes set in the Android Manifest file.
Read more on the Permissions in Xamarin.Android documentation.



