maui-permissions
8
总安装量
7
周安装量
#33977
全站排名
安装命令
npx skills add https://github.com/davidortinau/maui-skills --skill maui-permissions
Agent 安装分布
gemini-cli
7
amp
6
github-copilot
6
codex
6
kimi-cli
6
opencode
6
Skill 文档
.NET MAUI Permissions
Core API
using Microsoft.Maui.ApplicationModel;
// Check current status
PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.Camera>();
// Request permission
status = await Permissions.RequestAsync<Permissions.Camera>();
// Android: check if rationale should be shown after prior denial
bool showRationale = Permissions.ShouldShowRationale<Permissions.Camera>();
PermissionStatus Enum
| Value | Meaning |
|---|---|
Unknown |
Status unknown or not supported on platform |
Denied |
User denied the permission |
Disabled |
Feature is disabled on the device |
Granted |
User granted permission |
Restricted |
Permission restricted by policy (iOS parental, etc.) |
Limited |
Partial access granted (iOS limited photo access) |
Always-Check-Before-Request Pattern
public async Task<PermissionStatus> CheckAndRequestPermissionAsync<T>() where T : Permissions.BasePermission, new()
{
var status = await Permissions.CheckStatusAsync<T>();
if (status == PermissionStatus.Granted)
return status;
if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
{
// iOS only allows one request; after denial user must go to Settings
return status;
}
if (Permissions.ShouldShowRationale<T>())
{
// Show UI explaining why the permission is needed before re-requesting
await Shell.Current.DisplayAlert("Permission needed",
"This feature requires the requested permission.", "OK");
}
return await Permissions.RequestAsync<T>();
}
Available Permissions
Battery, Bluetooth, CalendarRead, CalendarWrite, Camera,
ContactsRead, ContactsWrite, Flashlight, LocationWhenInUse,
LocationAlways, Media, Microphone, NearbyWifiDevices,
NetworkState, Phone, Photos, PhotosAddOnly, PhotosReadWrite,
PostNotifications, Reminders, Sensors, Sms, Speech,
StorageRead, StorageWrite, Vibrate
Access via Permissions.<Name>, e.g. Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>().
Custom Permissions
Extend BasePlatformPermission and override platform-specific required permissions:
public class ReadExternalStoragePermission : Permissions.BasePlatformPermission
{
#if ANDROID
public override (string androidPermission, bool isRuntime)[] RequiredPermissions =>
new (string, bool)[]
{
("android.permission.READ_EXTERNAL_STORAGE", true)
};
#endif
}
// Usage
var status = await Permissions.RequestAsync<ReadExternalStoragePermission>();
Platform Notes
Android
- Permission requests show a system dialog;
ShouldShowRationalereturnstrueafter the user has previously denied (but not “Don’t ask again”). - API 33+ (Android 13):
StorageReadandStorageWritealways returnGrantedbecause scoped storage removes the need for broad storage permissions. UseMedia,Photos, orPhotosReadWritefor media access instead. - Declare permissions in
Platforms/Android/AndroidManifest.xml:<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
iOS
- The system permission dialog is shown only once. If the user denies,
subsequent
RequestAsynccalls returnDeniedimmediately. Guide users to Settings â App â Permission to re-enable. - Declare usage descriptions in
Platforms/iOS/Info.plist:<key>NSCameraUsageDescription</key> <string>This app needs camera access to take photos.</string> <key>NSLocationWhenInUseUsageDescription</key> <string>This app needs your location for nearby search.</string>
Windows
- Most permissions return
GrantedorUnknown. Declare capabilities inPlatforms/Windows/Package.appxmanifestunder<Capabilities>.
Mac Catalyst
- Follows iOS patterns. Add usage descriptions to
Info.plistand entitlements toEntitlements.plistas needed.
DI-Friendly Permission Service
public interface IPermissionService
{
Task<PermissionStatus> CheckAndRequestAsync<T>() where T : Permissions.BasePermission, new();
}
public class PermissionService : IPermissionService
{
public async Task<PermissionStatus> CheckAndRequestAsync<T>() where T : Permissions.BasePermission, new()
{
var status = await Permissions.CheckStatusAsync<T>();
if (status == PermissionStatus.Granted)
return status;
if (Permissions.ShouldShowRationale<T>())
{
await Shell.Current.DisplayAlert("Permission required",
"Please grant the requested permission to use this feature.", "OK");
}
return await Permissions.RequestAsync<T>();
}
}
// Registration
builder.Services.AddSingleton<IPermissionService, PermissionService>();
Key Rules
- Always call
CheckStatusAsyncbeforeRequestAsyncâ avoids unnecessary prompts. - Never call permission APIs from a constructor â use
OnAppearingor a command. - Handle every
PermissionStatusvalue â especiallyDeniedandRestricted. - Android: use
ShouldShowRationaleto show explanatory UI before re-requesting. - iOS: plan for one-shot request; provide Settings navigation for denied permissions.
- Scoped storage (API 33+): stop requesting
StorageRead/StorageWrite; use media permissions.