上一篇博客里面的代码,演示如何申请安卓的权限。
如何申请安卓的蓝牙权限?
本博客之前有一篇文章写过。
现在 Google 要求 Android API Level 必须是 33。对于 BLE 的权限申请,有了一些新的要求。
以下描述,基于 Delphi 11。
首先是用于安卓的 Project 在 Delphi IDE 里面的设置:
在 IDE 菜单:Project - Options - Uses Permissions - 里面:
然后是申请权限的代码:
unit UDmPermissions;
// 安卓的权限申请代码 Delphi 11
interface
uses
System.SysUtils, System.Types, System.Classes, System.Permissions, FMX.DialogService, System.UITypes;
type
TDmPermissions = class(TDataModule)
private
{ Private declarations }
FGotPermission: TNotifyEvent;
procedure DoGotPermissions;
private const
LOCATION_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;
var
DmPermissions: TDmPermissions;
implementation
{%CLASSGROUP 'FMX.Controls.TControl'}
{$R *.dfm}
{ TDmPermissions }
procedure TDmPermissions.DoGotPermissions;
begin
if Assigned(FGotPermission) then FGotPermission(Self);
end;
procedure TDmPermissions.GetAndroidBLEPermission;
var
Permissions: 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) then
Permissions := [LOCATION_PERMISSION, BLUETOOTH_SCAN_PERMISSION, BLUETOOTH_ADVERTISE_PERMISSION, BLUETOOTH_CONNECT_PERMISSION]
else
Permissions := [LOCATION_PERMISSION];
PermissionsService.RequestPermissions(Permissions,
procedure(const Permissions: TClassicStringDynArray; const GrantResults: TClassicPermissionStatusDynArray)
begin
if ((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)) then
begin
Self.DoGotPermissions;
end
else
begin
TDialogService.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 开始扫描外部设备。