
Skill
maui-device-capabilities
implement .NET MAUI device capabilities
Description
Implement .NET MAUI device capabilities with platform permissions and declarations. USE FOR: camera/photo/media capture, MediaPicker.IsCaptureSupported, FilePicker.PickAsync durable copies to FileSystem.AppDataDirectory, GeolocationRequest, Permissions.LocationWhenInUse, UseMauiMaps, Android manifest entries, READ_MEDIA_IMAGES/Android 13+ Photo Picker migration, NSCameraUsageDescription/NSLocationWhenInUseUsageDescription, runtime permission requests, denied/cancelled flows, and durable file access. DO NOT USE FOR: notifications, auth, or UI layout.
SKILL.md
MAUI Device Capabilities
Use this skill when a MAUI app needs device services such as files, media, camera, location, or maps. Always pair runtime API calls with platform declarations and a user-friendly denied/cancelled path.
Workflow
- Inspect target platforms and existing files under
Platforms/Android,Platforms/iOS,Platforms/MacCatalyst, andPlatforms/Windows. - Identify the exact capability and minimum permission needed.
- Add platform declarations before requesting runtime permissions.
- Request permissions close to the feature that needs them, after explaining why the app needs access.
- Treat cancellation as normal user choice.
- Keep device APIs behind services if ViewModels or tests should not depend on MAUI static APIs directly.
- Validate on every target platform because permission names and UX differ.
Permission Pattern
var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
if (status != PermissionStatus.Granted)
{
status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
}
if (status != PermissionStatus.Granted)
{
PermissionDeniedMessage = "Location is off. Enable it in Settings to show nearby stores.";
CanOpenSettings = true;
SemanticScreenReader.Announce(PermissionDeniedMessage);
return;
}
Do not repeatedly prompt after a user denies access. Show a feature-specific
empty/blocked state that screen readers can observe, and when appropriate guide
the user to app settings with an explicit button that calls
AppInfo.ShowSettingsUI().
Platform Declaration Map
| Capability | Android | iOS/Mac Catalyst |
|---|---|---|
| Camera/media capture | CAMERA and media storage permissions only when needed by target SDK behavior | NSCameraUsageDescription, NSMicrophoneUsageDescription, NSPhotoLibraryUsageDescription as applicable |
| Gallery/media library access | On Android 12 and earlier, audit READ_EXTERNAL_STORAGE; on Android 13+ use granular READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, or READ_MEDIA_AUDIO as applicable, or prefer the system photo picker when it satisfies the scenario | NSPhotoLibraryUsageDescription or limited-library APIs when reading the photo library |
| Geolocation | ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION, and background location only for true background scenarios | NSLocationWhenInUseUsageDescription; add always/background keys only when the app truly needs them |
| File picking | Usually no broad storage permission for system picker flows | Document picker usually needs no photo/camera usage key unless media capture/library access is used |
| Maps | Platform API key/configuration and UseMauiMaps() when using MAUI Maps | Platform map entitlement/configuration as required by the map provider |
Use the narrowest platform declaration that matches the feature. Do not add background location, broad storage, or microphone declarations "just in case".
Picker and Sensor Guardrails
FilePicker.PickAsyncandPickMultipleAsyncshould handle null, empty results, cancellation, andPermissionException.MediaPickershould checkIsCaptureSupportedbefore camera capture.- Copy picked file streams into app storage when the app needs durable access; picker-provided handles can be temporary.
Geolocation.GetLastKnownLocationAsynccan be stale. UseGetLocationAsyncwith aGeolocationRequestfor current location.- Choose
GeolocationRequest.DesiredAccuracydeliberately. Use medium or low accuracy to conserve battery unless the feature truly requires GPS precision. - Pass cancellation tokens to location requests where the UI can cancel or the page can disappear.
- Migrating apps should audit old Xamarin
READ_EXTERNAL_STORAGEdeclarations because Android 13+ media permissions changed runtime behavior.
Permission UX
- Ask at the moment of need, not on first launch.
- Explain the user benefit before invoking the platform prompt.
- Provide a useful fallback when access is denied.
- Make denied/blocked states visible and announced with
SemanticProperties.Description,SemanticScreenReader.Announce, or a focused explanatory label. - Avoid loops that immediately re-request permission after denial.
- Make error/cancelled states visible and testable with
AutomationIdwhen UI is affected.
Validation Checklist
- Platform manifests/plists include only the declarations required by the feature.
- Runtime permission requests happen before capability APIs that require them.
- Denied and cancelled flows are handled without crashes.
- Denied permission UI is visible, accessible, and offers Settings when the platform requires manual re-enable.
- Picked files/media are copied when durable access is required.
- Location code handles stale last-known data, timeout, and cancellation.
More skills from the maui-labs repository
View all 32 skillsandroid-slim-bindings
create Android slim bindings for .NET
Jul 12.NETAndroidJavaKotlin +1devflow-automation
automate .NET MAUI app state
Jul 12.NETAutomationMAUIMobiledevflow-connect
diagnose DevFlow agent connectivity issues
Jul 12DebuggingMAUINetworkingdotnet-workload-info
discover MAUI workload metadata
Jul 12C#CLIEngineeringMAUIios-slim-bindings
create iOS slim bindings for MAUI
Jul 12.NETiOSMAUISwift +1maui-accessibility
implement accessibility in .NET MAUI apps
Jul 12.NETAccessibilityMAUIMobile +1
More from .NET (Microsoft)
View publishermultithreaded-task-migration
migrate MSBuild tasks to multithreaded mode
msbuild
Jul 22.NETEngineeringPerformanceanalyzing-dotnet-performance
analyze .NET code for performance anti-patterns
skills
Jul 12.NETCode AnalysisDebuggingPerformanceandroid-tombstone-symbolication
symbolicate .NET runtime frames in Android tombstones
skills
Jul 12.NETAndroidDebuggingMicrosoftapple-crash-symbolication
symbolicate .NET runtime frames in crash logs
skills
Jul 12.NETDebuggingiOSmacOS +1assertion-quality
evaluate assertion quality in test suites
skills
Jul 12Code AnalysisQATestingauthor-component
create and review Blazor components
skills
Jul 15.NETBlazorC#UI Components +1