Android Pie上的Delphi Android API级别28-如何获取前景服务许可?

时间:2019-10-19 19:23:23

标签: android delphi

我正在使用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权限。

附录

enter image description here

enter image description here

1 个答案:

答案 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;