当我尝试在 Android 11 中读取文件时出现电容器文件系统错误

Posted

技术标签:

【中文标题】当我尝试在 Android 11 中读取文件时出现电容器文件系统错误【英文标题】:Capacitor Filesystem error when I try to read a file in Android 11 【发布时间】:2021-09-01 12:25:54 【问题描述】:

我尝试使用函数readFile of capacitor filesystem 在我的模拟器中读取文件。我尝试操作的文件位于模拟器的下载文件夹中,该函数返回此错误:

错误:文件不存在

我也尝试使用copy 函数,将此文件复制到我可以操作它的目录,但此函数返回此错误:

错误:源对象不存在

我还在应用程序中进行了权限测试,我得到了granted

我在网上搜索了这个错误,但没有成功。此外,我在文件系统服务的功能上使用了 Directory 的所有参数,但所有选项都返回相同的错误。使用相同的参数可以访问 android 10 中的文件系统。

所有测试均在具有 Android 11 (API30) 的模拟器 Pixel 4 中进行。

在android.xml的标签application里面,我加了android:requestLegacyExternalStorage="true",在user-permissions里面:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

homePage.ts

带副本

// file_dir_path = file:///storage/emulated/0/Download/
// file_name = file.kml
// path = 'MyApp/project' + this.projectId + '/temp'
return this.filesystem.copyFileToManegeDirectory(file_dir_path + file_name, path + '/teste').then(fileAs64 => 
    console.log(fileAs64).
);

带读

// file_dir_path = file:///storage/emulated/0/Download/
// file_name = file.kml
return readFile(file_dir_path + file_name).then(fileAs64 => 
    console.log(fileAs64);
);

文件系统服务

/** Copy Files */
// fileToCopy = file:///storage/emulated/0/Download/file.kml
copyFileToManegeDirectory(fileToCopy: string, directoryToGo: string): Promise<any> 
    return Filesystem.checkPermissions().then(permission => 
        console.log(permission)
        return Filesystem.copy(
            from: fileToCopy,
            directory: Directory.ExternalStorage,
            to: directoryToGo,
            toDirectory: Directory.External
        ).then(result => 
            console.log(result);
        )
    );


/** Read a file and returns a string base 64 */
readFile(path: string): Promise<string> 
    return Filesystem.readFile(
        path: path
    ).then(result => 
        return result.data;
    );

我需要知道是否可以从 Android 11 上应用的作用域文件夹中获取文件。我的应用需要导入可以存在于设备上任何位置的文件(用户选择从哪里)。

离子信息


   Ionic CLI                     : 6.15.1-testing.0 (C:\Users\Gabriel Vieira\AppData\Roaming\npm\node_modules\@ionic\cli)
   Ionic Framework               : @ionic/angular 5.6.8
   @angular-devkit/build-angular : 12.0.2
   @angular-devkit/schematics    : 12.0.2
   @angular/cli                  : 12.0.2
   @ionic/angular-toolkit        : 4.0.0

Capacitor:

   Capacitor CLI      : 3.0.0
   @capacitor/android : 3.0.0
   @capacitor/core    : 3.0.0
   @capacitor/ios     : not installed

Utility:

   cordova-res : 0.15.3
   native-run  : 1.4.0

System:

   NodeJS : v14.16.1 (C:\Program Files (x86)\nodejs\node.exe)
   npm    : 6.14.12
   OS     : Windows 10

npx 帽子医生

Latest Dependencies:

  @capacitor/cli: 3.0.1
  @capacitor/core: 3.0.1
  @capacitor/android: 3.0.1
  @capacitor/ios: 3.0.1

Installed Dependencies:

  @capacitor/ios: not installed
  @capacitor/cli: 3.0.0
  @capacitor/android: 3.0.0
  @capacitor/core: 3.0.0

编辑

尝试将目标 SDK 更改为 28 和 29,但出现同样的错误。

文档说当我需要访问范围存储之外的文件时添加标签MANAGE_EXTERNAL_STORAGE,但是这个参数已经包含在我的清单中,即使那样我也不允许读取范围存储之外的任何内容。

在使用 checkPermissions()requestPermissions() 测试文件系统权限时,这两个函数都返回 publicStorage: 'granted'。

【问题讨论】:

【参考方案1】:

如果您将正确的目标放在android/variables.gradle 中,它应该可以正常工作,如果没有,您必须在 Capacitor GitHub 页面中打开一个问题。

ext 
    compileSdkVersion = 29
    targetSdkVersion = 29
    ...

除非您有充分的理由,否则您不应使用 MANAGE_EXTERNAL_STORAGE,否则在 Google Play 商店中部署可能会很麻烦,有关详细信息,请参阅Google's support page。在您的 AndroidManifest 中还保留参数android:requestLegacyExternalStorage="true",并添加用户权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

【讨论】:

以上是关于当我尝试在 Android 11 中读取文件时出现电容器文件系统错误的主要内容,如果未能解决你的问题,请参考以下文章

当我尝试运行应用程序时出现 Android Studio 错误

在 Python 中读取 Twitter json 文件时出现 KeyErrors

使用 Python 中的列表理解读取 GPX 文件时出现 UTF 错误

下载工件时出现问题 - 读取签名内容时出错

尝试从 Java 中的二进制文件中读取 Int 时出现 BufferUnderflowException

尝试将 xml 导入到 android 时出现 OutOfMemoryException