android - 在 Delphi 10.3 Rio 中写入外部 SD 卡

标签 android delphi delphi-10.3-rio

我编写了一个照片应用程序,可将图像从外部源流式传输到我在平板电脑 (Samsung Galaxy TAB S) 上的应用程序。我决定使用平板电脑的外置 SD 卡作为存储空间,因为内部存储空间经常用完。另外,我需要删除它以备份所有图像。

“读取”JPG 一切正常,但是当涉及到从流中“写入”JPG 到 SD 卡时,权限被拒绝。

我已经设置了WRITE_EXTERNAL_STORAGE 权限,但这不适用于 Android SDK 25.2.5,因为 Android 改变了外部访问权限的工作方式。

fWriteStorage:=JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE);

PermissionsService.RequestPermissions([fReadStorage, fWriteStorage], DisplayRationale);

我想要做的是调用 Android 系统文件夹选择器对话框以允许应用程序访问 SD 卡。如此处所述:SD Card on Android 5.0 and Later .

有谁知道如何在 Delphi 10.3 Rio 中调用 SD 卡的权限选择器?类似于所有应用程序,包括 TotalCommander for Android,需要对外部 SD 卡的写入权限。

我现在再次尝试,使用以下代码,但仍然没有成功。我需要为图库创建新文件夹,但无法创建文件夹。

  fWriteStorage := JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE);
  if PermissionsService.IsPermissionGranted(fWriteStorage) then
  begin
    applog('IsPermissionGranted: TRUE');
    if ForceDirectories(System.IOUtils.TPath.Combine(GLOBAL_SDCARD, 'FoxyTab/Storage')) then
      AppLog('GLOBAL_SDCARD Created')
    else
      AppLog('Can not create SD CARD folder ' + System.IOUtils.TPath.Combine(GLOBAL_SDCARD, 'FoxyTab/Storage'));
      PermissionsService.RequestPermissions([fWriteStorage],
    procedure(const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>)
    begin
      if (Length(AGrantResults) = 1) and (AGrantResults[0] = TPermissionStatus.Granted) then
      begin
        AppLog('Access Granted');
        if ForceDirectories(System.IOUtils.TPath.Combine(GLOBAL_SDCARD, 'FoxyTab/Storage')) then
          AppLog('GLOBAL_SDCARD Created')
        else
          AppLog('Can not create SD CARD folder ' + System.IOUtils.TPath.Combine(GLOBAL_SDCARD, 'FoxyTab/Storage'));

      end
      else
      begin
        AppLog('Access Denied');
      end;
    end);

我总是得到“已授予访问权限”,但无法创建文件夹。

SD 卡不是平板电脑内置的,而是“可移动”microSD 卡,因为当图库已满时我需要将其移除以备份到另一台设备 (PC/MAC)。卡的路径是/storage/2266-7298/。与使用标准目录返回的内容不同。

最佳答案

您无需调用系统对话框即可获得访问权限。

使用 PermissionsService.RequestPermissions() 时,您实际上需要等待 Android 回复授予或拒绝状态,然后您才能尝试执行您请求权限的操作。

在您显示的代码中,您没有将回调函数传递给 RequestPermissions() 以获取回复。因此,在您向 SD 卡写入文件之前,您不知道用户是否真的授予了访问权限。

你需要更多这样的东西:

fWriteStorage := JStringToString(TJManifest_permission.JavaClass.WRITE_EXTERNAL_STORAGE);

...

if PermissionsService.IsPermissionGranted(fWriteStorage) then
begin
  // access previously granted, write files...
end
else
begin
  PermissionsService.RequestPermissions([fWriteStorage],
    procedure(const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>)
    begin
      if (Length(AGrantResults) = 1) and (AGrantResults[0] = TPermissionStatus.Granted) then
      begin
        // access granted, write files...
      end
      else
      begin
        // access denied, can't write files...
      end;
    end,
    DisplayRationale);
  end;
end;

请注意,如果您使用 Android 的 Context.getExternalFilesDir()函数(由 Delphi 的 System.IOUtils.TPath.GetSharedDocumentsPath() 方法包装),如果您正在写入属于您的应用程序包的文件夹,您实际上不需要 WRITE_EXTERNAL_STORAGE 权限来写入 SD 卡:

Starting in Build.VERSION_CODES.KITKAT, no permissions are required to read or write to the returned path; it's always accessible to the calling app. This only applies to paths generated for package name of the calling application. To access paths belonging to other packages, Manifest.permission.WRITE_EXTERNAL_STORAGE and/or Manifest.permission.READ_EXTERNAL_STORAGE are required.

像 TotalCommander 这样的应用程序会访问其他应用程序的文件,这就是它需要 (READ|WRITE)_EXTERNAL_STORAGE 的原因。如果您的应用只是为了自己使用而读/写自己的文件,则可能不会。

关于android - 在 Delphi 10.3 Rio 中写入外部 SD 卡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57599543/

相关文章:

delphi - 如何在 Delphi 中调试从 DLL 调用的 DLL

regex - 使用正则表达式从源代码中提取逗号分隔的单元

delphi - 在 Delphi 中按比例调整面板组件的大小

delphi - 如何在 Delphi COM 服务器应用程序中从 Getref 获取的指针调用 VBscript 函数

Android Eclipse 卡在启动委托(delegate)调试 session 的进度为 27%

delphi - W1000 符号 'StrLComp' 已弃用 : 'Moved to the AnsiStrings unit'

delphi - 修复Delphi中表单中的方法声明中的错误

Android Parent and Child Activity onCreate问题

android - 为什么 FusedLocationProviderApi 从不报告精度优于 10m?这有记录吗?

android - 无法设置约束组的可见性