Previous MAUI-Permissions MAUI-Preferences-and-SecureStorage Next

.NET MAUI Permissions Checklist

Here’s a permissions checklist per platform so you know exactly what to declare in manifests before coding with runtime permissions in .NET MAUI:

πŸ“± Android

Manifest (AndroidManifest.xml) β†’ Add required permissions:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    

Runtime Request β†’ Use Permissions.RequestAsync<T>() in code.

Notes

  • Android 6.0+ requires runtime permission prompts.
  • Grouped permissions (e.g., location) may require multiple checks.

🍎 iOS / macOS (Catalyst)

Info.plist β†’ Add usage descriptions (human-readable messages shown to users):

<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to show nearby stores.</string>

<key>NSCameraUsageDescription</key>
<string>We need camera access to take profile pictures.</string>

<key>NSContactsUsageDescription</key>
<string>We need contacts access to invite friends.</string>
    

Notes

  • iOS will crash if you call a sensitive API without a usage description.
  • Messages must clearly explain why the app needs access.

πŸ–₯ Windows

Package.appxmanifest β†’ Declare capabilities:

<Capabilities>
  <Capability Name="internetClient" />
  <DeviceCapability Name="location" />
  <DeviceCapability Name="microphone" />
  <DeviceCapability Name="webcam" />
</Capabilities>
    

Notes

  • Windows prompts users when apps request sensitive capabilities.
  • Capabilities must be declared or APIs may fail silently.

πŸ“Š Summary Table

Feature Android Manifest Permission iOS/macOS Info.plist Key Windows Capability
Location ACCESS_FINE_LOCATION NSLocationWhenInUseUsageDescription location
Camera CAMERA NSCameraUsageDescription webcam
Microphone RECORD_AUDIO NSMicrophoneUsageDescription microphone
Contacts READ_CONTACTS NSContactsUsageDescription N/A
Storage / Photos READ / WRITE_EXTERNAL_STORAGE NSPhotoLibraryUsageDescription N/A

πŸ’‘ Best Practices

  • Always declare permissions in manifests first.
  • Use runtime checks (Permissions.CheckStatusAsync) before calling APIs.
  • Provide clear, user-friendly explanations in iOS/macOS Info.plist.
  • Handle denied permissions gracefully (disable feature or show fallback).

.NET MAUI PermissionsHelper

A PermissionsHelper class that abstracts away the boilerplate logic so you can request and check permissions in a clean, reusable way across your .NET MAUI app.

🧩 PermissionsHelper Class

using Microsoft.Maui.ApplicationModel;
using Microsoft.Maui.Devices.Sensors;
using System.Threading.Tasks;

public static class PermissionsHelper
{
    public static async Task<bool> RequestLocationAsync()
    {
        var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
        if (status != PermissionStatus.Granted)
        {
            status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
        }
        return status == PermissionStatus.Granted;
    }

    public static async Task<bool> RequestCameraAsync()
    {
        var status = await Permissions.CheckStatusAsync<Permissions.Camera>();
        if (status != PermissionStatus.Granted)
        {
            status = await Permissions.RequestAsync<Permissions.Camera>();
        }
        return status == PermissionStatus.Granted;
    }

    public static async Task<bool> RequestMicrophoneAsync()
    {
        var status = await Permissions.CheckStatusAsync<Permissions.Microphone>();
        if (status != PermissionStatus.Granted)
        {
            status = await Permissions.RequestAsync<Permissions.Microphone>();
        }
        return status == PermissionStatus.Granted;
    }

    public static async Task<bool> RequestContactsAsync()
    {
        var status = await Permissions.CheckStatusAsync<Permissions.ContactsRead>();
        if (status != PermissionStatus.Granted)
        {
            status = await Permissions.RequestAsync<Permissions.ContactsRead>();
        }
        return status == PermissionStatus.Granted;
    }

    public static async Task<bool> RequestStorageAsync()
    {
        var status = await Permissions.CheckStatusAsync<Permissions.StorageRead>();
        if (status != PermissionStatus.Granted)
        {
            status = await Permissions.RequestAsync<Permissions.StorageRead>();
        }
        return status == PermissionStatus.Granted;
    }
}
    

πŸ“Œ Usage Example

if (await PermissionsHelper.RequestLocationAsync())
{
    var location = await Geolocation.GetLocationAsync();
    Console.WriteLine($"Lat: {location.Latitude}, Lon: {location.Longitude}");
}
else
{
    Console.WriteLine("Location permission denied.");
}
    

πŸ’‘ Benefits

  • Centralized logic β†’ All permission checks live in one place.
  • Reusable β†’ Call PermissionsHelper.RequestXAsync() from anywhere.
  • Clean code β†’ Avoid repeating CheckStatusAsync + RequestAsync everywhere.
  • Extensible β†’ Add more permissions as needed.
Back to Index
Previous MAUI-Permissions MAUI-Preferences-and-SecureStorage Next
*