Context#getExternalFilesDir, a summary of the use of various storage directories in android

The Context class defines some APIs for obtaining the directory of the mobile phone system. Here is a summary:

1. API comment translation

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)
     */

        The translation of the function api description information is as follows:

        The getExternalFilesDir function returns the absolute path of the main shared/external storage device directory where the application can store its own persistent files. These persistent files are internal to the program and are not normally visible to the user as media.

        When the application is uninstalled, these files will also be deleted, which is somewhat similar to the getFilesDir() function. However, there are some important differences between them, as follows:

  • Shared storage may not always be available because users can eject removable media devices. You can use Environment#getExternalStorageState(File) to check the media status;
  • There is no security enforcement for these files, for example, any application with android.Manifest.permission#WRITE_EXTERNAL_STORAGE permission can change these files;

        If the shared storage device is emulated (determined by Environment#isExternalStorageEmulated(File)), then its contents are backed by the private userdata partition, which means that there is a slight benefit in storing data here, rather than using getFilesDir() return private directory.

        Starting with android.os.Build.VERSION_CODES#KITKAT (sdk19, ie android 4.4), reading and writing to these returned directories no longer requires any permissions. These directories are always accessible by the app that is currently calling this function. This only applies to paths generated for the calling application's package name. To access paths belonging to other package names, you need to obtain android.Manifest.permission#WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE permissions.

        On a multi-user device, each user has its own independent shared storage directory. Applications can only access shared directories of the current running user.

        The returned path may change over time if a different shared storage medium is plugged in, so only relative paths should be preserved.

        Here is an example private_file of common code for manipulating files on application shared storage, see link: http://androidxref.com/9.0.0_r3/xref/development/samples/ApiDemos/src/com/example/android/apis/ content/ExternalStorage.java

        If you pass a non-null argument to this function, the returned path will be a subdirectory of the given directory. Although Media Scanner does not scan these files automatically, you can explicitly add them to the media database using MediaScannerConnection.scanFile.

        Note that this differs from Environment.getExternalStoragePublicDirectory(), which provides a media directory shared by all applications. The directories returned here are only owned by the application itself, and are deleted when the application is uninstalled. Unlike Environment.getExternalStoragePublicDirectory(), the directory returned here will be created automatically for you.

        Here's an example private_picture of generic code for manipulating pictures in the application's shared storage and adding pictures to the media database. See link http://androidxref.com/9.0.0_r3/xref/development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java

        Type parameter description:

        type represents the type of the file directory to be returned, and may be null or other values. null represents the root directory of the file directory, and other values ​​represent the subdirectories of the root directory, respectively:

Environment#DIRECTORY_MUSIC

Environment#DIRECTORY_PODCASTS

Environment#DIRECTORY_RINGTONES

Environment#DIRECTORY_ALARMS

Environment#DIRECTORY_NOTIFICATIONS

Environment#DIRECTORY_PICTURES

Environment#DIRECTORY_MOVIES        

        Return value description: The absolute path of the directory specified by the application. If the shared storage is currently unavailable, null may be returned.

reference:

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

2. Reference articles

It’s almost finished, and I still haven’t introduced the specific path returned by the function. Let me add here:

  1. This method is used to obtain external storage at /storage/emulated/0/Android/data/packageName/files
  2. This method can pass a String type parameter, expressed as a folder under the path, if there is no such folder, it will be created automatically
  3. Instructions
    ​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. This directory is mainly used to store some private files of the application . This directory has several properties:

Automatic deletion
        These files are deleted when the app is uninstalled. Of course, the premise is that the sd card is available.

Other applications accessing
        these files can be accessed by other applications, but the premise is that other applications have external storage permissions.

        But note that even after Android 11, other apps are not allowed to access these files even if they have storage permissions.

Storage permissions
         After Android api 19 (ie 4.4), this app can access these files even without storage permissions, although they are on the sd card. The official documentation is as follows:

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,

        Since the minSdkVersion of most Apps is 19 or above, there is no need to request storage permissions when using this directory.

3. The difference with getExternalFilesDirs

        Let's take a look at the annotations of 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)}.

        What the getExternalFilesDirs function returns is: the absolute path of the directory collection specified by the application. Some independent path collections may be null if shared storage is not currently available. The first path returned is the same as getExternalFilesDir(String).

        Next, I will debug through the break point to see what the specific value of the return path array of getExternalFilesDirs contains:

 Reference article:

1. What exactly is getExternalFilesDir_BennuCTech's Blog-CSDN Blog_getexternalfilesdir

2. [Android] internal parameters of getExternalFilesDir()

3. Android Compatibility Series Article 5: Memory Card - Nuggets

Guess you like

Origin blog.csdn.net/liuqinhou/article/details/127177192