Context类中定义了获取手机系统目录的一些api。这里做一个总结:

一、api 注释翻译

1、File getExternalFilesDir(@Nullable String type)

@Nullable
public abstract File getExternalFilesDir(@Nullable String type);
/**
     * Returns the absolute path to the directory on the primary shared/external
     * storage device where the application can place persistent files it owns.
     * These files are internal to the applications, and not typically visible
     * to the user as media.
     * <p>
     * This is like {@link #getFilesDir()} in that these files will be deleted
     * when the application is uninstalled, however there are some important
     * differences:
     * <ul>
     * <li>Shared storage may not always be available, since removable media can
     * be ejected by the user. Media state can be checked using
     * {@link Environment#getExternalStorageState(File)}.
     * <li>There is no security enforced with these files. For example, any
     * application holding
     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} can write to
     * these files.
     * </ul>
     * <p>
     * If a shared storage device is emulated (as determined by
     * {@link Environment#isExternalStorageEmulated(File)}), it's contents are
     * backed by a private user data partition, which means there is little
     * benefit to storing data here instead of the private directories returned
     * by {@link #getFilesDir()}, etc.
     * <p>
     * Starting in {@link android.os.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,
     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or
     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
     * <p>
     * On devices with multiple users (as described by {@link UserManager}),
     * each user has their own isolated shared storage. Applications only have
     * access to the shared storage for the user they're running as.
     * <p>
     * The returned path may change over time if different shared storage media
     * is inserted, so only relative paths should be persisted.
     * <p>
     * Here is an example of typical code to manipulate a file in an
     * application's shared storage:
     * </p>
     * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
     * private_file}
     * <p>
     * If you supply a non-null <var>type</var> to this function, the returned
     * file will be a path to a sub-directory of the given type. Though these
     * files are not automatically scanned by the media scanner, you can
     * explicitly add them to the media database with
     * {@link android.media.MediaScannerConnection#scanFile(Context, String[], String[], android.media.MediaScannerConnection.OnScanCompletedListener)
     * MediaScannerConnection.scanFile}. Note that this is not the same as
     * {@link android.os.Environment#getExternalStoragePublicDirectory
     * Environment.getExternalStoragePublicDirectory()}, which provides
     * directories of media shared by all applications. The directories returned
     * here are owned by the application, and their contents will be removed
     * when the application is uninstalled. Unlike
     * {@link android.os.Environment#getExternalStoragePublicDirectory
     * Environment.getExternalStoragePublicDirectory()}, the directory returned
     * here will be automatically created for you.
     * <p>
     * Here is an example of typical code to manipulate a picture in an
     * application's shared storage and add it to the media database:
     * </p>
     * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
     * private_picture}
     *
     * @param type The type of files directory to return. May be {@code null}
     *            for the root of the files directory or one of the following
     *            constants for a subdirectory:
     *            {@link android.os.Environment#DIRECTORY_MUSIC},
     *            {@link android.os.Environment#DIRECTORY_PODCASTS},
     *            {@link android.os.Environment#DIRECTORY_RINGTONES},
     *            {@link android.os.Environment#DIRECTORY_ALARMS},
     *            {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
     *            {@link android.os.Environment#DIRECTORY_PICTURES}, or
     *            {@link android.os.Environment#DIRECTORY_MOVIES}.
     * @return the absolute path to application-specific directory. May return
     *         {@code null} if shared storage is not currently available.
     * @see #getFilesDir
     * @see #getExternalFilesDirs(String)
     * @see Environment#getExternalStorageState(File)
     * @see Environment#isExternalStorageEmulated(File)
     * @see Environment#isExternalStorageRemovable(File)
     */

        函数api描述信息翻译如下:

        getExternalFilesDir函数返回主要的共享/外部存储设备的目录的绝对路径,在这些路径上应用程序可以存放应用程序自身的持久性文件。这些持久性文件是程序内部的,通常不会作为媒体对用户可见。

        当应用被卸载后,这些文件也会被删除掉,这有点类似于getFilesDir()函数。然而它们之间也有一些重要的不同点,如下:

  • 共享存储可能不总是可用的,因为用户可以弹出可移动媒体设备。可以使用 Environment#getExternalStorageState(File)来检查媒体状态;
  • 这些文件没有安全强制,比如,任何应用具有android.Manifest.permission#WRITE_EXTERNAL_STORAGE权限都可以更改这些文件;

        如果共享存储设备是被模拟的(由Environment#isExternalStorageEmulated(File)决定),那么它的内容被私有用户数据分区支持,这意味着在这里存储数据是有一点好处的,而不是使用getFilesDir()返回的私有目录。

从android.os.Build.VERSION_CODES#KITKAT (sdk19,即android 4.4)开始,读取和写人这些返回的目录都不再需要任何权限。这些目录总是可被当前正在调用该函数的app访问的。这仅适用于为调用应用程序的包名称生成的路径。要访问属于其他包名的路径,需要获取android.Manifest.permission#WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE权限。

        在多用户的设备上,每一个用户拥有自己独立的共享存储目录。应用程序仅仅可以访问当前正在运行用户的共享目录。

        如果插入不同的共享存储介质,返回的路径可能会随着时间而改变,因此只应保留相对路径。

        这里有一个在应用程序共享存储上操作文件通用代码的例子private_file,见链接:http://androidxref.com/9.0.0_r3/xref/development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java

        如果你传入了一个非空类型的参数到该函数中,返回的路径将会是给定目录的子目录。尽管媒体扫描仪不会自动扫描这些文件,但你可以使用MediaScannerConnection.scanFile明确地把它们添加到媒体数据库中。

需要注意它不同于Environment.getExternalStoragePublicDirectory(),后者提供被所有应用程序共享的媒体目录。这里返回的目录仅仅被应用程序自己拥有,并且当应用程序被卸载时这些目录也被删除。不同于Environment.getExternalStoragePublicDirectory(),这里返回的目录将会为你自动创建。

        type参数说明:

        type代表要返回的文件目录的类型,有可能为null或其他值。null代表文件目录的根目录,其他取值代表根目录的子目录,分别为:

Environment#DIRECTORY_MUSIC

Environment#DIRECTORY_PODCASTS

Environment#DIRECTORY_RINGTONES

Environment#DIRECTORY_ALARMS

Environment#DIRECTORY_NOTIFICATIONS

Environment#DIRECTORY_PICTURES

Environment#DIRECTORY_MOVIES        

        返回值说明:应用程序指定目录的绝对路径,如果共享存储当前不可用可能返回null。

参考:

Context#getFilesDir
Context#getExternalFilesDirs(String)
Environment#getExternalStorageState(File)
Environment#isExternalStorageEmulated(File)
Environment#isExternalStorageRemovable(File)

二、参考文章

都快写完了,还是没介绍函数返回的具体的路径是什么, 这里我补充一下吧:

  1. 该方法用于获得外部存储,地址为/storage/emulated/0/Android/data/packageName/files
  2. 该方法可传一个String类型的参数,表述为该路径下的文件夹,没有该文件夹会自动创建
  3. 使用方法
String path=context.getExternalFilesDir(null).getAbsolutePath();
File file=new File(path);
//输出:path:/storage/emulated/0/Android/data/backageName/files

String path2=context.getExternalFilesDir("UniApp").getAbsolutePath();
File file2=new File(path2);
//path:/storage/emulated/0/Android/data/packageName/files/UniApp
//如uniapp文件夹没有,则会自动创建

String path3=context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
File file3=new File(path3);
//path:/storage/emulated/0/Android/data/packageName/files/Download


String path4=context.getExternalFilesDir("").getAbsolutePath()+"/hhhhhh";
File file4=new File(path4);
//path:storage/emulated/0/Android/data/packageName/files/hhhhhh
//如果没有“hhhhhh”文件夹,则file4.exists()==false;

4.该目录主要是用来存放应用私有的一些文件。这个目录有几个特性:

自动删除
        当应用卸载的时候,这些文件会被删除。当然前提是sd卡可用。

其他应用访问
        这些文件可以被其他应用访问,但是前提是其他应用有外部存储权限。

但是注意在Android 11以后即使有存储权限,其他应用也不允许访问这些文件了。

存储权限
        在Android api 19(即4.4)之后,本应用即使没有存储权限,也可以访问这些文件,虽然它们是在sd卡上。官方文档如下:

Starting in {@link android.os.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,

        鉴于目前大部分App的minSdkVersion都是19或以上,所以当使用这个目录的时候,是没必要再请求存储权限的。

三、与getExternalFilesDirs的区别

        我们来看看getExternalFilesDirs的注释:

* @return the absolute paths to application-specific directories. Some
*         individual paths may be {@code null} if that shared storage is
*         not currently available. The first path returned is the same as
*         {@link #getExternalFilesDir(String)}.

        getExternalFilesDirs函数返回的是:应用程序指定目录集合的绝对路径。如果共享存储当前不可用,一些独立路径集合可能为null。返回的第一个路径和getExternalFilesDir(String)是一样的。

        下面我通过打断点调试查看下getExternalFilesDirs返回路径数组具体取值包含哪些内容:

android中get怎么传递参数json数据_应用程序