流程:1.到服务器那边拉去配置文件,然后解析配置文件来获取应用的地址,版本号,大小,md5和配置的更新的方式(可选更新与强制更新);
2.断点续传方式拉去apk。
一下为代码:
- import java.io.BufferedInputStream;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.RandomAccessFile;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import org.apache.http.HttpResponse;
- import org.apache.http.HttpStatus;
- import org.apache.http.client.ClientProtocolException;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.protocol.HTTP;
- import org.apache.http.util.EntityUtils;
- import org.json.JSONObject;
- import com.longjiang.youzhong.R;
- import com.uzone.util.Md5Check;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.app.ProgressDialog;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.content.pm.PackageInfo;
- import android.content.pm.PackageManager.NameNotFoundException;
- import android.net.Uri;
- import android.os.AsyncTask;
- import android.os.Bundle;
- import android.os.Environment;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.view.WindowManager;
- //下载配置的资源文件->解析资源文件来获取版本号和apk的下载地址、更新的方式的信息->对比版本号:(1)不需要更新,直接返回;(2)需要更新:a,强制更新 ;b,可选择更新.更新流程1.下载apk并且提示进度,下载完后自动安装
- public class VersionActivity extends Activity{
- //请求配置服务器的配置文件url
- private static String requestUrl="http://192.168.1.46/updateversion/updateversion.php";
- private static String version ;
- private static String apkDownUrl;
- private static int updateType;//1,表示可以选择更新;2,表示强制更新
- private static ProgressDialog checkDialog;
- private static Activity context;
- private static MyHandler mHandler;
- private static int retry;
- private static String path;
- private static String packageName;
- private static String md5;
- private static long fileTotalSize;
- private static ProgressDialog pbar;
- private String tag="VersionActivity";
- private int TryDownTotal=5;//下载失败再次尝试的次数
- private static String fileName="longjiang.apk";
- private interface DialogHandler{
- void fun();
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
- setContentView(R.layout.yzupdate);
- pbar =new ProgressDialog(this);
- context=this;
- mHandler=new MyHandler();
- checkDialog = ProgressDialog.show(this, null, getString(R.string.version_check_msg), true);
- checkDialog.setCancelable(false);
- checkVersion();
- }
- public static void checkVersion()
- {
- //下载配置服务器的配置文件
- new Thread(new Runnable() {
- @Override
- public void run() {
- // HttpGet连接对象
- HttpGet httpRequest = new HttpGet(requestUrl);
- try {
- // 取得HttpClient对象
- HttpClient httpclient = new DefaultHttpClient();
- // 请求HttpClient,取得HttpResponse
- HttpResponse httpResponse = httpclient.execute(httpRequest);
- // 请求成功
- if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
- String jsonResult = EntityUtils.toString(
- httpResponse.getEntity(), HTTP.UTF_8);
- JSONObject paramsjson = new JSONObject(jsonResult);
- version=paramsjson.optString("version");
- apkDownUrl=paramsjson.optString("apkDownUrl");
- updateType=paramsjson.optInt("updateType");
- md5=paramsjson.optString("md5");
- fileTotalSize=Long.valueOf(paramsjson.optString("size"));
- Message msg = Message.obtain(mHandler);
- msg.what = 0;
- //msg.obj = resultObj;
- mHandler.sendMessage(msg);
- } else {
- //提示下载出错了
- Message msg = Message.obtain(mHandler);
- msg.what = 1;
- //msg.obj = resultObj;
- mHandler.sendMessage(msg);
- }
- } catch (ClientProtocolException e) {
- } catch (IOException e) {
- } catch (Exception e) {
- }
- }
- }).start();
- }
- //只考虑两种状态,左边的button单独存在或者两个button同时存在
- private static void showDialog(String title,String content,String rightButton,String leftButton,final DialogHandler Rhandler,final DialogHandler Lhandler)
- {
- if(rightButton==null)
- {
- new AlertDialog.Builder(context)
- .setTitle(title)
- .setMessage(content)
- .setCancelable(false)
- .setPositiveButton(leftButton,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.dismiss();
- if(Lhandler!=null)
- Lhandler.fun();
- }
- }).show();
- }
- else if(leftButton!=null&&rightButton!=null)
- {
- new AlertDialog.Builder(context)
- .setTitle(title)
- .setMessage(content)
- .setCancelable(false)
- .setPositiveButton(leftButton,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.dismiss();
- Lhandler.fun();
- }
- })
- .setNegativeButton(rightButton,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- dialog.dismiss();
- if(Rhandler!=null)
- Rhandler.fun();
- }
- }).show();
- }
- }
- private class MyHandler extends Handler {
- @Override
- public void handleMessage(final Message msg) {
- switch (msg.what) {
- case 0:
- //检查apk的版本号
- checkDialog.dismiss();
- PackageInfo info;
- try {
- info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
- // 当前应用的版本名称
- //String versionName = info.versionName;
- // 当前版本的版本号
- int versionCode = info.versionCode;
- packageName=info.applicationInfo.packageName;
- //启动升级
- if(versionCode<Integer.valueOf(version))
- {
- //升级代码
- //可选择的更新
- if(updateType==1)//test 0
- {
- showDialog(context.getString(R.string.updatetitle),"是否从当前版本号"+versionCode+"升级到版本号"+version,"现在升级","以后再更新",new DialogHandler(){
- public void fun(){
- predownloadapk();
- }
- }
- , new DialogHandler(){
- public void fun(){ startGame(); }
- });
- }
- //强制更新
- else if(updateType==1)
- {
- showDialog(context.getString(R.string.updatetitle),"请点击确定更新为最新版本:"+version,null,"确定",null, new DialogHandler(){
- public void fun(){
- predownloadapk();
- }
- });
- }
- }
- //不用下载apk,直接进入游戏
- else
- {
- startGame();
- }
- } catch (NameNotFoundException e) {
- e.printStackTrace();
- }
- break;
- case 1:
- //下载配置文件出错了
- showDialog(context.getString(R.string.networkerror),context.getString(R.string.comfirmexist),null,context.getString(R.string.comfirmexist),null, new DialogHandler(){
- public void fun(){ context.finish(); }
- });
- break;
- case 2:
- break;
- case 3:
- //启动安卓应用
- if(md5.equals(Md5Check.md5sum(new File(path+"/"+fileName))))
- {
- ReplaceLaunchApk(path+"/"+fileName);
- }
- else if(retry<TryDownTotal)
- {
- retry++;
- downloadapk();
- }
- else
- {
- showDialog(context.getString(R.string.networkerror),context.getString(R.string.comfirmexist),null,context.getString(R.string.comfirmexist),null, new DialogHandler(){
- public void fun(){ context.finish(); }
- });
- }
- break;
- case 4:
- //t卡不存在
- showDialog("错误","请插入外部存储卡",null,context.getString(R.string.comfirmexist),null, new DialogHandler(){
- public void fun(){ context.finish(); }
- });
- break;
- case 5:
- //t卡空降不够
- showDialog("错误","存储卡剩余的空间不足,请先删掉些大的文件",null,context.getString(R.string.comfirmexist),null, new DialogHandler(){
- public void fun(){ context.finish(); }
- });
- break;
- default:
- break;
- }
- }
- }
- private void startGame()
- {
- Intent intent = new Intent(context, LongjiangActivity.class);
- startActivity(intent);
- context.finish();
- }
- //从url中下载apk
- private void predownloadapk()
- {
- retry=0;
- //创建文件
- downloadapk();
- }
- private void downloadapk()
- {
- //
- pbar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- pbar.setTitle("龙将游戏的版本号将升级为:"+version);
- pbar.setMessage("正在下载中,请稍后...");
- pbar.setCancelable(false);
- pbar.setMax(100);
- pbar.setProgress(0);
- pbar.show();
- new DownloadFilesTask().execute(apkDownUrl);
- }
- // 异步任务类
- class DownloadFilesTask extends AsyncTask<String,Integer,Long> {
- private URL url; // 资源位置
- private long beginPosition; // 开始位置
- @Override
- protected Long doInBackground(String... params) {
- InputStream inputStream = null;
- HttpURLConnection httpURLConnection =null;
- RandomAccessFile output = null;
- try {
- // 获取连接对象h
- //创建包名的文件夹
- boolean hasSD = Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED); //只检验是否可读且可
- if(!hasSD)
- {
- Message msg = Message.obtain(mHandler);
- msg.what = 4;
- mHandler.sendMessage(msg);
- return (long) 0;
- }
- long availablesize=getUsableStorage();
- if(availablesize<100)
- {
- Message msg = Message.obtain(mHandler);
- msg.what = 5;
- mHandler.sendMessage(msg);
- return (long) 0;
- }
- String sddir=getSDCardPath() ;
- path=sddir+"/"+packageName;
- File destDir = new File(sddir+"/"+packageName);
- if (!destDir.exists()) {
- destDir.mkdirs();
- }
- File outFile = new File(sddir+"/"+packageName+"/"+fileName);
- if (!outFile.exists()) {
- try {
- //在指定的文件夹中创建文件
- outFile.createNewFile();
- } catch (Exception e) {
- }
- }
- // 通过文件创建输出流对象RandomAccessFile,r:读 w:写 d:删除
- output = new RandomAccessFile(outFile, "rw");
- // 设置写入位置
- long lenth=outFile.length();
- if(fileTotalSize==lenth)
- {
- if(md5.equals(Md5Check.md5sum(outFile)) )
- {
- //下载完的处理
- publishProgress(100);
- Message msg = Message.obtain(mHandler);
- msg.what = 3;
- mHandler.sendMessage(msg);
- return lenth;
- }
- else
- {
- beginPosition=0;
- }
- }
- else
- {
- beginPosition=lenth;
- }
- // 设置断点续传的开始位置
- url=new URL(params[0]);
- httpURLConnection = (HttpURLConnection) url.openConnection();
- httpURLConnection = (HttpURLConnection)url.openConnection();
- httpURLConnection.setAllowUserInteraction(true);
- httpURLConnection.setRequestMethod("GET");
- httpURLConnection.setReadTimeout(4000);
- // httpURLConnection.setRequestProperty("User-Agent","NetFox");
- httpURLConnection.setRequestProperty("Range", "bytes=" + beginPosition + "-");
- inputStream = httpURLConnection.getInputStream();
- output.seek(beginPosition);
- byte[] buf = new byte[1024*100];
- int readsize=0;
- // 进行循环输出
- while ((readsize=inputStream.read(buf)) != -1) {
- output.write(buf, 0, readsize);
- beginPosition+=readsize;
- publishProgress((int)(beginPosition*100.0f/fileTotalSize));
- }
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- finally {
- if(inputStream!=null) {
- try {
- inputStream.close();
- if(output!=null) {
- output.close();
- }
- if(httpURLConnection!=null) {
- httpURLConnection.disconnect();
- }
- }
- catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- return beginPosition;
- }
- /**
- * 更新下载进度,当publishProgress方法被调用的时候就会自动来调用这个方法
- */
- @Override
- protected void onProgressUpdate(Integer... values) {
- super.onProgressUpdate(values);
- pbar.setProgress(values[0]);
- if(values[0]==100)
- {
- Message msg = Message.obtain(mHandler);
- msg.what = 3;
- mHandler.sendMessage(msg);
- }
- }
- //下载完的回调
- @Override
- protected void onPostExecute(Long size)
- {
- }
- }
- /**
- * 获取外置SD卡路径
- *
- * @return
- */
- public static String getSDCardPath() {
- return Environment.getExternalStorageDirectory().getPath();
- }
- /*
- * 返回SD卡可用容量 --#
- */
- private static long getUsableStorage(){
- String sDcString = android.os.Environment.getExternalStorageState();
- if (sDcString.equals(android.os.Environment.MEDIA_MOUNTED)) {
- File pathFile = android.os.Environment
- .getExternalStorageDirectory();
- android.os.StatFs statfs = new android.os.StatFs(pathFile.getPath());
- // 获取可供程序使用的Block的数量
- long nAvailaBlock = statfs.getAvailableBlocks();
- long nBlocSize = statfs.getBlockSize();
- // 计算 SDCard 剩余大小MB
- return nAvailaBlock * nBlocSize /1024 /1024;
- }
- else{
- return -1;
- }
- }
- //启动安装替换apk
- private void ReplaceLaunchApk(String apkpath) {
- // TODO Auto-generated method stub
- File file=new File(apkpath);
- if(file.exists())
- {
- Log.e(tag, file.getName());
- Intent intent = new Intent();
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setAction(android.content.Intent.ACTION_VIEW);
- intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
- startActivity(intent);
- context.finish();
- }
- else
- {
- Log.e(tag, "File not exsit:"+apkpath);
- }
- }
- }
参考:http://www.eoeandroid.com/thread-1081-1-1.html等其他