上一篇博客里面的代码,演示如何申请安卓的权限。
如何申请安卓的蓝牙权限?
本博客之前有一篇文章写过。
现在 Google 要求 Android API Level 必须是 33。对于 BLE 的权限申请,有了一些新的要求。
以下描述,基于 Delphi 11。
首先是用于安卓的 Project 在 Delphi IDE 里面的设置:
在 IDE 菜单:Project - Options - Uses Permissions - 里面:
然后是申请权限的代码:
unit UDmPermissions;
// 安卓的权限申请代码 Delphi 11
interfaceusesSystem.SysUtils, System.Types, System.Classes, System.Permissions, FMX.DialogService, System.UITypes;typeTDmPermissions = class(TDataModule)private{ Private declarations }FGotPermission: TNotifyEvent;procedure DoGotPermissions;private constLOCATION_PERMISSION = 'android.permission.ACCESS_FINE_LOCATION';BLUETOOTH_SCAN_PERMISSION = 'android.permission.BLUETOOTH_SCAN';BLUETOOTH_ADVERTISE_PERMISSION = 'android.permission.BLUETOOTH_ADVERTISE';BLUETOOTH_CONNECT_PERMISSION = 'android.permission.BLUETOOTH_CONNECT';public{ Public declarations }procedure GetAndroidBLEPermission;property OnGotPermissions: TNotifyEvent read FGotPermission write FGotPermission;end;varDmPermissions: TDmPermissions;implementation{%CLASSGROUP 'FMX.Controls.TControl'}{$R *.dfm}{ TDmPermissions }procedure TDmPermissions.DoGotPermissions;
beginif Assigned(FGotPermission) then FGotPermission(Self);
end;procedure TDmPermissions.GetAndroidBLEPermission;
varPermissions: TArray<string>;
begin
{------------------------------------------------------------------------安卓的蓝牙权限申请在 IDE 菜单:Project - Options - Uses Permissions -1. BlueTooth Admin: 不用选择,也能打开蓝牙扫描;2. BLUETOOTH SCAN;BLUETOOTH CONNECT 必须勾选;4. BLUETOOTH ADVERTISE 如果没有勾选,下面的代码里面 Permissions 包含了 BLUETOOTH_ADVERTISE_PERMISSION会导致 Length(GrantResults) = 4 而第三项 GrantResults[2] = TPermissionStatus.Granted 不能通过;但是,并不影响打开蓝牙扫描。因此,这里如果仅仅是使用蓝牙扫描,可以不需要这一项目。也就是说 Permissions 里面可以只有 3 项。
------------------------------------------------------------------------}if TOSVersion.Check(12) thenPermissions := [LOCATION_PERMISSION, BLUETOOTH_SCAN_PERMISSION, BLUETOOTH_ADVERTISE_PERMISSION, BLUETOOTH_CONNECT_PERMISSION]elsePermissions := [LOCATION_PERMISSION];PermissionsService.RequestPermissions(Permissions,procedure(const Permissions: TClassicStringDynArray; const GrantResults: TClassicPermissionStatusDynArray)beginif ((Length(GrantResults) = 4) and (GrantResults[0] = TPermissionStatus.Granted)and (GrantResults[1] = TPermissionStatus.Granted)and (GrantResults[2] = TPermissionStatus.Granted)and (GrantResults[3] = TPermissionStatus.Granted)) or((Length(GrantResults) = 1) and (GrantResults[0] = TPermissionStatus.Granted)) thenbeginSelf.DoGotPermissions;endelsebeginTDialogService.ShowMessage('Cannot start BLE scan as the permission has not been granted; 没有获得权限');end;end);
end;end.
一点说明:
上面的代码里面,申请了 4 个权限。如果是低版本的安卓,只需要申请一个,也就是 LOCATION_PERMISSION。
高版本的安卓系统,这里申请了 4 个。
实验证明,如果程序需要扫描外面的蓝牙设备,只需要3个,不需要上面代码里面的 BLUETOOTH_ADVERTISE;
实验证明,如果代码里面包含了 BLUETOOTH_ADVERTISE,但是在 IDE 的 Uses Permissions 里面,没有勾选 Bluetooth advertise,会导致上述代码里面的:
GrantResults[2] = TPermissionStatus.Granted
上述代码会返回 False 导致程序认为权限申请失败。但并不影响程序打开 BLE 开始扫描外部设备。