android 实现检测版本,下载apk更新(附源码)

Posted 头一回

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 实现检测版本,下载apk更新(附源码)相关的知识,希望对你有一定的参考价值。

其实这不是什么难事了,都有热更新的技术了,只是记录一下,大神勿嘲笑。

先说下思路,首先要有更新的接口,只要进入app,就监测一下接口,是否更新,更新的话,检测本地版本是否低于接口返回的版本,低的话,就根据返回的路径下载apk更新。接口返回的字段起码有 更新标志、更新版本,更新描述,apk下载地址。

更新标志应该有三种状态,更新,询问更新,强制更新,可以启动一个Service(不要忘记在清单文件中注册)来进行检查更新以及下载的工作;

这下面就是 Service里的全部代码,也不是很难理解,重要的地方都有注释。写好Service后,在代码中 startService()启动就可以了。

这里面弹出了一个讯问框,需要在清单文件中 加入权限,  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />,这是弹出全局讯问框的权限。

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Service;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.example.sdtz.wenmingweifang.R;
import com.example.sdtz.wenmingweifang.Tool.OkHttpUtil;
import com.example.sdtz.wenmingweifang.Util.App;
import com.example.sdtz.wenmingweifang.Util.MyUrl;

import org.json.JSONException;
import org.json.JSONObject;

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

/**
 * Created by sdtz on 2017/7/1.
 */
public class UpdateService extends Service {
    private ProgressBar mProgressBar;//进度条
    private TextView tv1;
    private TextView tv2;
    private String url = MyUrl.Httpurl;
    private String VersionCode;
    private String result;
    private App app;
    private String mSavePath;//apk保存地址
    private String mVersion_path;
    private String mVersion_name = "app.apk";//apk名
    private float length;
    private Dialog mDownloadDialog;//对话框
    private int mProgress;//进度值
    private static final int DOWNLOADING = 1;//apk下载中
    private static final int DOWNLOAD_FINISH = 2;//apk下载完毕
    private boolean mIsCancel = false;//是否取消下载标示符

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private Handler mUpdateProgressHandler = new Handler(){
        public void handleMessage(Message msg) {
            switch (msg.what){
                case DOWNLOADING:
                    // 设置进度条
                    mProgressBar.setProgress(mProgress);
                    tv1.setText( mProgress + "/100");
                    float len = length/1024/1024;//将length转换为M单位
                    float b = (float)(Math.round(len*100))/100;//保留两位小数点
                    tv2.setText( b+"M");
                    break;
                case DOWNLOAD_FINISH:
                    // 隐藏当前下载对话框
                    mDownloadDialog.dismiss();
                    // 安装 APK 文件
                    installAPK();
                    break;
                default:
                    break;
            }
        };
    };
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        try {
            VersionCode = getVersionName();
         /*   getJsonReuslt();*/
            new OkHttpUtil().getJson(MyUrl.appdown, new OkHttpUtil.HttpCallBack() {
                @Override
                public void onSusscess(String data) throws JSONException {
                    JSONObject jo1 = new JSONObject(data);
                    app = new App();
                    app.setVersion(jo1.getString("version").toString());
                    app.setDescription(jo1.getString("description").toString());
                    app.setUrl(MyUrl.Httpurl+jo1.getString("url").toString());
                    app.setUpdate_flag(jo1.getString("update_flag").toString());

                    mVersion_path = app.getUrl();
                    //手机当前版本
                    String phoneVersion = VersionCode.substring(0,VersionCode.lastIndexOf("."));
                    Double jiekou = Double.parseDouble(app.getVersion());
                    Double bendi = null;
                    try {
                        bendi = Double.parseDouble(getVersionName());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    Log.d("==","接口:"+jiekou+"本地:"+bendi+"::"+app.toString());
                    //本地版本 与 接口返回版本 不一致,并且 更新标志为1 ,则更新
                    if( !VersionCode.equals(app.getVersion()) && (jiekou>bendi) && app.getUpdate_flag().equals("1")){
                        Log.d("==","::进入");
                        showDialog(app.getDescription());
                    }else if( !VersionCode.equals(app.getVersion()) && (jiekou>bendi) && app.getUpdate_flag().equals("2")){
                        showDownloadDialog();
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        return super.onStartCommand(intent, flags, startId);
    }

    /*
     * 获取当前程序的版本号
     */
    private String getVersionName() throws Exception{
        //获取packagemanager的实例
        PackageManager packageManager = getPackageManager();
        //getPackageName()是你当前类的包名,0代表是获取版本信息
        PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(), 0);
        return packInfo.versionName;
    }


    private void showDialog(String drc) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this,AlertDialog.THEME_HOLO_LIGHT);
        builder.setMessage(drc);

        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                showDownloadDialog();
            }
        });

        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
               dialogInterface.dismiss();
            }
        });

        AlertDialog alertDialog = builder.create();
        alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        alertDialog.setCanceledOnTouchOutside(true);

        alertDialog.show();

        alertDialog.getButton(alertDialog.BUTTON_POSITIVE).setTextColor(Color.GREEN);
        alertDialog.getButton(alertDialog.BUTTON_NEGATIVE).setTextColor(Color.RED);

    }

    /*
     * 开启新线程下载文件
     */
    private void downloadAPK() {

        new Thread(new Runnable() {
            @Override
            public void run() {
                try{//检查sd是否挂载
                    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
                        String sdPath = Environment.getExternalStorageDirectory() + "/";
                        mSavePath = sdPath + "WenmingDownload";

                        File dir = new File(mSavePath);
                        if (!dir.exists())
                            dir.mkdir();
                        // 下载文件
                        HttpURLConnection conn = (HttpURLConnection) new URL(mVersion_path).openConnection();
                        conn.connect();
                        InputStream is = conn.getInputStream();
                        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) ((count/length) * 100);
                            // 更新进度条
                            mUpdateProgressHandler.sendEmptyMessage(DOWNLOADING);

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

    /*
    * 下载到本地后执行安装
    */
    protected void installAPK() {
        File apkFile = new File(mSavePath, mVersion_name);
        if (!apkFile.exists())
            return;

        Intent intent = new Intent(Intent.ACTION_VIEW);
        Uri uri = Uri.parse("file://" + apkFile.toString());
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        this.startActivity(intent);

    }
    /*
     * 显示正在下载对话框
     */
    protected void showDownloadDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("版本更新,下载中。。。");
        View view = LayoutInflater.from(this).inflate(R.layout.dialog_progress, null);
        mProgressBar = (ProgressBar) view.findViewById(R.id.id_progress);
        tv1 = (TextView) view.findViewById(R.id.tv1);
        tv2 = (TextView) view.findViewById(R.id.tv2);
        builder.setView(view);
        mDownloadDialog = builder.create();
        mDownloadDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        mDownloadDialog.show();

        // 下载文件
        downloadAPK();
    }

}

  

以上是关于android 实现检测版本,下载apk更新(附源码)的主要内容,如果未能解决你的问题,请参考以下文章

[android] 手机卫士欢迎页检测更新

如何对Android的版本进行检测与更新

Android差分升级原理和实现方式

android adb 如何检测手机中某个软件的版本?

android 客户端增量更新

Android App内检测更新新版本APK