Android 下载并安装apk,兼容7.0和8.0

一、下载apk文件

下载的方式有不少种,经常使用的有:android

(1)调用系统下载器下载,须要设置通知来接受下载完成的操做,而后进入安装流程浏览器

(2)最简单的,直接调起系统浏览器访问apk下载连接,后续的事情都无论,等下载完了用户自行安装网络

(3)本身写下载代码,缺点是不如前二者稳定,优势是下载进度和状态可控app

我这里使用的是第三种,而后下载代码并不本身写,而是直接调用OkHttpUtils框架,OkHttpUtils框架的配置跟导入这里再也不赘述,具体本身查一下用法,直接上下载代码(不要忘了网络权限跟存储权限):框架

isDownloading = true;//是否正在下载,同一时间不给同时进行多个下载任务
        final TextLoadingPopupWindow textLoadingPopupWindow = new TextLoadingPopupWindow(getActivity());//进度提示弹窗,具体替换本身的弹窗,这里不提供
        textLoadingPopupWindow.setText("00.0%");
        textLoadingPopupWindow.show();
        OkHttpUtils.get(url)
                .execute(new FileCallback(new PathUtil().getMusicEditorPath(), UUID.randomUUID().toString() + ".apk") {//这里指定下载保存文件的路径
                    @Override
                    public void onSuccess(File file, Call call, Response response) {
                        isDownloading = false;
                        textLoadingPopupWindow.dismiss();
                        installApp(file);//下载完成,调起安装
                    }

                    public void onError(Call call, Response response, Exception e) {
                        isDownloading = false;
                        textLoadingPopupWindow.dismiss();
                        ToastUtils.showToast(getContext(), "下载出错");
                    }

                    public void downloadProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
                        textLoadingPopupWindow.setText((int) (progress * 100) + "." + (int) (progress * 1000) % 10 + "%");//进度显示,处于UI线程
                    }
                });

二、安装apk

文件准备好了以后就是安装了,安装主要须要注意7.0和8.0两个系统的兼容.dom

(1)7.0适配ide

须要用到fileprovider,须要在res文件夹下建立一个xml文件,我这里叫xxxxxx.xml,主要就是配置几个路径,你须要安装的apk文件在调用安装以前,须要先移到这几个路径之下才能够。ui

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="xxxxx" path="xxxxx" />
</paths>

xml准备好了以后,须要去AndroidManifest.xml里面配置一下url

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="这里替换成你的包名.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/xxxxx" />
        </provider>

(2)8.0适配spa

适配了7.0以后,8.0基本上没啥问题了,惟一的区别就是8.0须要加上一个权限

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

若是以为有必要的话,8.0能够在调起安装以前校验一下本应用是否已经有了能够安装其余应用的权限,若是没有则直接跳转到手机设置的相关页面,这里须要说一下,在我亲测的几台手机中,若是使用了这个逻辑,基本上是会跳转到一个设置页面,页面是一箩筐的应用列表,很难找到本身的app并进去设置“容许安装未知应用”这个东西,我的以为这个体验很很差,而若是是直接调用安装代码,则系统会自发的提示是否须要开启这个应用“容许安装未知应用”的这个东西,因此这里的代码就是执行直接调起安装操做,是否具有权限就不验证了。

/**
     * 调起安装
     *
     * @param file
     */
    private void installApp(File file) {
        if (file == null || !file.getPath().endsWith(".apk")) {
            return;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);

        //判读版本是否在7.0以上
        if (Build.VERSION.SDK_INT >= 24) {
            Uri apkUri = FileProvider.getUriForFile(getActivity(), "你的包名.fileprovider", file);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        } else {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        }
        getActivity().startActivity(intent);
    }

本代码在7.0的vivo手机和8.0的小米手机上亲测有效。

相关文章
相关标签/搜索