Android 7.0 FileProvider Instructions for Use

Original address: https://blog.csdn.net/soslinken/article/details/70145354


FileProvider

The FileProvider component was added to the Android system under the Android 22.0.0 (that is, Android 5.0) version. This component is a subclass of ContentProvider, and its function is to provide the ability to access files across processes. Don't think that it was only added to Android 7.0.

Why Android 7.0 file sharing uses FileProvider

The reason for this is that, after Android 7.0, the review of StrictMode has been stricter. Just like the exception of NetWorkOnMainThread added after Android 3.0, Google will use strict mode for the parts that cause experience or security problems to the Android system. Limit program developers. 
For file access before Android 7.0, you can use file://uri to access, but there is a problem in this place, that is, even if it is not a file generated by your own application, you can call it as long as you know the uri of the other party. risk arises. Therefore, after Android 7.0, the restriction on cross-process access to files has been added. This restriction will cause an exception of android.os.FileUriExposedException if you use file://uri to access.

FileProvider use

Step 1 AndroidManifest, register FileProvider

 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
      <application
          ...>
          <provider
              android:name="android.support.v4.content.FileProvider"
              android:authorities="org.unreal.update"
              android:grantUriPermissions="true"
              android:exported="false">
              <meta-data
                  android:name="android.support.FILE_PROVIDER_PATHS"
                  android:resource="@xml/update_files" />
          </provider>
          ...
      </application>
  </manifest>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

The point to pay attention to is the 
android:authorities parameter, like ContentProvider, you need to provide a uri authority here, so that content://android:authorities/uri can be accessed, android:authorities can be freely defined

Step 2 Create an xml folder under res, and create update_files.xml under the xml folder

write picture description here

<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"/>
        <!-- 此标签需要 support 25.0.0以上才可以使用-->
        <external-cache-path  path="files" name="externalcache"/>  
    </paths>
</resources>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

name: name flag string, cannot have the same name! 
path: Folder "relative path", the full path depends on the current label type.

Label path
…….. * represents the current folder and its subfolders
file-path The physical path is Context.getFilesDir() + /files/*
cache-path The physical path is Context.getCacheDir() + /files/*
external-path The physical path is Environment.getExternalStorageDirectory() + /files/*
external-files-path The physical path is Context.getExternalFilesDir(String) + /files/*
external-cache-path The physical path is Context.getExternalCacheDir() + /files/*

After seeing the article about FileProvider by zhuhf in Jianshu, I found that there is a hidden label

Article address:  http://www.jianshu.com/p/55eae30d133c

<root-path name="name" path="path" />
  • 1
Label path
…….. * represents the current folder and its subfolders
root-path Physical path is equivalent to /path/*

Step 3 Get the uri through getUriForFile

data = FileProvider.getUriForFile(context,"之前在AndroidManifest中配置的android:authorities", "7.0后文件的路径");
// 给目标应用一个临时授权
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
               | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
  • 1
  • 2
  • 3
  • 4

FLAG_GRANT_READ_URI_PERMISSION: Indicates read permission; 
FLAG_GRANT_WRITE_URI_PERMISSION: Indicates write permission; 
according to your needs, choose whether to read or write

Example Install APK

 private void installApk(File apk) {
        if (!apk.exists()) {
            return;
        }
        Uri data;
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // UpdateConfig.FILE_PROVIDER_AUTH 即是在清单文件中配置的authorities
            data = FileProvider.getUriForFile(context, UpdateConfig.FILE_PROVIDER_AUTH, apk);
            // 给目标应用一个临时授权
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else {
            data = Uri.fromFile(apk);
        }
        intent.setDataAndType(data, "application/vnd.android.package-archive");
        context.startActivity(intent);
        android.os.Process.killProcess(android.os.Process.myPid());
    }

Guess you like

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