【问题标题】:Delphi Android API level 28 on Android Pie - How to obtain Foreground Service Permission?Android Pie 上的 Delphi Android API 级别 28 - 如何获得前台服务权限?
【发布时间】:2019-10-19 19:23:23
【问题描述】:

我正在使用 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 发布时得到解决。任何人都可以确认这一点,或提供 cmets 或解决方案。谢谢。

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 权限(在运行时)。

附录

【问题讨论】:

  • 您可以选择包含 AAR Android 库吗?我正在考虑创建和清空 AAR,只需要声明缺少 uses-permission 标记的清单。
  • @DaveNottage 我添加了 2 个屏幕截图,以证明我已经在 IDE 中设置了必要的使用权限,并且这向 AndroidManifest.xml 添加了使用权限。并且 targetSDKVersion 设置为“28”。
  • 您实际上是在为服务调用 startForeground 吗?例如,请参阅此处的 TServiceModule.StartForeground 方法:github.com/DelphiWorlds/KastriFree/blob/master/Demos/…
  • @DaveNottage 太多代码“在 10.2.3 中运行良好的应用程序”。该应用程序最初在柏林 (10.1) 下编码,随后升级到东京 (10.2)。这是一个广泛的应用程序,现已投入生产使用超过 2 年 - 并在十几种不同的手机型号上运行 - 并且其中包含超过 10,000 行代码。我在这里想做的只是针对更高的 API。您错过了我说“Androidapi.JNI.Os 中没有我需要的常量”和代码中的 //

标签: android delphi


【解决方案1】:

我将问题追溯到我的服务中的不兼容(使用 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;

【讨论】:

  • 请输入整个单元代码。对我来说,在 API 级别 26 的 Rio 10.3.3 中不工作。
  • 您缺少哪一部分?
猜你喜欢
  • 2019-02-28
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-16
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
相关资源
最近更新 更多