Android应用自动更新功能实现使用AsyncTask!
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
我所開發(fā)應(yīng)用不是面向大眾的應(yīng)用,所以無法放到應(yīng)用市場去讓大家下載,然后通過應(yīng)用市場更新.所以我必要做一個(gè)應(yīng)用自動(dòng)更新功能.但是不難,Thanks to下面這篇博客:
Android應(yīng)用自動(dòng)更新功能的實(shí)現(xiàn)!!!
如果你是以前沒有做過此類功能,建議你先看上面的文章.然后再來看我的.因?yàn)槲乙彩菂⒖剂松厦娴膶?shí)現(xiàn).
? 其實(shí)這個(gè)自動(dòng)更新功能大體就是兩個(gè)三個(gè)步驟:
? ?(1)檢查更新
? ?(2)下載更新
? (3)安裝更新 ?
? ? 檢查更新和下載更新其實(shí)可以算是一步.因?yàn)槎急容^簡單,都是主要是下載.
? ? 1) 當(dāng)你有新的版本發(fā)布時(shí),在一個(gè)位置放一個(gè)更新的文件.
里面到少放有最新應(yīng)用的版本號(hào).然后你拿當(dāng)前應(yīng)用的版本號(hào)和服務(wù)器上的版本號(hào)對(duì)比,就知道要不要下載更新了.
? ?2 ) 下載這個(gè)過程,對(duì)于Java來說不是什么難事,因?yàn)镴ava提供了豐富的API.更何況Android內(nèi)置了HttpClient可用.
? ?3) 這個(gè),安裝過程,其實(shí)就是使用一個(gè)打開查看此下載文件的 Intent.
? 這時(shí)需要考慮的是文件下載后放到哪里,安全否.:
?一般就是先檢測SD卡.然后選擇一個(gè)合適的目錄.
private void checkUpdate() {RequestFileInfo requestFileInfo = new RequestFileInfo();requestFileInfo.fileUrl = "http://www.waitab.com/demo/demo.apk";String status = Environment.getExternalStorageState();if (!Environment.MEDIA_MOUNTED.equals(status)) {ToastUtils.showFailure(getApplicationContext(),"SDcard cannot use!");return;}requestFileInfo.saveFilePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();requestFileInfo.saveFileName = "DiTouchClient.apk";showHorizontalFragmentDialog(R.string.title_wait,R.string.title_download_update);new DownlaodUpdateTask().execute(requestFileInfo);}
上面的進(jìn)度條顯示我已經(jīng)封裝好的了.showHorizontalFragmentDialog()
顯然我使用了android-support-v4兼容包來使用Fragment的.
? 在進(jìn)度條中有顯示,下載文件大小,已經(jīng)下載了多少.速度等信息.
? ?由于涉及到網(wǎng)絡(luò)操作.所以把這整個(gè)邏輯放在AsyncTask中.?
代碼如下:
private class DownlaodUpdateTask extendsAsyncTask<RequestFileInfo, ProgressValue, BasicCallResult> {@Overrideprotected BasicCallResult doInBackground(RequestFileInfo... params) {final RequestFileInfo req = params[0];String apkFileName = "";try {URL url = new URL(req.fileUrl); // throw MalformedURLExceptionHttpURLConnection conn = (HttpURLConnection) url.openConnection();// throws IOExceptionLog.i(TAG, "response code:" + conn.getResponseCode());// 1檢查網(wǎng)絡(luò)連接性if (HttpURLConnection.HTTP_OK != conn.getResponseCode()) {return new BasicCallResult("Can not connect to the update Server! ", false);}int length = conn.getContentLength();double total = StringUtils.bytes2M(length);InputStream is = conn.getInputStream();File path = new File(req.saveFilePath);if (!path.exists())path.mkdir();File apkFile = new File(req.saveFilePath, req.saveFileName);apkFileName = apkFile.getAbsolutePath();FileOutputStream fos = new FileOutputStream(apkFile);ProgressValue progressValue = new ProgressValue(0, " downlaod…");int count = 0;long startTime, endTime;byte buffer[] = new byte[1024];do {startTime = System.currentTimeMillis();int numread = is.read(buffer);endTime = System.currentTimeMillis();count += numread;if (numread <= 0) {// publish endbreak;}fos.write(buffer, 0, numread);double kbPerSecond = Math.ceil((endTime - startTime) / 1000f);double current = StringUtils.bytes2M(count);progressValue.message = String.format("%.2f M/%.2f M\t\t%.2fKb/S", total, current,kbPerSecond);progressValue.progress = (int) (((float) count / length) * DialogUtil.LONG_PROGRESS_MAX);publishProgress(progressValue);} while (true);fos.flush();fos.close();} catch (MalformedURLException e) {e.printStackTrace();return new BasicCallResult("Wrong url! ", false);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();return new BasicCallResult("Error: " + e.getLocalizedMessage(),false);}BasicCallResult callResult = new BasicCallResult("download finish!", true);callResult.result = apkFileName;return callResult;}@Overrideprotected void onPostExecute(BasicCallResult result) {removeFragmentDialog();if (result.ok) {installApk(result.result);} else {ToastUtils.showFailure(getApplicationContext(), result.message);}}@Overrideprotected void onProgressUpdate(ProgressValue... values) {ProgressValue value = values[0];updateProgressDialog(value);}}/*** 安裝更新APK.* * @param fileUri*/private void installApk(String fileUri) {Intent intent = new Intent(Intent.ACTION_VIEW);intent.setDataAndType(Uri.parse("file://" + fileUri),"application/vnd.android.package-archive");startActivity(intent);this.finish();}
PS:Java中傳遞或者返回多個(gè)值,我常用的辦法就是將數(shù)據(jù)封裝到一個(gè)對(duì)象中去.上面用到的一些封裝對(duì)象如下:
傳遞多個(gè)值用對(duì)象是因?yàn)锳syncTask設(shè)計(jì)讓你傳遞一個(gè)對(duì)象作為傳遞參數(shù),所以傳遞對(duì)象也需要這樣使用.
/*** 傳遞給android 設(shè)置進(jìn)度條對(duì)象* * @author banxi1988* */ public final class ProgressValue {/*** 需要設(shè)置的進(jìn)度*/public int progress;/*** 提示信息*/public String message;public ProgressValue(int progress, String message) {super();this.progress = progress;this.message = message;}}
基本的調(diào)用返回對(duì)象:
public class BasicCallResult {public String message;public boolean ok;public String result;public BasicCallResult(String message, boolean ok) {super();this.message = message;this.ok = ok;}}
傳遞下載相關(guān)信息..
public class RequestFileInfo {public String fileUrl;public String saveFilePath;public String saveFileName;}
??
? ??
今天更新到這里,有什么問題,請(qǐng)指出,謝謝.
?
轉(zhuǎn)載于:https://my.oschina.net/banxi/blog/57988
總結(jié)
以上是生活随笔為你收集整理的Android应用自动更新功能实现使用AsyncTask!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 装饰器入门
- 下一篇: Android OpenGL ES 开发