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);
    }

四、總結

以上只是簡單的更新模塊的步驟說明,詳細的代碼在以下地址
https://github.com/YougeView/Update-Module-ForOneClass

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