getExternalFilesDir 和 getExternalStorageDirectory() 之间的区别

Posted

技术标签:

【中文标题】getExternalFilesDir 和 getExternalStorageDirectory() 之间的区别【英文标题】:Difference between getExternalFilesDir and getExternalStorageDirectory() 【发布时间】:2012-04-24 19:30:49 【问题描述】:

我了解 ExternalFiles 用于 API 8 及更高版本,getExternalStorageDirectory 用于 7 及以下版本。但是我在使用之间有点困惑。例如,我想检查一个文件夹是否存在,以前你会使用类似的东西:

File ChildFolder = new File(Environment.getExternalStorageDirectory() + "/ParentFolder/Child");

但是,我看到的每个示例都说要使用 getExternalFilesDir (null)、File.ext。由于我在 API 8 以上,我想使用这种方法,但我该如何检查文件夹?我将在另一点检查文件是否存在,但现在只想查看文件夹是否存在??

【问题讨论】:

【参考方案1】:
getExternalFilesDir()

它返回您 SD 卡上 Android/data/data/your_package/ 内的 files 文件夹的路径。它用于存储您的应用程序所需的任何文件(例如,从 Web 下载的图像或缓存文件)。卸载应用后,此文件夹中存储的所有数据也将消失。

getExternalStorageDirectory()

它返回您 SD 卡的根路径(例如 mnt/sdcard/)。如果您在此路径上保存数据并卸载应用,则该数据不会丢失。

【讨论】:

Google android 希望您使用他们在框架内提供的任何内容。所以它取决于您的选择和设计要求。如果您不希望在卸载应用程序时文件留在左侧,那么建议您使用 getExternalFilesDir()getExternalCacheDir() 这是因为在 API 8 中,他们引入了高级媒体扫描仪功能,可以扫描音乐、图片、铃声等文件夹中的数据。只有当您使用 getExternalFilesDir( )。现在,由于 API 7 中不提供此功能,因此他们建议使用 getExternalStorageDirectory()。简单... 没关系,给它一些时间,很快就会有一个 eureka 时刻:) 重要的是要知道getExternalStorageDirectory() 不一定 -- 甚至可能通常不会 -- 返回“指向您的 SD 卡的路径。 "相反,它返回“主要外部存储目录”。文档 (developer.android.com/reference/android/os/…) 说: '注意:不要被这里的“外部”这个词弄糊涂了。最好将此目录视为媒体/共享存储。它是一个文件系统,可以保存相对大量的数据,并且在所有应用程序之间共享(不强制执行权限)。 传统上这是一个SD卡,但它也可以作为设备中的内置存储实现,不同于受保护的内部存储,并且可以作为文件系统安装在电脑上。'【参考方案2】:

首先,我们需要了解内部存储、外部存储(也称为主外部存储)和辅助外部存储之间的区别是什么?

内部存储:是用户无法访问的存储,除非通过已安装的应用程序(或通过 root 设备)。示例:data/data/app_packageName

主外部存储:内置共享存储,“用户可以通过插入 USB 电缆并将其作为驱动器安装在主机上来访问”。示例:当我们说 Nexus 5 32 GB。

辅助外部存储:可移动存储。示例:SD 卡。

getExternalFilesDir (String type)

它返回主外部存储上 Android/data/data/your_package/ 内文件夹的路径。这是内置存储。

Environment.getExternalStorageDirectory()

会返回二级外部存储目录的路径

【讨论】:

感谢您解释不同类型的存储。但是,也许编辑 internal storage 项以提及获取该值的方法调用是 getFilesDir()。好吧,我猜该方法实际上返回 data/data/app_packageName/files 但它仍然是内部存储。 @VicJordan 请同时写File getExternalStoragePublicDirectory (String type)File getFilesDir () 谢谢维克。 Environment.getExternalStorageDirectory() 输出 /storage/emulated/0 您是否有任何文档说明主外部存储始终是内置的,而辅助外部存储始终是可移动的?我认为这些是独立的问题......有些手机没有内置的“外部”存储,在这种情况下,主要的外部存储可能是可移动的 SD 卡。 @LarsH,据我所知,目前市场上或不久的将来没有没有内置主外部存储的手机。姜饼时代有手机,但现在没有。你能说出“一些”没有内置“主要外部存储”的手机吗?【参考方案3】:

