| MAUI-App-LifeCycle | MAUI-Handling-Platform-specific-code | |
.NET MAUI Device APIs |
Device APIs in .NET MAUI allow you to access native device features across platforms like Android, iOS, Windows, and macOS.
.NET MAUI integrates MAUI Essentials, a cross-platform library that exposes native device capabilities through a consistent API.
| API Category | Purpose & Examples |
|---|---|
| Device Info | Get model, manufacturer, platform, idiom, version. DeviceInfo.Current.Model |
| Battery | Monitor charge level, state, and power source. Battery.ChargeLevel |
| Connectivity | Check internet access and connection type. Connectivity.NetworkAccess |
| Display Info | Get screen metrics like resolution and orientation. DeviceDisplay.MainDisplayInfo |
| Secure Storage | Store sensitive data securely. SecureStorage.SetAsync("key", "value") |
| Geolocation | Access GPS coordinates. Geolocation.GetLocationAsync() |
| Sensors | Use accelerometer, compass, gyroscope. Accelerometer.Start(SensorSpeed.UI) |
| Media Picker | Pick photos/videos from gallery. MediaPicker.PickPhotoAsync() |
| File System | Access app directories. FileSystem.AppDataDirectory |
| Preferences | Store simple key-value pairs. Preferences.Set("theme", "dark") |
| Vibration | Trigger device vibration. Vibration.Vibrate() |
| Flashlight | Control flashlight. Flashlight.TurnOnAsync() |
| Phone Dialer | Launch dialer with number. PhoneDialer.Open("1234567890") |
| Email / SMS | Compose messages. Email.ComposeAsync() |
| Launcher | Open external apps or URLs. Launcher.OpenAsync("https://example.com") |
For features not covered by Essentials, you can use Dependency Injection or Platform Handlers to access native APIs directly:
#if ANDROID
using Android.OS;
var version = Build.VERSION.SdkInt;
#endif
using Microsoft.Maui.Devices;
var model = DeviceInfo.Current.Model;
var manufacturer = DeviceInfo.Current.Manufacturer;
var version = DeviceInfo.Current.VersionString;
Console.WriteLine($"Device: {manufacturer} {model}, OS: {version}");
using Microsoft.Maui.Devices;
var level = Battery.ChargeLevel; // 0.0 - 1.0
var state = Battery.State;
var source = Battery.PowerSource;
Console.WriteLine($"Battery: {level * 100}% - State: {state} - Source: {source}");
using Microsoft.Maui.Networking;
if (Connectivity.NetworkAccess == NetworkAccess.Internet)
{
Console.WriteLine("Connected to the Internet");
}
else
{
Console.WriteLine("No Internet access");
}
using Microsoft.Maui.Devices.Sensors;
var location = await Geolocation.GetLocationAsync();
if (location != null)
{
Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}");
}
using Microsoft.Maui.Media;
var photo = await MediaPicker.PickPhotoAsync();
if (photo != null)
{
var stream = await photo.OpenReadAsync();
Console.WriteLine($"Picked photo: {photo.FileName}");
}
using Microsoft.Maui.Storage;
await SecureStorage.SetAsync("auth_token", "12345");
var token = await SecureStorage.GetAsync("auth_token");
Console.WriteLine($"Token: {token}");
using Microsoft.Maui.Storage;
var path = FileSystem.AppDataDirectory;
Console.WriteLine($"App data stored at: {path}");
using Microsoft.Maui.Devices;
Vibration.Vibrate(TimeSpan.FromSeconds(1));
await Flashlight.TurnOnAsync();
await Flashlight.TurnOffAsync();
using Microsoft.Maui.ApplicationModel.Communication;
PhoneDialer.Open("9876543210");
using Microsoft.Maui.ApplicationModel.Communication;
var message = new EmailMessage
{
Subject = "Hello from MAUI",
Body = "This is a test email",
To = new List { "test@example.com" }
};
await Email.ComposeAsync(message);
For most of these (especially Camera, Location, and Battery), you must declare the permissions in:
AndroidManifest.xmlInfo.plistTo keep your code clean, it's best to handle permissions dynamically. In MAUI, you can use the built-in Permissions API to check and request access at runtime.
Here is a reusable helper class to handle common permission checks (Camera, Location, etc.) without repeating logic:
public static class PermissionHelper
{
public static async Task<bool> CheckAndRequestPermission<TPermission>()
where TPermission : Permissions.BasePermission, new()
{
PermissionStatus status = await Permissions.CheckStatusAsync<TPermission>();
if (status == PermissionStatus.Granted)
return true;
if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
{
// Prompt user to go to Settings on iOS as you can't re-request after a deny
return false;
}
// Request the permission
status = await Permissions.RequestAsync<TPermission>();
return status == PermissionStatus.Granted;
}
}
You can call this for any hardware API before using it:
// Example: Camera
bool hasCamera = await PermissionHelper.CheckAndRequestPermission<Permissions.Camera>();
if (hasCamera)
{
var photo = await MediaPicker.Default.CapturePhotoAsync();
}
// Example: Location
bool hasGps = await PermissionHelper.CheckAndRequestPermission<Permissions.LocationWhenInUse>();
if (hasGps)
{
var location = await Geolocation.Default.GetLocationAsync();
}
On Android, you often need to override the Back Button behavior (e.g., to prevent accidental exits or close side menus). You do this in your MainPage.xaml.cs:
protected override bool OnBackButtonPressed()
{
// Return 'true' to handle (prevent) the back action
// Return 'false' to allow the system to go back
bool isMenuOpen = MyFlyoutMenu.IsPresented;
if (isMenuOpen)
{
MyFlyoutMenu.IsPresented = false;
return true;
}
return base.OnBackButtonPressed();
}
For these to work, you must update your platform manifests:
| MAUI-App-LifeCycle | MAUI-Handling-Platform-specific-code | |