I have written a xamarin forms app which uses the Plugin.BLE NuGet package to scan and connect to ble devices. It was working/debugging flawlessly on my phone until it(my phone) updated to Android 12.0 - API 31. I am using the basic vanilla implementation from the plugin:
adapter.DeviceDiscovered += (s,a) => deviceList.Add(a.Device);
await adapter.StartScanningForDevicesAsync();
I have found that Android 12 requires different runtime permissions ([https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#declare-android11-or-lower][1]) and I have tried to accomodate them in the manifest file:
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
<application android:label="Rep_001.Android" android:theme="@style/MainTheme"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#declare-android11-or-lower
but alas I am having no luck. I am thinking that I need to ask the user for scan and connect privileges at runtime but I am not sure how to do that as Xamarin.Essentials does not have bluetooth permissions requests.
Well, I figured it out. Within the Android Project, I created a class that inherits from Xamarin.Essentials.Permissions.BasePlatformPermission:
public class BLEPermission : Xamarin.Essentials.Permissions.BasePlatformPermission
{
public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
{
(Android.Manifest.Permission.BluetoothScan, true),
(Android.Manifest.Permission.BluetoothConnect, true)
}.ToArray();
}
Then within MainActivity.cs -> OnCreate() I inserted the RequestAsync immediately after the Application is loaded:
protected override async void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
await Permissions.RequestAsync<BLEPermission>();
}
Now when the app loads for the first time it asks the user for bluetooth scanning an connecting permissions. All subsequent launches do not re-prompt for permissions. Sites/Documentation that helped along the way
https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#declare-android11-or-lower
https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/permissions?tabs=windows
The BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECT, and BLUETOOTH_SCAN permissions are runtime permissions.
Therefore, you must explicitly request user approval in your app before you can look for Bluetooth devices, make a device discoverable to other devices, or communicate with already-paired Bluetooth devices.
When your app requests at least one of these permissions, the system prompts the user to allow your app to access Nearby devices.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With