如何检查我的应用程序 ios 在 Xamarin.ios 中是否具有蓝牙权限?

Kik*_*nye 1 xamarin.ios core-bluetooth bluetooth-lowenergy xamarin xamarin.forms

我需要检查我的Xamarin.Forms应用程序是否具有蓝牙权限,如果没有,我想请求它。我已经能够将其实现为 Android 的依赖服务,但我不知道如何为 iOS 执行此操作。我已经看到一些文章提到了在 ios 13 与早期版本上的工作方式之间的一些差异,但他们还不是很清楚。

我尝试使用以下代码在运行 ios 12.2 的 iPhone 6s 上进行检查和测试:

var manager = new CBCentralManager();
return (CBCentralManager.Authorization) == CBManagerAuthorization.AllowedAlways;
Run Code Online (Sandbox Code Playgroud)

但它抛出一个MonoTouchException. 如何检查权限以及如何请求权限?以及如何处理不同版本ios的需求?(早在ios 11)。

Ran*_*jit 5

Apple从 iOS 13引入了蓝牙权限。

因此,您无需为 iOS 12 及更低版本请求或检查蓝牙权限。

要启用蓝牙,必须在 plist 文件中添加两个密钥。隐私 — 蓝牙外设使用说明和隐私 — 蓝牙始终使用说明。描述您希望在应用程序中使用蓝牙的原因。

Xamarin.Forms 共享 PCL 代码

依赖服务接口

public interface IPermissionService
{
    bool HasBluetoothPermission();
    void RequestBluetoothPermission(Action bluetoothAction);
}

Run Code Online (Sandbox Code Playgroud)

用于检查状态和请求蓝牙权限的 UI 页面

<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="StackQA2XF.BluetoothPermissionPage">
    <ContentPage.Content>
        <StackLayout Orientation="Vertical" Spacing="50" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
            <StackLayout Orientation="Horizontal" HeightRequest="60" >
                <Button Text="Has Bluetooth Permission" Clicked="HasBluetooth_Clicked" />
                <Label x:Name="LabelHasPermission" VerticalOptions="Center" FontSize="Micro" Margin="10,0,0,0" TextColor="OrangeRed" Text="No" />
            </StackLayout>
            <Button Text="Request Bluetooth Permission" Clicked="RequestBluetooth_Clicked"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
Run Code Online (Sandbox Code Playgroud)
public partial class BluetoothPermissionPage : ContentPage
{
    readonly IPermissionService service;

    public BluetoothPermissionPage()
    {
        InitializeComponent();
        service = DependencyService.Get<IPermissionService>();
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();
        CheckBluetooothPermission();
    }

    void HasBluetooth_Clicked(System.Object sender, System.EventArgs e)
    {
        CheckBluetooothPermission();
    }

    private void CheckBluetooothPermission()
    {
        LabelHasPermission.Text = service.HasBluetoothPermission() ? "YES" : "NO";
    }

    void RequestBluetooth_Clicked(System.Object sender, System.EventArgs e)
    {
        service.RequestBluetoothPermission(() =>
        {
            CheckBluetooothPermission();
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

iOS平台端(本机代码)

依赖服务实现。

[assembly: Dependency(typeof(StackQA2XF.iOS.Service.PermissionService))]
namespace StackQA2XF.iOS.Service
{
    public class PermissionService : IPermissionService
    {
        Action? _bluetoothAction = null; //Optional, if you wanted to notify user that you have performed action (allow or deny) on the permission request dialog

        public bool HasBluetoothPermission()
        {
            if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
            {
                return CBCentralManager.Authorization == CBManagerAuthorization.AllowedAlways;
            }
            else
            {
                return true;
            }
        }

        public void RequestBluetoothPermission(Action bluetoothAction)
        {
            _bluetoothAction = bluetoothAction;
            var myDelegate = new PermissionCBCentralManager(this);
            var centralManger = new CBCentralManager(myDelegate, DispatchQueue.MainQueue, new CBCentralInitOptions() { ShowPowerAlert = false });
        }

        internal void CurrentUpdatedState(CBCentralManager central)
        {
            _bluetoothAction?.Invoke();
        }
    }

    public class PermissionCBCentralManager : CBCentralManagerDelegate
    {
        PermissionService permissionService = null;

        public PermissionCBCentralManager(PermissionService controller)
        {
            permissionService = controller;
        }

        public override void UpdatedState(CBCentralManager central)
        {
            permissionService.CurrentUpdatedState(central);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Info.plist

在此处输入图片说明

为了向后支持旧的 iOS 版本,需要在 info.plist 中定义 NSBluetoothPeripheralUsageDescription

注意:如果CBCentralManager.ShowPowerAlert is true,当用户的蓝牙设置为关闭时,将导致在设备的蓝牙设置中显示打开的系统对话框。IE。CBCentralManager.ShowPowerAlert is true如果蓝牙权限关闭或您的应用程序和蓝牙功能在您的 iPhone 中关闭,将产生两个对话框。

ShowPowerAlert is false,将不显示此系统对话框。

不要使用模拟器来检查这个实现。

权限请求对话框将出现在 iOS 13 及更高版本中。

在 iOS 中,权限请求对话框将只显示一次。因此,只有在第一次安装后,您才能在单击“请求蓝牙权限”时看到蓝牙权限请求对话框。一旦您拒绝,稍后第二次单击“请求蓝牙权限”按钮时,将不会显示权限请求对话框。您可以通过显示带有按钮的自定义对话框导航到应用程序的设置来处理这些场景。

请使用此测试应用程序作为您的参考LINK

在此处输入图片说明