Android development learning to use FileProvider to get file uri

introduce

FileProvider is the recommended way to get file Uri in Android and will replace the Uri.fromFile() method


old-fashioned problem

In Android 7.0 version, directly obtaining Uri from the file in the internal storage will cause the program to crash. The relevant code is as follows:

Uri uri = Uri.fromFile (file);

If you run it, you will get an error:



The solution is to introduce FileProvider


Use of FileProvider

Now, I will show you the usage of FileProvider step by step

statement

We first need to declare a FileProvider child node under the application node in the manifest file

<provider
  android:authorities="com.example.songzeceng.myFileProvider"
  android:name="android.support.v4.content.FileProvider"
  android:exported="false"
  android:grantUriPermissions="true">
  <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
             android:resource="@xml/updatepath"></meta-data>
</provider>

The properties and nodes inside are explained as follows:

    provider: indicates that this is a provider    

    The name of android:authorities:provider, like this attribute of ContentProvider, is the identity of this provider

    android:name: fixed, to use FileProvider, it must be declared as in the code

    android:exported: whether to export, must be false

    android:grantUriPermissions: Whether to be granted uri permission, must be true

    <meta-data>: Attributes visible to external applications of this provider, a path must be declared, indicating the shared directory

        android:name: The name of the shared directory, fixed hard-coded

        android:resource: The xml file corresponding to the path, this should create a new corresponding xml file in the res directory


Create share xml file

Now we have to create an xml file corresponding to the android:resource tag mentioned above --> xml/updatepath.xml

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <paths>
        <files-path path="files" name="files" />
        <cache-path path="files" name="cache" />
        <external-path path="files" name="external" />
        <external-files-path path="files" name="externalfiles"/>
        <!-- This tag requires support 25.0.0 or above to use -->
        <external-cache-path  path="files" name="externalcache"/>
    </paths>
</resources>

The labels file-path and cache-path represent a directory in the phone memory, the path attribute is a subdirectory under this directory, and the name attribute is a pseudonym, which will replace the absolute path of the path directory

The paths corresponding to the sub-tags involved in the figure are as follows:

subtab The absolute path corresponding to the subtag (without path) The absolute path corresponding to the subtag (plus path) pseudonym
files-path

The files directory under the app's private storage area

(context.getFilesDir())

files directory plus path

(context.getFilesDir()/files)

files
cache-path

The cache directory under the app's private directory

(context.getCacheDir())

private cache directory plus path

(context.getCacheDir()/files)

cacheexternal-path external stub directory (Environment.getExternalStorageDirectory()) external stub directory plus path (Environment.getExternalStorageDirector()/files)external

external-files

-path

The file directory under the external stub directory

(context.getExternalFilesDir())

file directory plus path

(context.getExternalFilesDir()/files)

externalfiles

external-cache

-path

Cache directory under external stub directory

(context.getExternalCacheDir())

cache directory plus path

(context.getExternalCacheDir()/files)

externalcaches    

The final result is the shared directory obtained by the external app, not a path, but a pseudonym

Moreover, each time a shared directory is added, a corresponding sub-tag must be added.

For example, if I add a new shared directory, which is a folder under the external stub directory, I add a subtag as follows:

<external-path name = "fp_pictures" path = "/Pictures/dongqiudi/"></external-path>

just fine


Use FileProvider to get file Uri

code show as below:

String path = Environment.getExternalStorageDirectory().getPath() + "/Pictures/dongqiudi/1523624189281.jpg";
File file = new File(path);
if (file.exists()) {
   Uri uri = FileProvider.getUriForFile(MainActivity.this, "com.example.songzeceng.myFileProvider", file);
   Log.i(TAG, "uri:" + uri.toString());
}

The code is very simple, but in order to prevent errors, I judged whether the file exists (what happens if it does not exist, I have not tried it)


result

As you can see, it does replace the shared directory path we specified with the pseudonym fp_pictures. This uri is different from the previous path uri, but it does not affect the use, and it will still find our file correctly.


Epilogue

This example is just a verification, to see if the FileProvider parses and converts the file uri correctly, and whether the program crashes, and finds that everything is normal, then we can use the newly generated uri according to our own business.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324843608&siteId=291194637