<span style="font-size:14px;">怎麼檢索apk版本,然後自動更新?</span>
<span style="font-size:14px;">一共需要4步</span>
<span style="font-size:14px;">1存儲Bean;</span>
<span style="font-size:14px;">
</span>
package cn.demo.app.bean;
import java.io.Serializable;
public class Update implements Serializable{
private static final long serialVersionUID = -33345024522629534L;
private int versionCode;
private String versionName;
private String downloadUrl;
private String updateLog;
public int getVersionCode() {
return versionCode;
}
public void setVersionCode(int versionCode) {
this.versionCode = versionCode;
}
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
public String getDownloadUrl() {
return downloadUrl;
}
public void setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
public String getUpdateLog() {
return updateLog;
}
public void setUpdateLog(String updateLog) {
this.updateLog = updateLog;
}
@Override
public String toString() {
return "Update [versionCode=" + versionCode + ", versionName="
+ versionName + ", downloadUrl=" + downloadUrl + ", updateLog="
+ updateLog + "]";
}
}
2 管理更新文件:
package cn.demo.app.common;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DecimalFormat;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import cn.haiwan.R;
import com.google.gson.Gson;
/**
* 應用程序更新工具包
* @version 1.1
* @created 2012-6-29
*/
public class UpdateManager {
private static final int DOWN_NOSDCARD = 0;
private static final int DOWN_UPDATE = 1;
private static final int DOWN_OVER = 2;
private static final int DIALOG_TYPE_LATEST = 0;
private static final int DIALOG_TYPE_FAIL = 1;
private static UpdateManager updateManager;
private Context mContext;
//通知對話框
private Dialog noticeDialog;
//下載對話框
private Dialog downloadDialog;
//'已經是最新' 或者 '無法獲取最新版本' 的對話框
private Dialog latestOrFailDialog;
//進度條
private ProgressBar mProgress;
//顯示下載數值
private TextView mProgressText;
//查詢動畫
private ProgressDialog mProDialog;
//進度值
private int progress;
//下載線程
private Thread downLoadThread;
//終止標記
private boolean interceptFlag;
//提示語
private String updateMsg = "";
//返回的安裝包url
private String apkUrl = "";
//下載包保存路徑
private String savePath = "";
//apk保存完整路徑
private String apkFilePath = "";
//臨時下載文件路徑
private String tmpFilePath = "";
//下載文件大小
private String apkFileSize;
//已下載文件大小
private String tmpFileSize;
private String curVersionName = "";
private int curVersionCode;
private Update mUpdate;
private Handler mHandler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case DOWN_UPDATE:
mProgress.setProgress(progress);
mProgressText.setText(tmpFileSize + "/" + apkFileSize);
break;
case DOWN_OVER:
downloadDialog.dismiss();
installApk();
break;
case DOWN_NOSDCARD:
downloadDialog.dismiss();
Toast.makeText(mContext, "無法下載安裝文件,請檢查SD卡是否掛載", 3000).show();
break;
}
};
};
public static UpdateManager getUpdateManager() {
if(updateManager == null){
updateManager = new UpdateManager();
}
updateManager.interceptFlag = false;
return updateManager;
}
/**
* 檢查App更新
* @param context
* @param isShowMsg 是否顯示提示消息
*/
public void checkAppUpdate(Context context, final boolean isShowMsg){
this.mContext = context;
getCurrentVersion();
if(isShowMsg){
if(mProDialog == null)
mProDialog = ProgressDialog.show(mContext, null, "正在檢測,請稍後...", true, true);
else if(mProDialog.isShowing() || (latestOrFailDialog!=null && latestOrFailDialog.isShowing()))
return;
}
final Handler handler = new Handler(){
public void handleMessage(Message msg) {
//進度條對話框不顯示 - 檢測結果也不顯示
if(mProDialog != null && !mProDialog.isShowing()){
return;
}
//關閉並釋放釋放進度條對話框
if(isShowMsg && mProDialog != null){
mProDialog.dismiss();
mProDialog = null;
}
//顯示檢測結果
if(msg.what == 1){
mUpdate = (Update)msg.obj;
if(mUpdate != null){
if(curVersionCode < mUpdate.getVersionCode()){
apkUrl = mUpdate.getDownloadUrl();
updateMsg = mUpdate.getUpdateLog();
showNoticeDialog();
}else if(isShowMsg){
showLatestOrFailDialog(DIALOG_TYPE_LATEST);
}
}
}else if(isShowMsg){
showLatestOrFailDialog(DIALOG_TYPE_FAIL);
}
}
};
new Thread(){
public void run() {
Message msg = new Message();
try {
String data = HttpUtil.sendGet("http://file.demo.com/app/android/update.json","utf-8");
//這個地址是服務器返回給你的
if (data != null) {
Gson gson = new Gson();
Update update = gson.fromJson(data, Update.class);
msg.what = 1;
msg.obj = update;
}
} catch (Exception e) {
e.printStackTrace();
}
handler.sendMessage(msg);
}
}.start();
}
/**
* 顯示'已經是最新'或者'無法獲取版本信息'對話框
*/
private void showLatestOrFailDialog(int dialogType) {
if (latestOrFailDialog != null) {
//關閉並釋放之前的對話框
latestOrFailDialog.dismiss();
latestOrFailDialog = null;
}
AlertDialog.Builder builder = new Builder(mContext);
builder.setTitle("系統提示");
if (dialogType == DIALOG_TYPE_LATEST) {
builder.setMessage("您當前已經是最新版本");
} else if (dialogType == DIALOG_TYPE_FAIL) {
builder.setMessage("無法獲取版本更新信息");
}
builder.setPositiveButton("確定", null);
latestOrFailDialog = builder.create();
latestOrFailDialog.show();
}
/**
* 獲取當前客戶端版本信息
*/
private void getCurrentVersion(){
try {
PackageInfo info = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
curVersionName = info.versionName;
curVersionCode = info.versionCode;
} catch (NameNotFoundException e) {
e.printStackTrace(System.err);
}
}
/**
* 顯示版本更新通知對話框
*/
private void showNoticeDialog(){
AlertDialog.Builder builder = new Builder(mContext);
builder.setTitle("新版本更新");
builder.setMessage(Html.fromHtml(updateMsg));
builder.setPositiveButton("立即更新", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
showDownloadDialog();
}
});
builder.setNegativeButton("以後再說", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
noticeDialog = builder.create();
noticeDialog.show();
}
/**
* 顯示下載對話框
*/
private void showDownloadDialog(){
AlertDialog.Builder builder = new Builder(mContext);
builder.setTitle("正在下載新版本");
final LayoutInflater inflater = LayoutInflater.from(mContext);
View v = inflater.inflate(R.layout.update_progress, null);
mProgress = (ProgressBar)v.findViewById(R.id.update_progress);
mProgressText = (TextView) v.findViewById(R.id.update_progress_text);
builder.setView(v);
builder.setNegativeButton("取消", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
interceptFlag = true;
}
});
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.dismiss();
interceptFlag = true;
}
});
downloadDialog = builder.create();
downloadDialog.setCanceledOnTouchOutside(false);
downloadDialog.show();
downloadApk();
}
private Runnable mdownApkRunnable = new Runnable() {
@Override
public void run() {
try {
String apkName = "HaiwanAPP_"+mUpdate.getVersionName()+".apk";
String tmpApk = "HaiwanAPP_"+mUpdate.getVersionName()+".tmp";
//判斷是否掛載了SD卡
String storageState = Environment.getExternalStorageState();
if(storageState.equals(Environment.MEDIA_MOUNTED)){
savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/HaiwanAPP/Update/";
File file = new File(savePath);
if(!file.exists()){
file.mkdirs();
}
apkFilePath = savePath + apkName;
tmpFilePath = savePath + tmpApk;
}
//沒有掛載SD卡,無法下載文件
if(apkFilePath == null || apkFilePath == ""){
mHandler.sendEmptyMessage(DOWN_NOSDCARD);
return;
}
File ApkFile = new File(apkFilePath);
//是否已下載更新文件
if(ApkFile.exists()){
downloadDialog.dismiss();
installApk();
return;
}
//輸出臨時下載文件
File tmpFile = new File(tmpFilePath);
FileOutputStream fos = new FileOutputStream(tmpFile);
URL url = new URL(apkUrl);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.connect();
int length = conn.getContentLength();
InputStream is = conn.getInputStream();
//顯示文件大小格式:2個小數點顯示
DecimalFormat df = new DecimalFormat("0.00");
//進度條下面顯示的總文件大小
apkFileSize = df.format((float) length / 1024 / 1024) + "MB";
int count = 0;
byte buf[] = new byte[1024];
do{
int numread = is.read(buf);
count += numread;
//進度條下面顯示的當前下載文件大小
tmpFileSize = df.format((float) count / 1024 / 1024) + "MB";
//當前進度值
progress =(int)(((float)count / length) * 100);
//更新進度
mHandler.sendEmptyMessage(DOWN_UPDATE);
if(numread <= 0){
//下載完成 - 將臨時下載文件轉成APK文件
if(tmpFile.renameTo(ApkFile)){
//通知安裝
mHandler.sendEmptyMessage(DOWN_OVER);
}
break;
}
fos.write(buf,0,numread);
}while(!interceptFlag);//點擊取消就停止下載
fos.close();
is.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
}
}
};
/**
* 下載apk
* @param url
*/
private void downloadApk(){
downLoadThread = new Thread(mdownApkRunnable);
downLoadThread.start();
}
/**
* 安裝apk
* @param url
*/
private void installApk(){
File apkfile = new File(apkFilePath);
if (!apkfile.exists()) {
return;
}
Intent i = new Intent(Intent.ACTION_VIEW);
i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
mContext.startActivity(i);
}
}
3 progress.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dip"
android:paddingRight="5dip"
android:orientation="vertical">
<ProgressBar
android:id="@+id/update_progress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"/>
<TextView
android:id="@+id/update_progress_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:textColor="@color/text_blak_light"/>
</LinearLayout>
最後一個是需要放在服務器上的
update.json
{
"versionCode":20111111,
"versionName":"1.0",
"downloadUrl":"http://file.demo.com/app/android/oneapm.apk",
"updateLog":"<b>V0.01</b><br/>1.優化加載速度<br/>2.修復一些BUGS"
}
"versionCode" <pre name="code" class="java">"versionName"
對應manifest裏的versionCode,versionName