美文网首页
Android 下载Apk并安装

Android 下载Apk并安装

作者: 黑芝麻胡 | 来源:发表于2019-06-06 09:38 被阅读0次

1、自定义加载进度条 在drawable文件夹下新建 layer_progress.xml文件

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 总进度的颜色 -->
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="5dp" />
            <solid android:color="@color/hint_text_color"/>
        </shape>
    </item>
    <!-- 缓存的颜色 -->
    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <corners android:radius="5dp" />
                <gradient
                    android:endColor="#ffc93a"
                    android:startColor="#ff9f00"/>
            </shape>
        </clip>
    </item>

    <!-- 当前进度的颜色 -->
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="5dp" />
                <gradient
                    android:endColor="#ffc93a"
                    android:startColor="#ff9f00"/>
            </shape>
        </clip>
    </item>

</layer-list>

2、在布局文件update_bar_dialog.xml中 添加自定义的进度条布局 并引用@drawable/layer_progress

image.png
    <ProgressBar
        android:id="@+id/proBar"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="4dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="30dp"
        android:visibility="invisible"
        android:progressDrawable="@drawable/layer_progress" />
image.png

3、强制更新时dialog 设置点击外部和返回键盘 不消失

      //设置点击屏幕不消失
        dialog .setCanceledOnTouchOutside(false);
        //设置点击返回键不消失
        dialog .setCancelable(false);

4、下载并安装的代码 apk_file_url是从后台返回的apk下载的连接地址 例如:http://abc.zzshopping.cn/uploads/files/20190605/70284335bdf6dd5becbf8ade6da98585.apk

   //  进度
    private int mProgress;
    //  文件保存路径
    private String mSavePath;
    //  判断是否停止
    private boolean mIsCancel = false;
  //  版本名称
    private String mVersion_name="1.0";
    /**
     * 下载APk
     * @param apk_file_url
     */
    private void downloadAPK(final String apk_file_url) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
                        String sdPath = Environment.getExternalStorageDirectory() + "/";
//                      文件保存路径
                        mSavePath = sdPath + "oil";
                        File dir = new File(mSavePath);
                        if (!dir.exists()){
                            dir.mkdir();
                        }
                        // 下载文件
                        HttpURLConnection conn = (HttpURLConnection) new URL(apk_file_url).openConnection();
                        conn.connect();
                        InputStream is = conn.getInputStream();
                        int length = conn.getContentLength();

                        File apkFile = new File(mSavePath, AppUtil.getVersionName(mContext));
                        FileOutputStream fos = new FileOutputStream(apkFile);

                        int count = 0;
                        byte[] buffer = new byte[1024];
                        while (!mIsCancel){
                            int numread = is.read(buffer);
                            count += numread;
                            // 计算进度条的当前位置
                            mProgress = (int) (((float)count/length) * 100);
                            // 更新进度条
                            mUpdateProgressHandler.sendEmptyMessage(1);

                            // 下载完成
                            if (numread < 0){
                                mUpdateProgressHandler.sendEmptyMessage(2);
                                break;
                            }
                            fos.write(buffer, 0, numread);
                        }
                        fos.close();
                        is.close();
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        }).start();

    }
    /**
     * 接收消息
     */
    @SuppressLint("HandlerLeak")
    private Handler mUpdateProgressHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 1:
                    // 设置进度条
                    proBar.setProgress(mProgress);
                    break;
                case 2:
                    // 隐藏当前下载对话框
                    dialog.dismiss();
                    // 安装 APK 文件
                    installAPK();
            }
        };
    };

    /**
     * 安装Apk
     */
   private void installAPK() {
        File apkFile = new File(mSavePath, AppUtil.getVersionName(mContext));
        if (!apkFile.exists()) {
            return;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
//      安装完成后,启动app(源码中少了这句话)

        if (null != apkFile) {
            try {
                //兼容7.0
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    Uri contentUri = FileProvider.getUriForFile(mContext, mContext.getPackageName() + ".fileProvider", apkFile);
                    intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
                    //兼容8.0
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        boolean hasInstallPermission = mContext.getPackageManager().canRequestPackageInstalls();
                        if (!hasInstallPermission) {
                            startInstallPermissionSettingActivity();
                            return;
                        }
                    }
                } else {
                    intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                }
                if (mContext.getPackageManager().queryIntentActivities(intent, 0).size() > 0) {
                    mContext.startActivity(intent);
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }

    private void startInstallPermissionSettingActivity() {
        //注意这个是8.0新API
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mContext.startActivity(intent);
    }

兼容7.0 在AndroidManifest.xml 添加权限

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

然后在<application 中添加 <provider 如图

image.png

代码如下 注意 android:authorities 属性 修改为自己的包名

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

相关文章

网友评论

      本文标题:Android 下载Apk并安装

      本文链接:https://www.haomeiwen.com/subject/vkhyxctx.html