Skip to content

Instantly share code, notes, and snippets.

@salarcode
Last active August 19, 2024 12:41
Show Gist options
  • Save salarcode/da8ad2b993e67c602db88a62259d0456 to your computer and use it in GitHub Desktop.
Save salarcode/da8ad2b993e67c602db88a62259d0456 to your computer and use it in GitHub Desktop.
MAUI Bluetooth Permission Declaration (for Android)
// IMPORTANT: Put this file in `Platforms/Android/` directory.
using Microsoft.Maui.ApplicationModel;
using System.Collections.Generic;
/// <summary>
/// MAUI Bluetooth Permission Decleration (for Android).
/// </summary>
/// <remarks>
/// IMPORTANT: Put this file in `Platforms/Android/` directory.
/// </remarks>
public partial class BluetoothPermissions : Permissions.BasePlatformPermission
{
private readonly bool _scan;
private readonly bool _advertise;
private readonly bool _connect;
private readonly bool _bluetoothLocation;
public BluetoothPermissions()
: this(true, false, true, false)
{
}
/// <summary>
///
/// </summary>
/// <param name="scan">Needed only if your app looks for Bluetooth devices.
/// If your app doesn't use Bluetooth scan results to derive physical location, you can make a strong assertion that your app never uses the Bluetooth permissions to derive physical location.
/// Add the `android:usesPermissionFlags` attribute to your BLUETOOTH_SCAN permission declaration, and set this attribute's value to `neverForLocation`.
/// </param>
/// <param name="advertise">Needed only if your app makes the device discoverable to Bluetooth devices.</param>
/// <param name="connect">Needed only if your app communicates with already-paired Bluetooth devices.</param>
/// <param name="bluetoothLocation">Needed only if your app uses Bluetooth scan results to derive physical location.</param>
/// <remarks>
/// https://developer.android.com/guide/topics/connectivity/bluetooth/permissions
/// </remarks>
public BluetoothPermissions(bool scan = true, bool advertise = true, bool connect = true, bool bluetoothLocation = true)
{
_scan = scan;
_advertise = advertise;
_connect = connect;
_bluetoothLocation = bluetoothLocation;
}
private (string androidPermission, bool isRuntime)[] _requiredPermissions;
public override (string androidPermission, bool isRuntime)[] RequiredPermissions
{
get
{
if (_requiredPermissions != null)
return _requiredPermissions;
var result = new List<(string androidPermission, bool isRuntime)>();
var sdk = (int)Android.OS.Build.VERSION.SdkInt;
if (sdk >= 31)
{
// If your app targets Android 12 (API level 31) or higher, declare the following permissions in your app's manifest file:
if (_scan)
result.Add((global::Android.Manifest.Permission.BluetoothScan, true));
if (_advertise)
result.Add((global::Android.Manifest.Permission.BluetoothAdvertise, true));
if (_connect)
result.Add((global::Android.Manifest.Permission.BluetoothConnect, true));
if (_bluetoothLocation)
result.Add((global::Android.Manifest.Permission.AccessFineLocation, true));
}
else
{
// If your app targets Android 11 (API level 30) or lower, declare the following permissions in your app's manifest file:
result.Add((global::Android.Manifest.Permission.Bluetooth, true));
if (sdk >= 29)
{
result.Add((global::Android.Manifest.Permission.AccessFineLocation, true));
}
else
{
// If your app targets Android 9 (API level 28) or lower, you can declare the ACCESS_COARSE_LOCATION permission instead of the ACCESS_FINE_LOCATION permission.
result.Add((global::Android.Manifest.Permission.AccessCoarseLocation, true));
}
if (_scan || _connect || _advertise)
{
result.Add((global::Android.Manifest.Permission.BluetoothAdmin, true));
if (sdk >= 29)
{
// If your app supports a service and can run on Android 10 (API level 29) or Android 11, you must also declare the ACCESS_BACKGROUND_LOCATION permission to discover Bluetooth devices.
result.Add((global::Android.Manifest.Permission.AccessBackgroundLocation, true));
}
}
}
_requiredPermissions = result.ToArray();
return _requiredPermissions;
}
}
}
/// <summary>
/// IMPORTANT: Put this file in root of Application
/// </summary>
public partial class BluetoothPermissions : Permissions.BasePlatformPermission
{
}
// How to use MAUI Bluetooth LE permissions
private async Task<bool> CheckBluetoothStatus()
{
try
{
var requestStatus = await new BluetoothPermissions().CheckStatusAsync();
return requestStatus == PermissionStatus.Granted;
}
catch (Exception ex)
{
// logger.LogError(ex);
return false;
}
}
public async Task<bool> RequestBluetoothAccess()
{
try
{
var requestStatus = await new BluetoothPermissions().RequestAsync();
return requestStatus == PermissionStatus.Granted;
}
catch (Exception ex)
{
// logger.LogError(ex);
return false;
}
}
@gfmoore
Copy link

gfmoore commented May 23, 2024

Hi, I'm sorry it's been a long time since I worked on this code that I cannot remember anything about it. Have a look at the stackoverflow post, it may help. Also Maui has had some major updates since I worked with it that things may have changed. I hope you figure it out because it was a right mess.
Gordon

@axa88
Copy link

axa88 commented May 23, 2024

Hello and thank you for this code. However, I don't understand the purpose of the BluetoothPermissions class at the root of Application. How do you make the link between BluetoothPermissions at the root of Application and BluetoothPermissions in Platforms.Android ? I have the impression that my programme doesn't pass into BluetoothPermissions in Plateforms.Android...

@ALEXJNX
I believe you need to make clear what you mean by root of Application I dont think it is proper terminology so it cant clearly explain what you are trying to say.
Anyway MAUI is cross platform, so some of this code is abstracted and some is platform specific, I advise you get familiar with that first which will make it more easy to understand here.

@ALEXJNX
Copy link

ALEXJNX commented May 23, 2024

Hello and thank you for this code. However, I don't understand the purpose of the BluetoothPermissions class at the root of Application. How do you make the link between BluetoothPermissions at the root of Application and BluetoothPermissions in Platforms.Android ? I have the impression that my programme doesn't pass into BluetoothPermissions in Plateforms.Android...

Ok, I Find answer here : https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/invoke-platform-code?view=net-maui-8.0#partial-classes-and-methods

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment