一、動態獲取項目清單版本信息
有時候我們在更新了軟件之後需要將新的軟件版本信息顯示到界面我們該如何動態的操作呢?PackageManager : 用來管理Apk
創建一個方法用來動態獲取項目清單的版本信息
public String getVersionName(){
//用來管理手機的Apk
PackageManager manager = getPackageManager();
try {
//得知Apk功能清單項目
PackageInfo info = manager.getPackageInfo(getPackageName(), 0);
//返回項目清單裏面的版本名稱
return info.versionName;
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
注意這裏的是: 如果在項目清單中配置過版本信息,那麼就不能在低於配置版本信息的版本號了,不然會報錯的<span style="white-space:pre"> </span>Installation error: INSTALL_FAILED_VERSION_DOWNGRADE
/**
* 判斷是否可更新
*/
public String CheckUpdate() {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
URL url = new URL(getString(R.string.serverurl));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
int responseCode = connection.getResponseCode();
if(responseCode == 200){
InputStream inputStream = connection.getInputStream();
String result = StreamTools.readFromStream(inputStream);
Log.d(TAG, result);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
return null;
}
鏈接服務器查看版本更新信息
在程序啓動的時候會鏈接服務器獲取最新版本信息,然後將自己的版本跟從服務器獲取的版本信息進行對比,如
果不一致(有最新版本)則提示用戶更新。
注意:1、這裏我們使用到了網絡,因此要在清單文件中添加 android.permission.INTERNET 權限。2、因爲訪問網
絡是“耗時”過程,因此我們把檢查版本更新業務要放在子線程中進行。
/**
* 判斷是否可更新
*/
private void CheckUpdate() {
new Thread(new Runnable() {
@Override
public void run() {
long StartTime = java.lang.System.currentTimeMillis();
// TODO Auto-generated method stub
// 不要new ,直接獲取
Message message = new Message();
try {
URL url = new URL(getString(R.string.serverurl));
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.connect();
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
InputStream inputStream = connection.getInputStream();
String result = StreamTools.readFromStream(inputStream);
Log.d(TAG, result);
// 解析JSON,
JSONObject object = new JSONObject(result);
// 解析出來的信息,包括版本,升級內容,升級地址
Object version = object.get("version");
description = (String) object.get("description");
apkurl = (String) object.get("apkurl");
Log.d(TAG, "版本信息 :" + version);
if (getVersionName().equals(version)) {
// 進入主頁
message.what = ENTER_HOME;
} else {
// 顯示下載dialog
message.what = SHOW_DIALOG;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
message.what = EXCEPITON;
} finally {
long Endtime = java.lang.System.currentTimeMillis();
//所用時間
long Dtime = Endtime - StartTime;
if(Dtime < 2000){
try {
Thread.sleep(2000 - Dtime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
handler.sendMessage(message);
}
}
}).start();
}
在 onCreate 方法中,給 Splash 界面添加啓動畫面。這裏添加的是漸變動畫,透明度從 0 到 1 漸變,時長 500 毫秒AlphaAnimation alphaAnimation = new AlphaAnimation(0.f, 1.f);
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.rl_root);
alphaAnimation.setDuration(500);
relativeLayout.startAnimation(alphaAnimation);
發送到handler裏面之後,我們進行判斷,發送的內容,是進行升級還是,直接進入主界面,還是拋出了異常
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case ENTER_HOME:
EnterHome();
break;
case SHOW_DIALOG:
// Toast.makeText(MainActivity.this, "新版本信息內容 : " +
// description, Toast.LENGTH_SHORT).show();
// 升級應用程序
showUpdateDialog();
break;
case EXCEPITON:
EnterHome();
Toast.makeText(MainActivity.this, "Unknown Error",
Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
};
這裏我們可以看出如果是沒有更新就直接進入主界面,如果有我們就在showUpdateDialog裏面進行更新,拋出異常了得話
我們提醒用戶出錯,進入主界面這裏就不演示了自己實現
private void showUpdateDialog() {
// TODO Auto-generated method stub
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("發現新版本");
builder.setMessage("已經發布新版本了,希望您能及時升級。");
builder.setCancelable(false);
builder.setPositiveButton("升級", new OnClickListener() {
@Override
public void onClick(final DialogInterface dialog, int which) {
// TODO Auto-generated method stub
// 安裝並替換
// 一般下載的安裝包會放在sd卡上
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
// 這裏使用框架進行下載
FinalHttp finalHttp = new FinalHttp();
finalHttp.download(apkurl, Environment.getExternalStorageDirectory().getAbsolutePath()+"/mobilesafe3.0.apk", new AjaxCallBack<File>() {
/*
* 下載錯誤
*/
@Override
public void onFailure(Throwable t, int errorNo,
String strMsg) {
// TODO Auto-generated method stub
t.printStackTrace();
//print Error Log
Toast.makeText(getApplicationContext(), "下載出錯", 0).show();
super.onFailure(t, errorNo, strMsg);
}
/*
* 正在下載
*/
@Override
public void onLoading(long count, long current) {
// TODO Auto-generated method stub
super.onLoading(count, current);
int values = (int) (current * 100 / count);
progress.setText("下載進度" +values+ "%");
}
/*
* 下載成功
*/
@Override
public void onSuccess(File t) {
// TODO Auto-generated method stub
super.onSuccess(t);
Toast.makeText(getApplicationContext(), "下載成功", 0).show();
installAPK(t);
}
private void installAPK(File t) {
// TODO Auto-generated method stub
/**
* 安裝APK
*/
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.setDataAndType(Uri.fromFile(t), "application/vnd.android.package-archive");
startActivity(intent);
}
});
} else {
Toast.makeText(getApplicationContext(), "請安裝好sd卡後再試試", 0)
.show();
return;
}
}
});
builder.setNegativeButton("下次下載", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
/*
* 消掉對話框進入主頁面
*/
dialog.dismiss();
EnterHome();
}
});
builder.show();
}
這裏在下載新版本安裝包時需要使用到框架afinal,這裏不過多介紹.
這樣一個進入界面檢查版本是否需要更新,更新彈出更新或者不更新的Dialog就創建好了