Android 程序自动更新功能模块实现--有改动

来源:互联网 发布:windows怎么修改图标 编辑:程序博客网 时间:2024/05/16 06:07

Android 程序自动更新功能模块实现

在程序启动的时候检测服务器上有没有对应版本更新,如果有更新,提示用户是否更新。

在程序启动的时候首先调用更新模块检测服务器上存放的版本号跟当前程序的版本号如果大于当前版本号,弹出更新对话框,如果用户选择更新,则显示当前更新状态,然后替换当前程序。

程序调用版本更新检测:

复制代码
    private UpdateManager updateMan;
private ProgressDialog updateProgressDialog;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//没有判断网路是否连接


//检查是否有更新
//如果有更新提示下载
updateMan = new UpdateManager(Update_TestActivity.this, appUpdateCb);
updateMan.checkUpdate();
}
复制代码

 执行检测版本号以及回调更新提示

下载更新文件等实现:

复制代码
package update.test;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 org.json.JSONArray;import org.json.JSONObject;import com.trinet.util.NetHelper;import android.content.Context;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.util.Log;public class UpdateManager {private String curVersion;private String newVersion;private int curVersionCode;private int newVersionCode;private String updateInfo;private UpdateCallback callback;private Context ctx;    private int progress;  private Boolean hasNewVersion;private Boolean canceled;//存放更新APK文件的路径public static final String UPDATE_DOWNURL = "http://192.168.1.102:8080/web/update/Broadcast.apk";//存放更新APK文件相应的版本说明路径public static final String UPDATE_CHECKURL = "http://192.168.1.102:8080/web/update/update_version.txt";public static final String UPDATE_APKNAME = "Broadcast.apk";//public static final String UPDATE_VERJSON = "ver.txt";public static final String UPDATE_SAVENAME = "Broadcast.apk";private static final int UPDATE_CHECKCOMPLETED = 1; private static final int UPDATE_DOWNLOADING = 2;  private static final int UPDATE_DOWNLOAD_ERROR = 3;  private static final int UPDATE_DOWNLOAD_COMPLETED = 4;  private static final int UPDATE_DOWNLOAD_CANCELED = 5;  private File f_update; //从服务器上下载apk存放文件夹 private String savefolder =Environment.getExternalStorageDirectory() + "/viper_update/";// "/mnt/innerDisk/";public UpdateManager(Context context, UpdateCallback updateCallback) {ctx = context;callback = updateCallback;canceled = false;getCurVersion();}public String getNewVersionName(){return newVersion;}public String getUpdateInfo(){return updateInfo;}private void getCurVersion() {try {PackageInfo pInfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0);curVersion = pInfo.versionName;curVersionCode = pInfo.versionCode;System.out.println("curVersionCode: "+curVersionCode);} catch (NameNotFoundException e) {Log.e("update", e.getMessage());curVersion = "1.1.1000";curVersionCode = 111000;System.out.println("curVersionCode: "+curVersionCode);}}public void checkUpdate() {hasNewVersion = false;new Thread(){@Overridepublic void run() {System.out.println("@@@@@>>>>>>>>>>>>>>>>>>>>>>>>>>>getServerVerCode() ");//Log.i();try {String verjson = NetHelper.httpStringGet(UPDATE_CHECKURL);System.out.println("@@@@"+verjson+ "**************************************************");JSONArray array = new JSONArray(verjson);if (array.length() > 0) {JSONObject obj = array.getJSONObject(0);try {newVersionCode = Integer.parseInt(obj.getString("verCode"));newVersion = obj.getString("verName");updateInfo = "";System.out.println("newVerCode: "+newVersionCode);System.out.println("newVerName: "+newVersion);if (newVersionCode > curVersionCode) {hasNewVersion = true;}} catch (Exception e) {newVersionCode = -1;newVersion = "";updateInfo = "";}}} catch (Exception e) {System.out.println("checkUpdate---err: "+ e.getMessage());}updateHandler.sendEmptyMessage(UPDATE_CHECKCOMPLETED);};// ***************************************************************}.start();}public void update() {f_update = new File(savefolder); if (!f_update.exists()) { f_update.mkdir(); } Intent intent = new Intent(Intent.ACTION_VIEW);intent.setDataAndType(Uri.fromFile(new File(savefolder, UPDATE_SAVENAME)),"application/vnd.android.package-archive");ctx.startActivity(intent);}// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++public void downloadPackage() {System.out.println("downloadPackage------------------");new Thread() { @Override          public void run() {              try {                  URL url = new URL(UPDATE_DOWNURL);                                HttpURLConnection conn = (HttpURLConnection)url.openConnection();                  conn.connect();                  int length = conn.getContentLength();                  InputStream is = conn.getInputStream();                                                   File ApkFile = new File(savefolder,UPDATE_SAVENAME);                                                if(ApkFile.exists())                {                                ApkFile.delete();                }                                                FileOutputStream fos = new FileOutputStream(ApkFile);                                   int count = 0;                  byte buf[] = new byte[512];                                    do{                                      int numread = is.read(buf);                      count += numread;                      progress =(int)(((float)count / length) * 100);                                         updateHandler.sendMessage(updateHandler.obtainMessage(UPDATE_DOWNLOADING));                     if(numread <= 0){                                                  updateHandler.sendEmptyMessage(UPDATE_DOWNLOAD_COMPLETED);                        break;                      }                      fos.write(buf,0,numread);                  }while(!canceled);                  if(canceled)                {                updateHandler.sendEmptyMessage(UPDATE_DOWNLOAD_CANCELED);                }                fos.close();                  is.close();              } catch (MalformedURLException e) {                  e.printStackTrace();                                 updateHandler.sendMessage(updateHandler.obtainMessage(UPDATE_DOWNLOAD_ERROR,e.getMessage()));            } catch(IOException e){                  e.printStackTrace();                                  updateHandler.sendMessage(updateHandler.obtainMessage(UPDATE_DOWNLOAD_ERROR,e.getMessage()));            }                        } }.start();}public void cancelDownload(){canceled = true;}Handler updateHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case UPDATE_CHECKCOMPLETED:callback.checkUpdateCompleted(hasNewVersion, newVersion);break;case UPDATE_DOWNLOADING:callback.downloadProgressChanged(progress);break;case UPDATE_DOWNLOAD_ERROR:callback.downloadCompleted(false, msg.obj.toString());break;case UPDATE_DOWNLOAD_COMPLETED:callback.downloadCompleted(true, "");break;case UPDATE_DOWNLOAD_CANCELED:callback.downloadCanceled();default:break;}}};public interface UpdateCallback {public void checkUpdateCompleted(Boolean hasUpdate,CharSequence updateInfo);public void downloadProgressChanged(int progress);public void downloadCanceled();public void downloadCompleted(Boolean sucess, CharSequence errorMsg);}}
复制代码

需要连接服务器模块:

复制代码
package com.trinet.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

public class NetHelper {

public static String httpStringGet(String url) throws Exception {
return httpStringGet(url, "utf-8");
}

/**
*
*
*
@param url
*
@return
*/
public static Drawable loadImage(String url) {
try {
return Drawable.createFromStream(
(InputStream) new URL(url).getContent(), "test");
} catch (MalformedURLException e) {
Log.e("exception", e.getMessage());
} catch (IOException e) {
Log.e("exception", e.getMessage());
}
return null;
}

public static String httpStringGet(String url, String enc) throws Exception {
// This method for HttpConnection
String page = "";
BufferedReader bufferedReader = null;
try {
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(CoreProtocolPNames.USER_AGENT,
"android");

HttpParams httpParams = client.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 3000);
HttpConnectionParams.setSoTimeout(httpParams, 5000);

HttpGet request = new HttpGet();
request.setHeader("Content-Type", "text/plain; charset=utf-8");
request.setURI(new URI(url));
HttpResponse response = client.execute(request);
bufferedReader = new BufferedReader(new InputStreamReader(response
.getEntity().getContent(), enc));

StringBuffer stringBuffer = new StringBuffer("");
String line = "";

String NL = System.getProperty("line.separator");
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line + NL);
}
bufferedReader.close();
page = stringBuffer.toString();
Log.i("page", page);
System.out.println(page + "page");
return page;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
Log.d("BBB", e.toString());
}
}
}
}

