一個完整的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