• Android 7.0 FileProvider 使用说明


    FileProvider

    FileProvider 这个组件在Android 22.0.0 (也就是 Android 5.0 ) 版本下加入进Android系统,该组件是ContentProvider的子类,功能就是用来提供文件在跨进程间的访问能力。大家千万不要觉得是Android 7.0 才加入进来的。

    为什么Android 7.0 文件共享要使用FileProvider

    这个原因是因为,Android 7.0 版本以后,对于StrictMode的审查又严格了一步,就如在Android 3.0以后加入的NetWorkOnMainThread的异常一样,Google对于会对Android系统造成体验或者安全问题的部分会使用严格模式来限制程序开发者。 
    对于文件访问在Android 7.0以前可以使用file://uri的方式访问,但是这个地方有个问题,就是即使不是你自身应用产生的文件,只要知道对方的uri则就可以调用到,这样在安全性上就产生了风险。所以Android 7.0后新增了对文件跨进程访问的限制,这个限制会造成,如果使用file://uri的方式访问,则会出现android.os.FileUriExposedException的异常。

    FileProvider 使用

    Step 1 AndroidManifest ,注册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>
    

    需要注意的地方是 
    android:authorities 参数,如同ContentProvider,此处需要你提供一个uri的authorities,以便于content://android:authorities/uri访问到,android:authorities可以随意定义

    Step 2 res下创建xml文件夹,并在xml文件夹下创建update_files.xml

    <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>
    

    name:名称标志字符串,不可以同名! 
    path:文件夹“相对路径”,完整路径取决于当前的标签类型。

    标签路径
    …….. * 代表 当前文件夹及其子文件夹
    file-path 物理路径为Context.getFilesDir() + /files/*
    cache-path 物理路径为Context.getCacheDir() + /files/*
    external-path 物理路径为Environment.getExternalStorageDirectory() + /files/*
    external-files-path 物理路径为Context.getExternalFilesDir(String) + /files/*
    external-cache-path 物理路径为Context.getExternalCacheDir() + /files/*

    在简书看到 zhuhf 大神的关于FileProvider的文章后,发现还有一个隐藏的标签

    文章地址: http://www.jianshu.com/p/55eae30d133c

    <root-path name="name" path="path" />
    
    标签路径
    …….. * 代表 当前文件夹及其子文件夹
    root-path 物理路径相当于 /path/*

    Step 3 通过getUriForFile获取到uri

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

    FLAG_GRANT_READ_URI_PERMISSION:表示读取权限; 
    FLAG_GRANT_WRITE_URI_PERMISSION:表示写入权限; 
    根据你的需求,是读取呢,还是写入自行选择

    例子 安装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());
        }
    
  • 相关阅读:
    多态
    SSM前后端分离 ssm+html+js(ajax) 这种controll层的返回值是结合或者网址
    Eclipse创建ssm项目
    在idea中创建Maven项目
    Maven的安装和配置
    IDEA修改快捷键!和一些常用的快捷键
    mysql数据库的安装和连接测试并给root用户赋密码
    ssm动态sql语句
    Java基础--JDBC
    Java基础--注解、反射
  • 原文地址:https://www.cnblogs.com/vijozsoft/p/9304096.html
Copyright © 2020-2023  润新知