public static boolean checkNetWorkStatus(Context context) {
boolean result;
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netinfo = cm.getActiveNetworkInfo();
if (netinfo != null && netinfo.isConnected()) {
result = true;
Log.i("NetStatus", "The net was connected");
} else {
result = false;
Log.i("NetStatus", "The net was bad!");
}
return result;
}
}
复制代码

以及提示对话框:

复制代码
package com.trinet.util;

import java.lang.reflect.Field;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.view.View;

public class DialogHelper {

public static void Alert(Context ctx, CharSequence title, CharSequence message,
CharSequence okText, OnClickListener oklistener) {
AlertDialog.Builder builder = createDialog(ctx, title, message);
builder.setPositiveButton(okText, oklistener);
builder.create().show();
}

public static void Alert(Context ctx, int titleId, int messageId,
int okTextId, OnClickListener oklistener) {
Alert(ctx, ctx.getText(titleId), ctx.getText(messageId), ctx.getText(okTextId), oklistener);
}

public static void Confirm(Context ctx, CharSequence title, CharSequence message,
CharSequence okText, OnClickListener oklistener, CharSequence cancelText,
OnClickListener cancellistener) {
AlertDialog.Builder builder = createDialog(ctx, title, message);
builder.setPositiveButton(okText, oklistener);
builder.setNegativeButton(cancelText, cancellistener);
builder.create().show();
}

public static void Confirm(Context ctx, int titleId, int messageId,
int okTextId, OnClickListener oklistener, int cancelTextId,
OnClickListener cancellistener) {
Confirm(ctx, ctx.getText(titleId), ctx.getText(messageId), ctx.getText(okTextId), oklistener, ctx.getText(cancelTextId), cancellistener);
}

private static AlertDialog.Builder createDialog(Context ctx, CharSequence title,
CharSequence message) {
AlertDialog.Builder builder = new Builder(ctx);
builder.setMessage(message);
if(title!=null)
{
builder.setTitle(title);
}
return builder;
}

@SuppressWarnings("unused")
private static AlertDialog.Builder createDialog(Context ctx,int titleId, int messageId) {
AlertDialog.Builder builder = new Builder(ctx);
builder.setMessage(messageId);
builder.setTitle(titleId);
return builder;
}

public static void ViewDialog(Context ctx, CharSequence title, View view,
CharSequence okText, OnClickListener oklistener, CharSequence cancelText,
OnClickListener cancellistener) {

}

public static void ViewDialog(Context ctx, int titleId, View view,
int okTextId, OnClickListener oklistener, int cancelTextId,
OnClickListener cancellistener) {

ViewDialog(ctx, ctx.getText(titleId), view, ctx.getText(okTextId), oklistener, ctx.getText(cancelTextId), cancellistener);

}

//
public static void SetDialogShowing(DialogInterface dialog, boolean showing)
{
try {
Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");
field.setAccessible(true);
field.set(dialog, showing);
} catch (Exception e) {
e.printStackTrace();
}
}

}
复制代码