!重要更新!给遇到这个问题的人。

因为这是一个有点老的问题,只是想提供一些额外的信息。由于 KitKat 甚至具有 WRITE_EXTERNAL_STORAGE 权限的应用程序只允许写入外部存储上的 Android/data/data/your_package/又名 getExternalFilesDir()

如果您尝试写信给getExternalStorageDirectory() + "/somefolder/anotherfolder/",您将在大多数设备上收到 SecurityException

【讨论】:

根据文档,具有 WRITE_EXTERNAL_STORAGE 权限的应用程序可以写入其他包的外部存储,而不仅仅是他们自己的。没有权限的应用程序只能写入自己的目录:developer.android.com/reference/android/content/…“从 KITKAT 开始,读取或写入返回的路径不需要权限;调用应用程序始终可以访问它...访问属于其他包的路径,WRITE_EXTERNAL_STORAGE 和/或 READ_EXTERNAL_STORAGE 是必需的。" 这是“在大多数设备上”开始变得重要的地方,因为 android 文档概括了这个想法,但制造商有时会有 InternalStorage(应用数据的内置存储)、ExternalStorage-Primary(还具有更大访问范围的内置存储)和 ExternalStorage-Secondary(这将安装诸如 SD 卡之类的东西)。现在你可以猜测一下 getExternalStorageDirectory 返回哪个路径 这并没有解决您答案中的错误信息。 “由于 KitKat 甚至具有 WRITE_EXTERNAL_STORAGE 权限的应用程序也只允许写入外部存储上的 Android/data/data/your_package/,即 getExternalFilesDir()”。根据文档,这是错误的。使用 WRITE_EXTERNAL_STORAGE,应用可以写入所有外部存储。 @Oded,你测试过这个吗?我对文档的理解,以及我对 KitKat 和后来的设备的体验,与你的不同。 (希望我现在有时间讨论所有细节。也许以后。)我的经验是 SGal 是对的。然后还有棒棒糖,有点不同。 根据 Android 的文档,这个答案是公然错误的。请参阅developer.android.com/reference/android/…“从 API 级别 19 开始,读取/写入 getExternalFilesDir(String) 和 getExternalCacheDir() 返回的应用程序特定目录中的文件不需要此权限。” (请注意,API 级别 19 = KitKat。)不知道它是如何获得这么多支持的。【参考方案4】:

!!重要!!

Environment.getExternalStorageDirectory()弃用,应使用 Context#getExternalFilesDir(String)、MediaStore 或 Intent#ACTION_OPEN_DOCUMENT。

此方法在 API 级别 29 中已弃用。 为了提高用户隐私,不推荐直接访问共享/外部存储设备。当应用程序以 Build.VERSION_CODES.Q 为目标时,从此方法返回的路径不再可供应用程序直接访问。通过迁移到 Context#getExternalFilesDir(String)、MediaStore 或 Intent#ACTION_OPEN_DOCUMENT 等替代方案,应用可以继续访问存储在共享/外部存储上的内容。

https://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory()

同样从 Android.M 开始,开发者需要在运行时请求权限。

在文档here 和this question 中查看更多详细信息

Environment.getExternalStorageDirectory() deprecated in API level 29 java

【讨论】:

如果有人正在寻找堆栈溢出链接,而不是从谷歌文档复制粘贴的内容,请看这里***.com/questions/57116335/… 从 Android 11 开始,应用无法在外部存储上创建自己的应用特定目录。 应用程序*技术上*不能,但系统可以为它们执行此操作:***.com/questions/64044993/…

以上是关于getExternalFilesDir 和 getExternalStorageDirectory() 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

为啥 getExternalFilesDirs 根据使用的上下文返回不同的结果?

在 API 23 及更高版本中插入 SD 卡时,getExternalFilesDirs() 未在 ApplicationContext 中更新

getExternalFilesDir到底是什么

Android存储及getCacheDir()getFilesDir()getExternalFilesDir()getExternalCacheDir()区别

android 各种存储目录使用总结之Context#getExternalFilesDir

与他人共享图像和文本应用程序