Android实践 -- 使用FileProvider安全的共享文件 简介篇

使用FileProvider安全的共享文件 简介篇

应用篇

FileProviderContentProvider的一个子类,可以通过content://uri的方式更安全的共享文件
可以在通过URI的方式共享文件时,可以通过IntentsetFlags()赋予文件临时的读写权限,不需要
设置全局的读写权限

定义一个FileProvider

不需要继承FileProvider,只需要在AndroidManifest.xml中定义一个<provider>的组件即可,设置
android:name的属性为android.support.v4.content.FileProvider,设置android:authorities
的属性为packange_name.fileprovider,设置android:exported的属性值为false,因为FileProvider
不需要公开,设置android:grantUriPermissions="true" 这样可以增加临时权限,在meta-data中指出
需要共享的文件夹路径

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

可以共享的文件

meta-data中需要指定需要共享的文件,有哪些文件可以通过FileProvider来共享呢,需要在
xml/filepaths.xml中配置相关的路径,一般的格式如下

  <paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="my_images" path="images/"/>
    ...
  </paths>

paths中可以包含一个或多个子元素,name="name"这个属性相当于path的别名可以隐藏子目录
path="path"就是你要共享的目录

  • 应用的内部资源

    可以通过Context.getFilesDir()获得的路径的子目录

    <files-path name="name" path="path" />
    
  • 应用内部的缓存文件夹

    可以通过getCacheDir()获得的路径的子目录

    <cache-path name="name" path="path" />
    
  • sdcard文件

    可以通过 Environment.getExternalStorageDirectory()获得的子目录

    <external-path name="name" path="path" />
    
  • 应用的外部储存目录

    可以通过Context.getExternalFilesDir(String)获得的子目录

    <external-files-path name="name" path="path" />
    
  • 应用的外部缓存目录

    可以通过Context.getExternalCacheDir()获得的子目录

    <external-cache-path name="name" path="path" />
    

生成文件的URI

为了和另外一个app利用content URI的方式共享文件,我们需要生成这个文件的URI,可以通过
getUriForFile()方法生成文件的URI

  File imagePath = new File(Context.getFilesDir(), "images");
  File newFile = new File(imagePath, "default_image.jpg");
  Uri contentUri = getUriForFile(getContext(), "com.mydomain.fileprovider", newFile);

赋予URI临时权限

  • IntentsetData()方法,将数据放进Intent
  • 通过IntentsetFlags()方法设置临时权限 FLAG_GRANT_READ_URI_PERMISSION or FLAG_GRANT_WRITE_URI_PERMISSION或者both
  • Intent发送到另一个app

接受处理Intent

另一个app接受处理对应的文件即可

更多精彩内容