简介
app经常需要向其他应用提供一个或多个文件。例如,一个图片画廊可能要向图片编辑器提供文件,或者一个文件管理app需要允许使用者复制和粘贴文件到外部存储器中。一种方法是,发送端app可以通过接收端app的请求进行响应来共享一个文件。
在所有情况下,从你的app向其他app提供一个文件的唯一安全方式是,通过content URL 向接收端app发送这个文件,并且授权URL的临时访问权限。Content URLs 的临时 URL 访问权限是安全的,因为这个申请只对这个app接收 URL ,并且它会自动终止。Android 的FileProvider 组件提供了 getUriForFile()
方法,用来生成文件的 content URL 。
如果你想要在app之间分享一些文本或者数字数据,你应该发送一个包含数据data的 Intent 。想要学习怎么使用 Intent 发送简单的数据,请看培训教程:Sharing Simple Data.
这门课解释了如何安全地,从应用程序到另一个应用程序共享文件,使用Android FileProvider组件来生成的URI和临时权限授予接收应用程序内容URI。
前往课程:Setting Up File Sharing
这节课向你展示了如何为你的应用程序添加默认的FileProvider接口,以及如何指定你想提供给其他应用程的文件。
注意: FileProvider 类是v4包中的一部分,请确保你的应用包含这个库。
1. 指定 FileProvider
在manifest中为你的app定义一个FileProvider请求入口。该入口指定在生成内容uri时使用的权限,就像一个xml文件的名字一样,指定你app能分享的的目录。
下面的代码展示了怎么向你的manifest中添加<provider>元素,指定FileProvider类,权限和xml文件名字。
<manifest xmlns:andro
package="">
<application
...>
<provider
android:name="."
android:authorities=""
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name=".FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
...
</application>
</manifest>
xmlns:andro
package="">
<application
...>
<provider
android:name="."
android:authorities=""
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name=".FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
...
</application>
</manifest>
在这个例子中, android:authorities 属性指定了你想要通过FileProvide产生的 URL 权限。在这个例子中,权限是:。
对于你自己的app,可以指定一个由app包名加上字符"fileprovider"拼接而成的权限。想要学习更多关于权限和android:authorities属性,请参考Content URIs。
2.指定可分享的目录
一旦你添加了FileProvider到你的manifest中,你就需要指定包含了你想要分享的文件目录。为了指定目录,首先应该在你的工程中的 res/xml/
子目录下创建 文件。在这个文件中,通过为每个目录添加一个xml节点来指定目录。下面的片段展示了res/xml/文件的内容。这个片段也示范了怎么分享一个你内置存储中的文件子目录。
<paths>
<files-path path="images/" name="myimages" />
</paths>
<files-path path="images/" name="myimages" />
</paths>
比如:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="aitoutiao"
path="Android/data//" />
<external-path
name="external_storage_root"
path="." />
</paths>
<files-path>
中指定了你app存储中的分享文件目录,path属性分配了files文件夹下面的iamges.子目录。name 属性告诉了FileProvider添加路径段在 files/images/子目录下的myimages到 content UIRs中,。
<paths>节点可以有多个子节点,来指定多个不同的分享目录。除了<files-path>节点之外,你可以使用<external-path>节点来分享外部存储中的目录, <cache-path>
节点可以分享内部缓存中的目录。
注意:XML 文件是你想要分享的唯一指定的目录,你不能以编程的方式来添加目录。
您现在拥有了一个完整规范的FileProvider,生成内容文件的uri文件,在应用程序的内部存储files/下或files/子目录下的文件。当你的app产生一个文件content URL时,应该在<provider>节点中指定权限,myimages/路径和文件的名字。
例如,如果你根据这篇课程中的片段定义了一个FileProvider,你为文件default_image.jpg请求一个content URL FileProvider,返回下面的URL:
content:///myimages/default_image.jpg
获取URL:
File imagePath = new File(Context.getFilesDir(), "images");
File newFile = new File(imagePath, "default_image.jpg");
Uri contentUri = getUriForFile(getContext(), "", newFile);
imagePath = new File(Context.getFilesDir(), "images");
File newFile = new File(imagePath, "default_image.jpg");
Uri contentUri = getUriForFile(getContext(), "", newFile);
3. 调启应用安装界面
添加权限:
<uses-permission android:name=".INSTALL_PACKAGES" />
/**
* 安装apk
*/
public void installApk(Context context, String filePath) {
File apkfile = new File(filePath);
if (!()) {
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
if (.SDK_INT >= Build.VERSION_CODES.N) {
(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = (context, "", apkfile);
(contentUri, "application/-archive");
} else {
((apkfile), "application/-archive");
(Intent.FLAG_ACTIVITY_NEW_TASK);
}
(intent);
("tag", "apk正在安装...");
}
注意报名一定要填写对了!
FileProvider API: /reference/android/support/v4/content/
Sharing a File: /training/secure-file-sharing/
Sending Simple Data to Other Apps:https: ///training/sharing/