我正在使用Delphi 10.3.2 build 6593来编译在10.2.3 build 2631中可以正常运行的应用程序。它具有自己的服务。由于SDK API级别现在为28,因此我必须专门为所需的权限编写代码,但是我不知道如何请求ForeGroundService权限。
在此问题上,我找不到任何与Android Java文档相关的信息。这是Android的特定Delphi实现。
Androidapi.JNI.Os
中缺少我需要的常数。结果,Android Pie手机会报告
未授予前台服务权限
我将想象Embarcadero有一些工作要做,并且这个问题将在10.3.3版发布时得到解决。任何人都可以确认这一点,或者提供评论或解决方案。谢谢。
private
FPermittoVibrate: Boolean;
FVibratePermission: String;
FPermitAccessFineLocation: Boolean;
FAccessFineLocation: String;
FPermitNetworkState: Boolean;
FNetworkStatePermission: String;
FPermitWifiState: Boolean;
FWifiStatePermission: String;
FPermitPhoneState: Boolean;
FPhoneStatePermission: String;
FPermitForeGroundService: Boolean;
FForegroundServicePermission: String;
procedure TfrmTabbed.FormCreate(Sender: TObject);
begin
FPermittoVibrate := False;
FVibratePermission := JStringToString(TJManifest_permission.JavaClass.VIBRATE);
FPermitAccessFineLocation := False;
FAccessFineLocation := JStringToString(TJManifest_permission.JavaClass.ACCESS_FINE_LOCATION);
FPermitNetworkState := False;
FNetworkStatePermission := JStringToString(TJManifest_permission.JavaClass.ACCESS_NETWORK_STATE);
FPermitWifistate := False;
FWifiStatePermission := JStringToString(TJManifest_permission.JavaClass.ACCESS_WIFI_STATE);
FPermitPhoneState := False;
FPhoneStatePermission := JStringToString(TJManifest_permission.JavaClass.READ_PHONE_STATE);
FPermitForeGroundService := False;
FForegroundServicePermission := JStringToString(TJManifest_permission.JavaClass.??? // <====
procedure TfrmTabbed.FormShow(Sender: TObject);
begin
PermissionsService.RequestPermissions([
FVibratePermission
, FAccessFineLocation
, FNetworkStatePermission
, FWifiStatePermission
, FPhoneStatePermission
, FForeGroundServicePermission
],
PermissionResult, PermissionRequest
);
procedure TfrmTabbed.PermissionResult(Sender: TObject;
const APermissions: TArray<string>;
const AGrantResults: TArray<TPermissionStatus>);
var
Permission: String;
i: Integer;
begin
for i := 0 to High(APermissions) do
begin
Permission := APermissions[i];
if Permission = FVibratePermission then
FPermitToVibrate := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FAccessFineLocation then
FPermitAccessFineLocation := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FNetworkStatePermission then
FPermitNetworkState := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FWifiStatepermission then
FPermitWifiState := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FPhoneStatePermission then
FPermitPhoneState := AGrantResults[i] = TPermissionStatus.Granted
else if Permission = FForeGroundServicePermission then
FPermitForeGroundService := AGrantResults[i] = TPermissionStatus.Granted
;
end;
if FPermitForeGroundService then
// START(ing)_NOT_STICKY
StartService;
如果您想知道,我使用此代码确实授予了我请求的其他权限,所以没关系。只是(在运行时)未授予ForegroundService权限。
附录
答案 0 :(得分:0)
我在服务中找到了与我的不兼容(使用API 28)通知代码有关的问题。因此,因为该服务未启动,所以未授予FOREGROUND SERVICE权限。作为记录,这是我的修改代码,对于API 28,该代码包括打开通道的代码。我希望有人觉得这有用。
function TMainService.AndroidServiceStartCommand(const Sender: TObject;
const Intent: JIntent; Flags, StartId: Integer): Integer;
var
ServiceChannel: JNotificationChannel;
NotificationManager: JNotificationManager;
Obj: JObject;
NewIntent: JIntent;
ncb: JNotificationCompat_Builder;
ntf: JNotification;
PendingIntent: JPendingIntent;
begin
Result := TJService.JavaClass.START_NOT_STICKY;
if TJBuild_VERSION.JavaClass.SDK_INT > TJBuild_VERSION_CODES.JavaClass.O then
begin
// 28 > 26
ServiceChannel := TJNotificationChannel.JavaClass.init(
StringtoJString(CHANNEL_ID),
StrToJCharSequence('MyApp Service Channel'),
TJNotificationManager.JavaClass.IMPORTANCE_DEFAULT
);
Obj := TAndroidHelper.Context.getSystemService(
TJContext.JavaClass.NOTIFICATION_SERVICE);
NotificationManager := TJNotificationManager.Wrap(Obj);
NotificationManager.createNotificationChannel(ServiceChannel);
PendingIntent := TJPendingIntent.JavaClass.getActivity(
JavaService.getApplicationContext, 0, Intent, 0
);
ncb := TJNotificationCompat_Builder.JavaClass.init(
TAndroidHelper.Context,
StringToJString(CHANNEL_ID)
);
ncb.setContentTitle(StrToJCharSequence('MyApp Service'));
// ncb.setTicker(StrToJCharSequence('Communications Service'));
ncb.setSmallIcon(JavaService.getApplicationInfo.icon);
ncb.setContentIntent(PendingIntent);
ncb.setOngoing(True);
ntf := ncb.build;
end
else
begin
// earlier notification code (worked under 10.2.3, targetting API 14)
PendingIntent := TJPendingIntent.JavaClass.getActivity(
JavaService.getApplicationContext, 0, Intent, 0
);
ntf := TJNotification.Create;
ntf.icon := JavaService.getApplicationInfo.icon;
ntf.setLatestEventInfo(
JavaService.getApplicationContext,
StrToJCharSequence('MyApp Service'),
StrToJCharSequence('Communications Service'), PendingIntent);
end;
JavaService.startForeground(StartId, ntf);
end;