1. 程式人生 > >Android應用-更新模組的實現

Android應用-更新模組的實現

一個完整的app應用都會包含一個更新的功能模組,通過網上查詢相關資料,今天我來簡單說明一下更新模組的實現步驟

一、版本的確認

app要更新一般都是有新版本才要更新,所以首先要確認伺服器端的版本是否比當前客戶端的版本高,如果高就進行後續操作,否則就沒有必要進行下去
1、首先要獲取當前客戶端應用的版本號

//獲取應用當前版本號
    public int getVersionCode() {
        try {
            return context.getPackageManager().getPackageInfo(context.getPackageName(), 0
).versionCode; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return 0; }

2、通過網路請求獲取服務端版本號然後進行版本號對比

//檢查應用版本
    public void checkVersion(final String url) {
        new Thread(new Runnable() {
            @Override
            public
void run() { try { URL requestUrl = new URL(url); HttpURLConnection connection = (HttpURLConnection) requestUrl.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(10 * 1000); connection.setReadTimeout(15
* 1000); if (connection.getResponseCode() == 200) { InputStream is = connection.getInputStream(); String response = read(is); JSONObject jObject = new JSONObject(response); int lastVersion = jObject.getInt(VERSIONCODE); lastName = jObject.getString(VERSIONNAME); downloadUrl = jObject.getString(DOWNLOADURL); description = jObject.getString(DESCRIPTION); if (lastVersion > getVersionCode()) { activity.runOnUiThread(new Runnable() { @Override public void run() { showDialogForUpdate(); } }); } else { activity.runOnUiThread(new Runnable() { @Override public void run() { myToast("當前已經是最新版本"); } }); } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } } }).start(); }

以上方法通過HttpURLConnection物件傳送網路請求,獲取服務端的json檔案,然後通過JSONObject的物件對json檔案進行解析獲取服務端的版本號,如果高於本地應用版本號就彈出dialog提示是否進行更新

二、進行下載任務

下載的實現我通過一個非同步任務來完成,具體下載進度的提示在通知欄

//非同步任務下載
    class DownloadTask extends AsyncTask<String, Integer, File> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            builder = new Notification.Builder(context);
            builder.setContentTitle("開始下載檔案");
            builder.setSmallIcon(R.mipmap.icon_update);
            //設定進度條,false表示為確定的
            builder.setProgress(100, 0, false);
            manager.notify(NOTIFI_DOWNLOAD_ID, builder.build());
        }

        @Override
        protected File doInBackground(String... params) {
            InputStream in = null;
            FileOutputStream out = null;

            String appName = context.getString(context.getApplicationInfo().labelRes);
            int icon = context.getApplicationInfo().icon;
            try {
                URL requrl = new URL(params[0]);
                HttpURLConnection urlConnection = (HttpURLConnection) requrl.openConnection();

                urlConnection.setRequestMethod("GET");
                urlConnection.setDoOutput(false);
                urlConnection.setConnectTimeout(10 * 1000);
                urlConnection.setReadTimeout(10 * 1000);
                urlConnection.setRequestProperty("Connection", "Keep-Alive");
                urlConnection.setRequestProperty("Charset", "UTF-8");
                urlConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");

                urlConnection.connect();
                long bytetotal = urlConnection.getContentLength();
                long bytesum = 0;
                int byteread = 0;
                in = urlConnection.getInputStream();
                File dir = getCacheDirectory(context);
                String apkName = downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1, downloadUrl.length());
                File apkFile = new File(dir, apkName);
                out = new FileOutputStream(apkFile);
                byte[] buffer = new byte[1024 * 10000];

                while ((byteread = in.read(buffer)) > -1) {
                    bytesum += byteread;
                    out.write(buffer, 0, byteread);
                    progress = (int) (((float) bytesum / (float) bytetotal) * 100);
                    publishProgress(progress);
                }
                return apkFile;
            } catch (Exception e) {
            } finally {
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException ignored) {

                    }
                }
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException ignored) {

                    }
                }
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            builder.setProgress(100, values[0], false);
            builder.setContentTitle("正在下載檔案");
            builder.setContentText("當前進度是:" + values[0] + "%");

            Notification notify = builder.build();
            //不讓使用者刪除通知資訊
            notify.flags = Notification.FLAG_NO_CLEAR;
            manager.notify(NOTIFI_DOWNLOAD_ID, notify);
        }

        @Override
        protected void onPostExecute(File result) {
            super.onPostExecute(result);

            if (progress == 100) {
                manager.cancel(NOTIFI_DOWNLOAD_ID);
            }
            if (!result.exists()) {
                myToast("下載失敗");
            } else {
                installAPk(result);
                deleteApk(result);
            }
        }
    }

以上類通過繼承AsyncTask來實現非同步任務常用方法

onPreExecute()//開始非同步任務前呼叫,做一些準備工作
doInBackground//下載過程時呼叫,具體下載操作的實現
onProgressUpdate//當呼叫publishProgress方法之後呼叫,用來更新進度條
onPostExecute//下載完成後的就呼叫該方法,做一下結尾操作

三、安裝軟體

下載完之後,當然要進行安裝

//安裝apk
    private void installAPk(File apkFile) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        //如果沒有設定SDCard寫許可權,或者沒有sdcard,apk檔案儲存在記憶體中,需要授予許可權才能安裝
        try {
            String[] command = {"chmod", "777", apkFile.toString()};
            ProcessBuilder builder = new ProcessBuilder(command);
            builder.start();
        } catch (IOException ignored) {
        }
        intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

四、總結