Android檢測升級並下載安裝工具類

UpdateAppUtils

APP檢測升級與下載APP並安裝的Android原生API的封裝工具類

  • 聯網HttpURLConnection

  • json解析JSONObject

  • 以及進度對話框ProgressDialog

如果需要 更改自己的定製聯網方法與解析可以在相應方法進行更改替換
如果需要自定義對話框與進度框,同樣可以更改替換

需要注意引用v7兼容包,當然可以不引用,需要把import android.support.v7.app.AlertDialog;改爲import android.app.AlertDialog;

調用方法爲:

  /**
    * ************調用示例***********
    * 檢測更新方法,在需要更新的地方調用該方法
    */
    public static void checkUpdate(Context context) {
      //示例檢查更新地址
      String url = "http://localhost:8081/view/app/pub?event=update&platform=android&versionCode=" +    UpdateAppUtils.getVerCode(context);
      //實例化更新工具
      UpdateAppUtils versionUtils = new UpdateAppUtils(context, false);
      //檢查更新
      versionUtils.checkUpdate(url);
  }
 

全部源代碼:

/**
 * UpdateAppUtils 更新版本
 * <p/>
 * 注意需要存儲讀寫權限與聯網權限
 *
 * @author ssy
 * @date 2016/10/18 10:59
 */
