Android中下载apk文件并安装

Posted zhaihaohao1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android中下载apk文件并安装相关的知识,希望对你有一定的参考价值。

这篇文章是从https://blog.csdn.net/zhaihaohao1/article/details/73848986 简化出来一部分
效果图:

代码:MainActivity中

package com.zhh.test;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class MainActivity extends Activity 
//  按钮
    private Button button;
//  上下文
    private Context mContext;
//  进度条
    private ProgressBar mProgressBar;
//  对话框
    private Dialog mDownloadDialog;
//  判断是否停止
    private boolean mIsCancel = false;
//  进度
    private int mProgress;
//  文件保存路径
    private String mSavePath;
//  版本名称
    private String mVersion_name="1.0";
//  请求链接
    private String url ="https://download.dgstaticresources.net/fusion/android/app-c6-release.apk";
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = MainActivity.this;
        button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                mIsCancel=false;
//              展示对话框
                showDownloadDialog();
            
        );
    


    /*
     * 显示正在下载对话框
     */
    protected void showDownloadDialog() 
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle("下载中");
        View view = LayoutInflater.from(mContext).inflate(R.layout.dialog_progress, null);
        mProgressBar = (ProgressBar) view.findViewById(R.id.id_progress);
        builder.setView(view);

        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() 
            @Override
            public void onClick(DialogInterface dialog, int which) 
                // 隐藏当前对话框
                dialog.dismiss();
                // 设置下载状态为取消
                mIsCancel = true;
            
        );

        mDownloadDialog = builder.create();
        mDownloadDialog.show();

        // 下载文件
        downloadAPK();
    
    /*
     * 开启新线程下载apk文件
     */
    private void downloadAPK() 
        new Thread(new Runnable() 
            @Override
            public void run() 
                try
                    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
                        String sdPath = Environment.getExternalStorageDirectory() + "/";
//                      文件保存路径
                        mSavePath = sdPath + "jikedownload";

                        File dir = new File(mSavePath);
                        if (!dir.exists())
                            dir.mkdir();
                        
                        // 下载文件
                        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
                        conn.connect();
                        InputStream is = conn.getInputStream();
                        int length = conn.getContentLength();

                        File apkFile = new File(mSavePath, mVersion_name);
                        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();
    

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


    /*
     * 下载到本地后执行安装
     */
    protected void installAPK() 
        File apkFile = new File(mSavePath, mVersion_name);
        if (!apkFile.exists())
            return;
        
        Intent intent = new Intent(Intent.ACTION_VIEW);
//      安装完成后,启动app(源码中少了这句话)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Uri uri = Uri.parse("file://" + apkFile.toString());
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        mContext.startActivity(intent);
    


//calss

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.zhh.test.MainActivity"
    android:orientation="vertical"
    >

   <Button
       android:id="@+id/button"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="下载"
       />

</LinearLayout>

对话框布局 dialog_progress.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <ProgressBar
        android:id="@+id/id_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

在AndroidManifest.xml中开权限

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

完了。。。。
注意:在这里用的编译是 targetSdkVersion 22
22对应的是5.0
23对应的是6.0,对权限做了控制参考
https://blog.csdn.net/zhaihaohao1/article/details/81509627
https://blog.csdn.net/zhaihaohao1/article/details/81509909
24对应的是7.0,对访问文件权限收回参考
https://blog.csdn.net/zhaihaohao1/article/details/81809110
源码下载:
https://download.csdn.net/download/zhaihaohao1/10612316

开发者涨薪指南 48位大咖的思考法则、工作方式、逻辑体系

以上是关于Android中下载apk文件并安装的主要内容,如果未能解决你的问题,请参考以下文章

Android项目实战(三十一):异步下载apk文件并安装(非静默安装)

如何在Android上安装apk软件

android怎么获取刚刚下载安装的APK的APP名字和图片

android 修改apk的asset目录后怎么安装

Android 查看apk包名、当前Activity名等

Android系统安装应用程序的几种方法