毛伊蓝牙LE -运行时权限检查和设置在Android设备上



既然微软已经决定蓝牙(显然还有Wi-fi)不值得出现在他们的毛伊岛路线图上,我想我们必须自己做:叹息。https://github.com/dotnet/maui/discussions/277见David Ortinau评论

我承认,即使从1977年开始用PDP-8上的纸带编程,我也在努力为我的代码找到合适的结构,甚至理解它是如何工作的,所以如果我犯了错误,请原谅我,并请随时把我放在正确的轨道上。

因为这将有利于未来的新手-欢呼!我将尽可能详细地说明。

我有一个Maui应用程序,它有一个shell弹出菜单和一些ViewModels我正在使用CommunityToolkit。Mvvm(通过NuGet)使我的编码生活更容易绑定。

文件夹结构是Pages>BluetoothPage。xaml文件及其后面的相应代码BluetoothPage.xaml.cs和其他页面。有一个模型文件夹的类,其中包含一个bluetoothperiphers .cs类,它持有类的属性,我需要记住外设,我已经连接到一个ViewModels文件夹中,我有一个BluetoothPeripheralsViewModel.cs这是用于绑定到我的BluetoothPage。

当我开始时,我可以从shell中选择Bluetooth并进入BluetoothPage。在这个文件后面的代码中,我开始了我的工作。

我设法使用插件。可以开始,但是当我想扫描时,我立即得到了Android上的问题(从版本23 (Marshamallow?)),应用程序需要提示用户接受使用蓝牙的许可。

我还将以下行添加到Platforms>Android>Resources>AndroidManifest.xml文件


<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" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
</manifest>

这是我的基本代码和注释-(我猜有一个更复杂的方法来做到这一点,但现在这是我的大脑可以处理的。)

bluetoothpage . example .cs -后台代码

//other imports are in a GlobalUsing.cs file
using Android;
using Android.OS;
namespace TSDZ2Monitor.Pages;
public partial class BluetoothPage : ContentPage
{
public BluetoothPage()
{
InitializeComponent();
*//so I start my code here, but I suspect that I should be using some kind of page displayed, on startup event?*
Console.WriteLine("Bluetooth here");
getBLEPermission();
startScan();

*//Need to get user to accept bluetooth permissions in Android 6.0+,v23 that is the Run-time Permissions check - should this be in the constructor?*
async void getBLEPermission()
{
bool blePermissionGranted = false;
int sdk = (int)Build.VERSION.SdkInt; //<-- if you want to check > 23

//Do the check to see if permission already granted - how?

if (!blePermissionGranted)  //so go and get permission, display an alert
{  
blePermissionGranted = await App.Current.MainPage.DisplayAlert("Alert", "Allow use of bluetooth for scanning for your peripheral devices such as heart rate monitor etc?", "Allow", "Deny");
if (blePermissionGranted)
{
//Set the permission on android - how
}
//Console.WriteLine($"SDK version {sdk}");
//Console.WriteLine($"BLE permission granted: {blePermissionGranted}");
}
}
async void startScan()
{
//TODO 
}
}
}

Q1如何测试是否设置了蓝牙权限?

如果不是,我如何设置它?

非常感谢您的建议等。

编辑(添加):所以我已经弄清楚了如何使用。net Maui提供的权限。下面是在文档中使用位置的示例https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/appmodel/permissions?tabs=android

//using InTheHand.Bluetooth;
namespace TSDZ2Monitor.Pages;
public partial class BluetoothPage : ContentPage
{
public BluetoothPage()
{
InitializeComponent();
Console.WriteLine("Bluetooth here");
getBLEPermission();
static async void getBLEPermission()
{
PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
if (status != PermissionStatus.Granted)
{
status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
if (status != PermissionStatus.Granted)
{
//well kill the app because it's no use if bluetooth not enabled
}
}
}

}
}

注意,我不需要做一个提醒,Android为我做了。

当然蓝牙权限不是这个场景的一部分。加上这个能有多难?如果您是MS,请这样做。

有什么想法吗?

有关可行的解决方案,请参阅此处的讨论https://github.com/dotnet/maui/discussions/277

和完整的代码解决方案在这里https://gist.github.com/salarcode/da8ad2b993e67c602db88a62259d0456 gistcomment - 4197943

我非常感谢所有做出贡献的人,尤其是github上的salarcode。欢呼。

(我把它留给别人来标记答案:))

您注意到的权限需要在信息中输入。列表和应用清单。然后根据https://learn.microsoft.com/en-us/xamarin/essentials/permissions?context=xamarin%2Fandroid&tabs=android

检查它们的授予或未授予状态。BLE在Shiny的预览内核正在Maui为macatalyst, iOS和Android工作https://shinylib.net/mobile/ble/index.html

我现在刚开始使用BLE和MAUI应用程序开发,然后我通过使用我的手机作为VS2022 v17.4.3中的Android模拟器测试了该应用程序。这款手机是OPPO A72型号CPH2067_11 (Android 11, API级别30),带有Polar H10带。

在第一次尝试让所有的东西工作后,我已经添加ACCESS_BACKGROUND_LOCATION到Platforms->Android->AndroidManifest.xml文件如下:

<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<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" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

,我也改变了BluetoothLEPermissions.cs代码如下(通过简单的注释和取消注释一些行):

namespace MauiXAMLBluetoothLE;
public class BluetoothLEPermissions : Permissions.BasePlatformPermission
{
public override (string androidPermission, bool isRuntime)[] RequiredPermissions
{
get
{
return new List<(string androidPermission, bool isRuntime)>
{
(Android.Manifest.Permission.Bluetooth, true),
(Android.Manifest.Permission.BluetoothAdmin, true),
//(Android.Manifest.Permission.BluetoothScan, true),
//(Android.Manifest.Permission.BluetoothConnect, true),
(Android.Manifest.Permission.AccessFineLocation, true),
//(Android.Manifest.Permission.AccessCoarseLocation, true),
(Android.Manifest.Permission.AccessBackgroundLocation, true),
}.ToArray();
}
}    
}

如果这对其他人有用的话。

谢谢!