public class UpdateAppUtils {
    private static final String TAG = "UpdateAppUtils";
    private String des = null;// 版本描述
    private String apkurl = null;// 新版本url
    private String version;// 版本
    private Context ct;//上下文
    private boolean isShowProgressbar;//是否需要打圈
    private ProgressDialog progressDialog;//打圈框
    private ProgressDialog progressDialog_update;//升級進度框
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0: // 下載完成,點擊安裝
                    if (progressDialog_update.getProgress() == 100) {
                        dismissUpdateDialog();
                        installAPK((File) msg.obj);
                    }
                    break;
                case 1://下載失敗
                    dismissUpdateDialog();
                    showToast("下載失敗,請稍後重試");
                    break;
                case 2://正在下載
                    showToast("正在下載中");
                    break;
                case 3://開始下載,下載中進度
                    float p = (float) msg.obj;
                    setDialogProgress((int) p);
                    break;
                case 111://檢測更新
                    checkIsUpdate((String) msg.obj);
                    break;

            }
        }
    };

     /**
     * ************調用示例***********
     * 檢測更新方法,在需要更新的地方調用該方法
     */
    public static void checkUpdate(Context context) {
        //示例檢查更新地址
        String url = "http://localhost:8081/view/app/pub?event=update&platform=android&versionCode=" + UpdateAppUtils.getVerCode(context);
        //實例化更新工具
        UpdateAppUtils versionUtils = new UpdateAppUtils(context, false);
        //檢查更新
        versionUtils.checkUpdate(url);
    }

    /**
     * 實例化更新工具類
     *
     * @param context           該頁面的上下文
     * @param isShowProgressbar 是否需要顯示檢查更新打圈
     */
    public UpdateAppUtils(Context context, Boolean isShowProgressbar) {
        this.ct = context;
        this.isShowProgressbar = isShowProgressbar;
    }

    /**
     * 得到應用程序的版本號名 VersionName
     *
     * @param ct Context上下文
     */
    public static String getVersionName(Context ct) {
        try {
            // 管理手機的APP
            PackageManager packageManager = ct.getPackageManager();
            // 得到APP功能清單文件
            PackageInfo info = packageManager.getPackageInfo(ct.getPackageName(), 0);
            return info.versionName;
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 得到應用程序的版本 code
     *
     * @param ct Context上下文
     */
    public static int getVerCode(Context ct) {
        int verCode = -1;
        try {
            // 管理手機的APP
            PackageManager packageManager = ct.getPackageManager();
            // 得到APP功能清單文件
            PackageInfo info = packageManager.getPackageInfo(ct.getPackageName(), 0);
            return info.versionCode;
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
        return verCode;
    }

    /**
     * 檢查更新
     *
     * @param url url 地址
     */
    public void checkUpdate(final String url) {

        if (isShowProgressbar) {
            creatProgressbar();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                String result = checkUpdateConnect(url);

                Message msg = handler.obtainMessage();
                msg.what = 111;
                msg.obj = result;
                handler.sendMessage(msg);
            }
        }).start();
    }

    /**
     * 請求服務
     *
     * @param url url
     * @return String
     */
    private String checkUpdateConnect(String url) {
        try {
            HttpURLConnection httpURLConnection = (HttpURLConnection) new URL(url).openConnection();
            httpURLConnection.setConnectTimeout(5 * 1000);//設置連接超時時間
            httpURLConnection.setReadTimeout(10 * 1000);//設置從主機讀取數據超時(單位:毫秒)
            httpURLConnection.setDoInput(true);//打開輸入流,以便從服務器獲取數據
//            httpURLConnection.setDoOutput(true);//打開輸出流,以便向服務器提交數據
            httpURLConnection.setRequestMethod("POST");//設置以Post方式提交數據
            httpURLConnection.setUseCaches(false);//使用Post方式不能使用緩存
            int response = httpURLConnection.getResponseCode(); //獲得服務器的響應碼
            if (response == HttpURLConnection.HTTP_OK) {//200
                InputStream inptStream = httpURLConnection.getInputStream();
                return dealResponseResult(inptStream);
            } else {
                Log.i(TAG, "httpErr:response:" + response);
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 處理服務器的響應結果(將輸入流轉化成字符串)
     *
     * @param inputStream 服務器的響應輸入流
     * @return String
     */
    private String dealResponseResult(InputStream inputStream) {
        String resultData = null; //存儲處理結果
        try {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] data = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(data)) != -1) {
                byteArrayOutputStream.write(data, 0, len);
            }
            byte[] enByte = byteArrayOutputStream.toByteArray();
            resultData = new String(enByte);
            Log.i(TAG, "請求結果爲:" + resultData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultData;
    }

    /**
     * 解析結果,判斷是否升級
     * <p/>
     * 返回json比如:{"data":{"platform":"android","detail":"版本升級","fileName":null,"url":"http://localhost:8085/app.apk","version":"1.0.1"},"code":1,"msg":"操作成功"}
     *
     * @param result json
     */
    private void checkIsUpdate(String result) {
        if (!TextUtils.isEmpty(result)) {
            try {
                JSONObject jsonObject = new JSONObject(result);
                int code = jsonObject.getInt("code");
                if (code == 1) {
                    if (jsonObject.has("data")) {
                        JSONObject data = jsonObject.getJSONObject("data");
                        if (data != null) {
//                            String platform = data.getString("platform");
//                            String fileName = data.getString("fileName");//文件名
                            if (data.has("detail")) {
                                des = data.getString("detail");//描述
                            }
                            if (data.has("url")) {
                                apkurl = data.getString("url");//下載地址
                            }
                            if (data.has("version")) {
                                version = data.getString("version");//版本
                            }

                            //現在爲地址不爲空就提示升級
                            if (!TextUtils.isEmpty(apkurl) && !"NULL".equalsIgnoreCase(apkurl)) {
                                showUpdateDialog();
                            } else {
                                showToast("已是最新版本");
                            }

                            //採用比較versoinName
                            /*if (!TextUtils.isEmpty(version)) {
                                String newVersion = version.replaceAll("\\.", "");
                                String currentVersion = getVersionName(ct);
                                Pattern pattern = Pattern.compile("[0-9]*");
                                Matcher isNum = pattern.matcher(newVersion);
                                Matcher isNumCurr = pattern.matcher(currentVersion);
                                if (isNum.matches() && isNumCurr.matches()) {//是全數字
                                    if ( Long.parseLong(currentVersion) < Long.parseLong(newVersion)) {
                                        showUpdateDialog();
                                    }else{
                                     showToast("已是最新版本");
                                    }
                                }else{
                                     showToast("已是最新版本");
                                 }
                                Log.i(TAG, newVersion+" currentVersion:" + currentVersion);
                            }*/

                            //採用code比較
                            //同上取值判斷

                        } else {
                            showToast("已是最新版本");
                        }
                    } else {
                        showToast("已是最新版本");
                    }
                } else {
                    showToast("檢查更新失敗,請稍後再試");
                }
            } catch (Exception e) {
                showToast("檢查更新失敗,請稍後再試");
                e.printStackTrace();
            }
        } else {
            showToast("檢查更新失敗,請稍後再試");
        }
        dismissProgressbar();
    }

    /**
     * 顯示吐司提示
     */
    private void showToast(String msg) {
        Toast.makeText(ct, msg, Toast.LENGTH_SHORT).show();
    }

    /**
     * 顯示打圈框
     */
    private void creatProgressbar() {
        if (progressDialog == null) {
            progressDialog = new ProgressDialog(ct);
            progressDialog.setCanceledOnTouchOutside(false);
            progressDialog.setMessage("檢查更新中...");
            progressDialog.show();
        } else {
            progressDialog.show();
        }
    }

    /**
     * 取消打圈框
     */
    private void dismissProgressbar() {
        if (progressDialog != null && (progressDialog.isShowing())) {
            progressDialog.dismiss();
        }
    }

    /**
     * 顯示是否升級對話框
     */
    private void showUpdateDialog() {
        if (TextUtils.isEmpty(des)) {
            des = "有新的版本,是否更新?";
        }
        //確認對話框
        AlertDialog.Builder builder = new AlertDialog.Builder(ct);
        builder.setCancelable(false);
        builder.setTitle("新版本");
        builder.setMessage(des);
        builder.setPositiveButton("立刻升級",
                new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        downloadApp();
                        dialog.dismiss();
                    }
                });
        builder.setNegativeButton("下次再說",
                new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
        builder.create().show();

    }

    /**
     * 下載APP
     */
    private void downloadApp() {
        updateDialog();
        startDownloadApp();
    }

    /**
     * 開始下載
     */
    private void startDownloadApp() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    long totalSize;// 文件總大小
                    long downloadCount = 0;// 已經下載好的大小
                    String path;
                    // 下載apk,並且安裝
                    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                        path = ct.getExternalFilesDir(null) + "/apk";
                    } else {
                        path = ct.getFilesDir() + "/apk";
                    }

                    File filePath = new File(path);
                    if (!filePath.exists() || !filePath.isDirectory()) {
                        filePath.mkdirs();
                    }

                    File apkPath = new File(filePath, "app.apk");
                    if (!apkPath.exists()) {
                        apkPath.createNewFile();
                    }

                    URL url = new URL(apkurl);
                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                    httpURLConnection.setConnectTimeout(10 * 1000);
                    httpURLConnection.setReadTimeout(10 * 1000);
                    httpURLConnection.setDoInput(true);
                    // 獲取下載文件的size
                    totalSize = httpURLConnection.getContentLength();
                    int response = httpURLConnection.getResponseCode(); //獲得服務器的響應碼
                    if (response == HttpURLConnection.HTTP_OK) {//200
                        InputStream inputStream = httpURLConnection.getInputStream();
                        FileOutputStream outputStream = new FileOutputStream(apkPath, false);// 文件存在則覆蓋掉
                        byte buffer[] = new byte[1024];
                        int readsize = 0;
                        while ((readsize = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, readsize);
                            downloadCount += readsize;// 時時獲取下載到的大小
                            float progress = downloadCount * 1.0f / totalSize;
                            Message msg = handler.obtainMessage();
                            msg.what = 3;
                            msg.obj = progress * 100;
                            handler.sendMessage(msg);
                            Log.i(TAG, "downloadCount:" + downloadCount);
                        }

                        httpURLConnection.disconnect();
                        outputStream.flush();
                        inputStream.close();
                        outputStream.close();

                        Message msg = handler.obtainMessage();
                        msg.what = 0;
                        msg.obj = apkPath;
                        handler.sendMessage(msg);

                        Log.i(TAG, apkPath + " downloadCount:" + downloadCount);
                    } else {
                        handler.sendEmptyMessage(1);
                        Log.i(TAG, "httpErr:response:" + response);
                    }
                } catch (Exception e) {
                    handler.sendEmptyMessage(1);
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 設置進度
     *
     * @param progress 進度值
     */
    private void setDialogProgress(int progress) {
        progressDialog_update.setProgress(progress);
    }

    /**
     * 顯示下載升級進度的對話框 updateDialog
     */
    private void updateDialog() {
        progressDialog_update = new ProgressDialog(ct);
        progressDialog_update.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog_update.setMessage("正在升級,請稍後");
        progressDialog_update.setMax(100);
        progressDialog_update.setCancelable(false);
        progressDialog_update.setCanceledOnTouchOutside(false);
        progressDialog_update.setProgress(0);
        progressDialog_update.show();
    }

    /**
     * 取消進度框
     */
    private void dismissUpdateDialog() {
        if (progressDialog_update != null && (progressDialog_update.isShowing())) {
            progressDialog_update.dismiss();
        }
    }

    /**
     * 安裝APP
     *
     * @param t File
     */
    private void installAPK(File t) {
        Intent intent = new Intent();
        intent.setAction("android.intent.action.VIEW");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.setDataAndType(Uri.fromFile(t), "application/vnd.android.package-archive");
        ct.startActivity(intent);
    }
}

源碼下載地址:http://download.csdn.net/detail/susanyuanaijia/9680939
點擊進入源代碼GitHub

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章