您的位置:首页 > 移动开发 > Android开发

android做个版本下载更新

2014-01-18 15:13 513 查看
流程: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等其他
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: