在app上面有一個版本升級的功能,我們在服務器上傳了新的安裝包之後,就可以點擊更新版本去拿到服務器上面的新包並更新
拿到當前版本的版本號:
/**
* 拿到versionName
*
* @return
*/
public String getPackageVersionName() {
//1.PackageManager 包的管理者對象
PackageManager pm = getPackageManager();
//2.獲取應用的配置信息,在此處傳遞0獲取的是基本信息(包名,版本名稱,版本號)
try {
PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), 0);
String versionName = packageInfo.versionName;
return versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return "";
}
/**
* 拿到versionCode
*
* @return
*/
public int getPackageVersionCode() {
//1.PackageManager 包的管理者對象
PackageManager pm = getPackageManager();
//2.獲取應用的配置信息,在此處傳遞0獲取的是基本信息(包名,版本名稱,版本號)
try {
PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), 0);
int versionCode = packageInfo.versionCode;
return versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return 0;
}
發送請求,拿到新版本的相關信息:
/**
* 請求服務器拿到新的app版本的相關信息
*
* @param updateURL
*/
private void getNewPackInfro(final String updateURL) {
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();//創建OkHttpClient對象
Request request = new Request.Builder()
.url(updateURL)//請求接口。如果需要傳參拼接到接口後面。
.build();//創建Request 對象
Response response = null;
response = client.newCall(request).execute();//得到Response 對象
if (response.isSuccessful()) {
if (response.code() == 200) {
String res = null;
try {
res = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
checkVersion(res);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
private void checkVersion(String res) {
//拿到服務器返回的相關數據
//進行版本比較是否進行升級
System.out.println("返回的升級包數據:"+res);
try {
JSONObject jsonObject = new JSONObject(res);
JSONObject dataStr=new JSONObject(jsonObject.getString("data"));
String version=null;
version=dataStr.getString("version");
if(version.equals("null")){
Toast.makeText(getBaseContext(), "當前已經是最新版本了", Toast.LENGTH_SHORT).show();
}else{
downloadUrl=dataStr.getString("url");
//服務器有新版本,可供下載
runOnUiThread(new Runnable() {
@Override
public void run() {
showDialog();
}
});
}
} catch (JSONException e) {
e.printStackTrace();
}
}
彈出是否下載新版本的提示:
/**
* 檢查更新版本時的消息提示
*/
private void showDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
// builder.setTitle("是否下載新版本?");
builder.setMessage("是否下載新版本");//設置對話框除標題外的描述內容
builder.setPositiveButton("立即更新", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
//下載apk,下載路徑downloadUrl,考慮在何處存儲 files cache() sd卡
downloadApk();
}
});
builder.setNegativeButton("稍後再說", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
//什麼都不做
}
});
builder.setCancelable(false);
builder.show();
}
顯示下載安裝包的進度:
/**
* 下載新的apk文件
*/
private void downloadApk() {
//下載apk,並且指定放置下載文件的路徑,sd卡
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
//創建一個進度條對話框,用於顯示下載進度
progressDialog = new ProgressDialog(this);
//默認情況下對話框進度條圓形轉圈的
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(false);
progressDialog.show();
//手機的sd卡可用
//sd卡存儲文件的路徑
final String path = Environment.getExternalStorageDirectory().getPath() + File.separator + "jizhixinxi/package" + "mobilesafe.apk";
//如何根據downloadUrl進行下載,okhttp下載
OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS).build();
Request request = new Request.Builder().get().url(downloadUrl).build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//請求失敗
Toast.makeText(SystemConfigActivity.this, "下載新版本失敗請稍後重試", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//請求成功,從服務器的響應對象中獲取apk,流(服務器 輸入流(提供數據) 本地 輸出流(寫入文件))
ResponseBody body = response.body();
//告知progressDialog總進度,不變
progressDialog.setMax((int) body.contentLength());
//inputStream就是服務器把需要下載的apk以流的形式提供給客戶端
InputStream inputStream = body.byteStream();
File file = new File(path);
FileOutputStream fos = new FileOutputStream(file);
byte[] bytes = new byte[1024];
int len = 0;
int temp = 0;//用於記錄目前下載的到的位置
while ((len = inputStream.read(bytes)) != -1) {
//將讀過的數據寫入文件中
fos.write(bytes, 0, len);
//告知progressDialog在下載過程中的當前進度
temp += len;
//將當前的下載位置,設置給progressDialog
progressDialog.setProgress(temp);
//沒下載一段數據,睡眠一段時間
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//一旦循環結束,則sd卡中就有一個從服務器下載下來的apk
//下載完成後,則隱藏對話框
progressDialog.dismiss();
//安裝apk,這個要裝的apk在哪裏
installApk(file);
}
});
}
}
讓系統幫我們安裝:
/**
* 安裝指定路徑下的apk
*
* @param file 需要安裝文件的路徑
*/
private void installApk(File file) {
//找到系統的安裝界面,把安裝過程中要用到的東西傳遞進去,讓系統幫助我們安裝.
Intent intent = new Intent("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
//通過隱式意圖開啓系統的安裝apk界面
startActivity(intent);
}