Delphi FMX Android,复制文件,RequestPermissions问题

问题描述 投票:0回答:1

我有一个用 Delphi 12 FMX for Android 编写的应用程序。我想将文件从 '/storage/emulated/0/Documents/calorie_conspiration.db' 复制到 '/data/user/0/com.embarcadero.CC/files/calorie_conspiration.db'。 我的代码如下:

procedure TfrmMain.CopyDB(direction2download: Boolean);
var
  f1, f2: String;
const

  permRead = 'android.permission.READ_EXTERNAL_STORAGE';
  permWrite = 'android.permission.WRITE_EXTERNAL_STORAGE';
begin
{$IFDEF ANDROID}
  PermissionsService.RequestPermissions([permRead, permWrite],
    procedure(const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray)
    begin
      if (Length(AGrantResults) = 2) and (AGrantResults[0] = TPermissionStatus.Granted) and (AGrantResults[1] = TPermissionStatus.Granted) then
      begin
        dmCC.FDConnection.Connected := False;
        f1 := TPath.Combine(TPath.GetDocumentsPath, 'calorie_consumption.db');
        f2 := TPath.Combine(TPath.GetSharedDocumentsPath, 'calorie_consumption.db');
        if direction2download then
        begin
          TFile.Copy(f2, f1, True);
          memSQLTest.Lines.Add(f2 + ' -> ' + f1);
        end else
        begin
          TFile.Copy(f1, f2, True);
          memSQLTest.Lines.Add(f1 + ' -> ' + f2);
        end;
        dmCC.FDConnection.Connected := True;
      end else
      begin
       TDialogService.ShowMessage('Permission not granted!');
      end;
    end);
 {$ENDIF}
end;

在“使用权限”中,我将 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 设置为 True。

我的AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.embarcadero.CC"
    android:versionCode="1"
    android:versionName="1.0.1"
    android:installLocation="auto">
    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="34" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>
    <queries>

    </queries>
    <application
        android:persistent="False"
        android:restoreAnyVersion="False"
        android:label="CC"
        android:debuggable="true"
        android:largeHeap="False"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/AppTheme"
        android:hardwareAccelerated="true"
        android:resizeableActivity="true"
        android:requestLegacyExternalStorage="true">


<meta-data android:name="com.google.android.gms.version" android:value="12451000" />

        <!-- Trigger Google Play services to install the backported photo picker module. -->
        <service
            android:name="com.google.android.gms.metadata.ModuleDependencies"
            android:enabled="false"
            android:exported="false"
            tools:ignore="MissingClass">
            <intent-filter>
                <action android:name="com.google.android.gms.metadata.MODULE_DEPENDENCIES" />
            </intent-filter>

            <meta-data android:name="photopicker_activity:0:required" android:value="" />
        </service>

        <!-- Our activity is a subclass of the built-in NativeActivity framework class.
             This will take care of integrating with our NDK code. -->
        <activity
            android:name="com.embarcadero.firemonkey.FMXNativeActivity"
            android:exported="true"
            android:label="CC"
            android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|uiMode"
            android:launchMode="singleTask">
            <!-- Tell NativeActivity the name of our .so -->
            <meta-data android:name="android.app.lib_name" android:value="CC" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name="com.embarcadero.rtl.notifications.NotificationAlarm" />

    </application>
</manifest>
<!-- END_INCLUDE(manifest) -->

当我尝试执行代码时,它不会请求许可,但会出现错误: Project CC.apk 引发异常类 EFCreateError 并显示消息“无法创建文件“/storage/emulated/0/Documents/calorie_conspiration.db”。权限被拒绝'。

我已经尝试了所有可能的选项,包括 TMobilePermissions 组件,但它不起作用。

任何人都可以帮助我并指出我正确的方向吗?

android delphi firemonkey
1个回答
0
投票

我设法通过从 TPath.GetPublicPath, 'Documents/calorie_conspiration.db 而不是从 TPath.GetSharedDocumentsPath, 'calorie_conspiration.db 复制文件来解决这个问题。这似乎无需分配任何权限即可工作。

procedure TfrmMain.CopyDB(direction2download: Boolean);
var
  f1, f2: String;
begin
{$IFDEF ANDROID}
  try
    f1 := TPath.Combine(TPath.GetDocumentsPath, 'calorie_consumption.db');
    f2 := TPath.Combine(TPath.GetPublicPath, 'Documents/calorie_consumption.db');
         
    dmCC.FDConnection.Connected := False;
    if direction2download then
    begin
      TFile.Copy(f2, f1, True);
      memSQLTest.Lines.Add(f2 + ' -> ' + f1);
     end else
     begin
       TFile.Copy(f1, f2, True);
       memSQLTest.Lines.Add(f1 + ' -> ' + f2);
      end;
      dmCC.FDConnection.Connected := True;
  except
    on E: Exception do
      TDialogService.ShowMessage('Error: ' + E.Message);
  end;
{$ENDIF}
end;
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.