【问题标题】:Internal Storage: Why is getFilesDir() giving me the wrong folder?内部存储:为什么 getFilesDir() 给了我错误的文件夹?
【发布时间】:2019-10-29 13:11:11
【问题描述】:

我正在开发一个安卓应用程序。我想将文件从 Firebase 存储下载到内部存储,然后能够播放它们(音频文件)。我使用 getFilesDir() 来实现这一点。

在模拟器上一切正常。我的音频目录位于

/data/user/0/com.package.name/files/audio/

此问题出现在使用 Android API 28 的部分华为设备(手机和平板电脑)上。

我收到错误消息,在上述位置找不到我的音频文件夹,使用设备文件资源管理器我可以清楚地看到没有 data/user/ 文件夹,而是系统仍然使用旧的 /data/data/com.package.name/ 目录。

所以我的问题是:

有人知道为什么 getFilesDir() 没有给我正确的路径,以及如何在不硬编码路径的情况下解决这个问题。

这是一些代码,我也尝试在根文件夹上调用exists(),但没有成功。

    String filename = document.getId() + ".m4a";
    String rootPath = getFilesDir().getAbsolutePath();
    File root = new File(rootPath);

//not working
    if(!root.exists()){
        rootPath = "/data/data/" + getPackageName() + File.separator + "files"
                + File.separator + "voice" + File.separator;
    }
//

    String folderPath = rootPath + File.separator + "voice" + File.separator;
    File subFolder = new File(folderPath);

    if(!subFolder.exists()){
        subFolder.mkdir();
    }

    final File localFile = new File(subFolder, filename);
    final StorageReference voiceRef = uploadsRef.child("voice").child(filename);
    voiceRef.getFile(localFile);

【问题讨论】:

  • getFilesDir() 存在的原因是因为设备之间的绝对路径可以而且确实不同,这是意料之中的。你是说getFilesDir().exists() 在这些设备上返回 false 吗?
  • getFilesDir().getAbsolutePath() 返回错误的路径,它返回 /data/user/0/ 但设备没有这样的目录。它使用 data/data/ 代替。我在 root.exists() 上面的代码中的方式返回 true。我希望 getFilesDir 给我设备特定的路径,但由于它不起作用,我试图通过硬编码那些旧目录系统的路径来解决问题(因为存在返回 true,所以没有帮助。
  • 绝对路径在不同的设备上会有所不同。你为什么要看绝对路径?
  • 你的音频目录不是一直在new File(getFilesDir(), "audio")吗(如果你的文件夹叫音频,你的代码也用voice)?这将在每台设备上保持一致
  • /data/data/ 是指向/data/user/0 实际位置的符号链接

标签: java android firebase-storage


【解决方案1】:

getFilesDir() 可以并且确实根据您正在运行的设备或什至正在运行您的应用程序的用户(对于支持多用户的设备)返回不同的绝对路径(这就是您所看到的 user/0)。

只要您在getFilesDir() 返回的目录或其子目录(例如您的new File(getFilesDir(), "voice") 目录)上进行操作,一切都将在每台设备上运行。

【讨论】:

  • 使用 getFilesDir() 遇到一个奇怪的问题。如果我删除目录并在下一个应用程序运行调用 getFilesDir().mkdir/mkdirs 返回错误,则在有根电话上!知道为什么吗?另外我认为这个目录是在应用安装时自动创建的,或者可能是第一次启动?
  • @MuhammadBabar - 如果您查看source code for getFilesDir(),您会注意到如果该文件夹不存在,它会尝试自动创建该文件夹,但该文件夹的所有权比您可能会想(系统拥有更高级别的目录,您的应用无法写入这些目录,这就是您无法自己创建这些目录的原因)。
  • 是的,感谢您的指出。所以你说系统拥有目录(getFilesDir)但文档说No additional permissions are required for the calling app to read or write files under the returned path。所以我的理解是 getFilesDir 返回的路径只能由系统写入,但系统允许访问该路径内的相应应用程序以执行写入操作?
  • 在根电话上。如果我删除目录并在下次运行时执行getFilesDir,为什么系统无法再次创建目录?
【解决方案2】:

我很困惑为什么getFilesDir() 在正确的目录中创建文件但在需要删除时找不到它们,getFilesDir().getPath() 为我工作。

【讨论】:

    【解决方案3】:

    getFilesDir() 方法返回一个抽象文件路径,该路径会根据存储系统而改变。

    您可以使用getCanonicalFile() 获取/data/data/com.package.name/files 路径。在 Kotlin 中,它看起来像这样:

    val filePath = context.filesDir.canonicalFile
    

    这将为您提供特定于设备的路径名。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-15
      • 2021-05-13
      • 2014-08-16
      • 2021-06-09
      • 2016-11-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多