android 7.0 应用间文件共享FileProvider

1.官方教程

  Android 7.0 以后安全系数提高,应用间文件共享要使用FileProvider。原来的 file:/// Uri 替换为 content://Uri 

  https://developer.android.com/reference/android/support/v4/content/FileProvider

2.步骤

  1. Defining a FileProvider
  2. Specifying Available Files
  3. Retrieving the Content URI for a File
  4. Granting Temporary Permissions to a URI
  5. Serving a Content URI to Another App

3.示例

3.1 定义 FileProvider

  在AndroidManifest.xml中

1         <provider
2             android:name="androidx.core.content.FileProvider"
3             android:authorities="cn.com.txw.fileprovider"
4             android:exported="false"
5             android:grantUriPermissions="true">
6             <meta-data
7                 android:name="android.support.FILE_PROVIDER_PATHS"
8                 android:resource="@xml/file_paths" />
9         </provider>

  非androidx 使用 android:name="android.support.v4.content.FileProvider"

3.2 定义共享文件的路径

1 <?xml version="1.0" encoding="utf-8"?>
2 <paths>
3     <external-files-path    name="externalFiles"    path="download/"/>
4     <external-path          name="externalRoot"     path="download/" />
5     <root-path              name="root"             path="" />
6 </paths>

注意 path的值是目录时要有 "/" 

<paths>可选子标签及含义 如下:

子标签路径
file-path Context.getFilesDir()
cache-path getCacheDir()
external-path Environment.getExternalStorageDirectory()
external-files-path Context#getExternalFilesDir(String) Context.getExternalFilesDir(null).
external-cache-path Context.getExternalCacheDir()
external-media-path Context.getExternalMediaDirs()

root-path

根目录 "/"

3.3 生成共享文件的uri

 1    public static void openApkFile(String file ) {
 2 
 3         Intent intent = new Intent(Intent.ACTION_VIEW);
 4         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 5         Uri data;
 6         File apk = new File(file);
 7 
 8         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
 9             final String author = "cn.com.txw.fileprovider";
10             try {
11                 data = FileProvider.getUriForFile(mContext, author, apk);
12                 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
13             }catch (Exception e){
14                 e.printStackTrace();
15                 Log.e(TAG, "openApkFile: exception = " + e.getMessage() );
16                 return;
17             }
18         } else {
19             data = Uri.fromFile(apk);
20         }
21         intent.setDataAndType(data, "application/vnd.android.package-archive");
22         mContext.startActivity(intent);
23     }

FileProvider.getUriForFile(mContext, author, apk) 生成uri,其中:

  • author   为AndroidManifest 中指定的 android:authorities="cn.com.txw.fileprovider"
  • apk     为文件绝对路径
  • mContext  为Context

3.4 文件的临时权限

上述代码中的 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 增加uri相关临时权限。

mContext.grantUriPermission开启权限

1    uri = FileProvider.getUriForFile(mContext, author, apk);
2    int mode_flags = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
3    mContext.grantUriPermission(mContext.getPackageName(), uri, mode_flags);
4   intent.addFlags(mode_flags);

mContext.revokeUriPermission关闭权限

1    mContext.revokeUriPermission(uri,mode_flags);

  

4.android 8.0的问题

  上述示例是打开apk文件,注意在8.0后要申请”未知来源应用“的安装权限。

 1     private boolean checkPermissions(){
 2         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
 3             String[] permissions = {
 4                     Manifest.permission.WRITE_EXTERNAL_STORAGE,
 5                     Manifest.permission.ACCESS_NETWORK_STATE,
 6                     Manifest.permission.REQUEST_INSTALL_PACKAGES};
 7             final int KG_PERMISSION = 13440;
 8 
 9             int permissionCheck = 0 ;
10 
11             for (String permission : permissions){
12                 permissionCheck += checkSelfPermission(permission);
13             }
14             if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
15                 requestPermissions(permissions,KG_PERMISSION);
16                 return false;
17             }
18         }
19         return true;
20     }

 

posted @ 2017-06-02 23:15  f9q  阅读(1001)  评论(0编辑  收藏  举报