Android應用-更新模組的實現
阿新 • • 發佈:2019-01-04
一個完整的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);
}