Delphi Android API level 28 на Android Pie - Как получить разрешение на обслуживание переднего плана? - PullRequest
0 голосов
/ 19 октября 2019

Я использую Delphi 10.3.2 build 6593 для компиляции приложения, которое отлично работает в 10.2.3 build 2631. У него есть собственный сервис. Поскольку уровень API SDK теперь равен 28, я должен специально кодировать необходимые мне разрешения, но я не знаю, как запросить разрешение ForeGroundService.

Здесь нет корреляции с какой-либо документацией по Android Java, которую я мог найти по этой проблеме. Это конкретная реализация Delphi для Android.

Необходимая мне константа отсутствует в Androidapi.JNI.Os. В результате телефон Android Pie сообщает

Разрешение службы Foreground Service не было предоставлено

Я собираюсь представить, что 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 голосов
/ 24 октября 2019

Я отследил проблему до своего несовместимого (с 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...