Android应用自动更新功能实现使用AsyncTask!
為什么80%的碼農都做不了架構師?>>> ??
我所開發應用不是面向大眾的應用,所以無法放到應用市場去讓大家下載,然后通過應用市場更新.所以我必要做一個應用自動更新功能.但是不難,Thanks to下面這篇博客:
Android應用自動更新功能的實現!!!
如果你是以前沒有做過此類功能,建議你先看上面的文章.然后再來看我的.因為我也是參考了上面的實現.
? 其實這個自動更新功能大體就是兩個三個步驟:
? ?(1)檢查更新
? ?(2)下載更新
? (3)安裝更新 ?
? ? 檢查更新和下載更新其實可以算是一步.因為都比較簡單,都是主要是下載.
? ? 1) 當你有新的版本發布時,在一個位置放一個更新的文件.
里面到少放有最新應用的版本號.然后你拿當前應用的版本號和服務器上的版本號對比,就知道要不要下載更新了.
? ?2 ) 下載這個過程,對于Java來說不是什么難事,因為Java提供了豐富的API.更何況Android內置了HttpClient可用.
? ?3) 這個,安裝過程,其實就是使用一個打開查看此下載文件的 Intent.
? 這時需要考慮的是文件下載后放到哪里,安全否.:
?一般就是先檢測SD卡.然后選擇一個合適的目錄.
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);}
上面的進度條顯示我已經封裝好的了.showHorizontalFragmentDialog()
顯然我使用了android-support-v4兼容包來使用Fragment的.
? 在進度條中有顯示,下載文件大小,已經下載了多少.速度等信息.
? ?由于涉及到網絡操作.所以把這整個邏輯放在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檢查網絡連接性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中傳遞或者返回多個值,我常用的辦法就是將數據封裝到一個對象中去.上面用到的一些封裝對象如下:
傳遞多個值用對象是因為AsyncTask設計讓你傳遞一個對象作為傳遞參數,所以傳遞對象也需要這樣使用.
/*** 傳遞給android 設置進度條對象* * @author banxi1988* */ public final class ProgressValue {/*** 需要設置的進度*/public int progress;/*** 提示信息*/public String message;public ProgressValue(int progress, String message) {super();this.progress = progress;this.message = message;}}
基本的調用返回對象:
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;}}
傳遞下載相關信息..
public class RequestFileInfo {public String fileUrl;public String saveFilePath;public String saveFileName;}
??
? ??
今天更新到這里,有什么問題,請指出,謝謝.
?
轉載于:https://my.oschina.net/banxi/blog/57988
總結
以上是生活随笔為你收集整理的Android应用自动更新功能实现使用AsyncTask!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 装饰器入门
- 下一篇: asp.net网站安全常见问题与防范