下面是又更新的话执行回调函数提示用户:

复制代码
// 自动更新回调函数
UpdateManager.UpdateCallback appUpdateCb = new UpdateManager.UpdateCallback()
{

public void downloadProgressChanged(int progress) {
if (updateProgressDialog != null
&& updateProgressDialog.isShowing()) {
updateProgressDialog.setProgress(progress);
}

}

public void downloadCompleted(Boolean sucess, CharSequence errorMsg) {
if (updateProgressDialog != null
&& updateProgressDialog.isShowing()) {
updateProgressDialog.dismiss();
}
if (sucess) {
updateMan.update();
} else {
DialogHelper.Confirm(Update_TestActivity.this,
R.string.dialog_error_title,
R.string.dialog_downfailed_msg,
R.string.dialog_downfailed_btnnext,
new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog,
int which) {
updateMan.downloadPackage();

}
}, R.string.dialog_downfailed_btnnext, null);
}
}

public void downloadCanceled()
{
// TODO Auto-generated method stub

}

public void checkUpdateCompleted(Boolean hasUpdate,
CharSequence updateInfo) {
if (hasUpdate) {
DialogHelper.Confirm(Update_TestActivity.this,
getText(R.string.dialog_update_title),
getText(R.string.dialog_update_msg).toString()
+updateInfo+
getText(R.string.dialog_update_msg2).toString(),
getText(R.string.dialog_update_btnupdate),
new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog,
int which) {
updateProgressDialog = new ProgressDialog(
Update_TestActivity.this);
updateProgressDialog
.setMessage(getText(R.string.dialog_downloading_msg));
updateProgressDialog.setIndeterminate(false);
updateProgressDialog
.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
updateProgressDialog.setMax(100);
updateProgressDialog.setProgress(0);
updateProgressDialog.show();

updateMan.downloadPackage();
}
},getText( R.string.dialog_update_btnnext), null);
}

}
};
复制代码

 

要记得给程序添加权限:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


测试源码下载:

http://dl.dbank.com/c0f2pa9gwj


update_verson.txt 的内容解码出来了:


{"verCode" : "3","verName" : "3.0"}
]