APK自动安装——FileProvider

时间:2025-01-26 12:21:54

简介

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/