FileProvider

2019-06-10  本文已影响0人  Ci_ci

Android 7.0 开始执行的 StrictMode API 政策禁止在应用外部公开 file:// URI,应用间共享文件必须使用FileProvider,使用content://uri替代file://uri

使用

声明FIleProvider

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.shuxun.bom.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

编写file_paths.xml文件

因为要使用content://uri替代file://uri,那么,content://的 uri 如何定义呢?总不能使用文件路径吧?所以,需要一个虚拟的路径对文件路径进行映射,所以需要编写个xml文件,通过path以及xml节点确定可访问的目录,通过name属性来映射真实的文件路径。

<paths>
    <root-path name="root" path="" />
    <files-path name="name" path="path" /> 
    <cache-path name="name" path="path" /> 
    <external-path name="external_storage_root" path="." />
    <external-files-path name="name" path="path" /> 
    <external-cache-path name="name" path="path" /> 
</paths>

每个节点都支持两个属性:

子节点 含义
root-path Android设备的根目录,该目录下包含着手机内部存储器,外置SD卡等所有文件的目录
external-path 代表外部存储区域的根目录下的文件,Environment.getExternalStorageDirectory()
external-files-path 代表 context.getExternalFilesDirs()
external-cache-path 代表 getExternalCacheDirs()
files-path 代表 context.getFileDir()
cache-path 代表 context.getCacheDir()

使用FileProvider

  val install = Intent(Intent.ACTION_VIEW)
  val apkFile = File(BosApplication.context?.cacheDir, "/$apkPath") 
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        install.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
        val uriForFile = FileProvider.getUriForFile(this, "com.shuxun.bom.fileprovider", apkFile)
        install.setDataAndType(uriForFile, "application/vnd.android.package-archive") }
   else {
        install.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive")
   }

  install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
  startActivity(install)
上一篇下一篇

猜你喜欢

热点阅读