android做个版本下载更新
2014-01-18 15:13
513 查看
流程:1.到服务器那边拉去配置文件,然后解析配置文件来获取应用的地址,版本号,大小,md5和配置的更新的方式(可选更新与强制更新);
2.断点续传方式拉去apk。
一下为代码:
参考:http://www.eoeandroid.com/thread-1081-1-1.html等其他
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等其他
相关文章推荐
- android中DownloadManager实现版本更新,监听下载进度实例
- Android 版本更新下载自动安装APK,并解决Android6.0安装失败的问题
- android检查版本更新、下载、安装工具类
- android SDK manager 无法获取更新版本,连线包下载大全【转】
- 【Ionic】Ionic实现iOS与Android端代码『热更新』与Android升级下载功能 ( v1.3.x版本 )
- Android程序版本更新--通知栏更新下载安装
- Android实现版本更新通知栏下载
- Android——Tomcat版本更新下载+头像照片上传到Tomcat
- 搭建android版本更新服务器使用android系统自带的DownloadManager下载文件
- android 实现版本更新和下载安装
- Android版本更新(Service下载 Notification进度条:直接拿来用)
- Android 版本检测、文件下载并更新
- android 客户端版本检测更新,服务下载,通知栏显示
- ionic 检测版本更新,Android版,IOS在浏览器打开下载页面。
- Android----- 版本更新和 服务器下载新版本APK并安装
- Android服务器——使用TomCat实现软件的版本检测,升级,以及下载更新进度!
- android客户端版本检测更新,服务下载,通知栏显示
- [置顶] Android开发必有功能,更新版本提示,检测是否有新版本更新。下载完成后进行安装。
- Android服务器——使用TomCat实现软件的版本检测,升级,以及下载更新进度!