联网更新应用
把图给贴上,先把逻辑整得明明白白!
image1. 判断是否有网络
这里的联网更新应用操作在SplashActivity(渲染/欢迎界面)中执行,只针对该功能做笔记,而不涉及其他类似于冷启动优化等的知识摘录!
在SplashActivity中定义好需要用到的变量。
private static final int TO_MAIN = 1;//是否进入MainActivity
private static final int DOWNLOAD_VERSION_SUCCESS = 2;//解析版本数据成功
private static final int DOWNLOAD_APK_FAIL = 3;//下载失败
private static final int DOWNLOAD_APK_SUCCESS = 4;//下载成功
private boolean connect;//是否联网的标志
private long startTime;//系统当前时间
private UpdateInfo updateInfo;//json数据对应的更新信息bean类对象
private ProgressDialog dialog;//初始化水平进度条的dialog
private File apkFile;
private Handler handler = new Handler()
首先判断是否有网络
public boolean isConnect()
{
boolean connected = false;
ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
if (networkInfo != null)
{
connected = networkInfo.isConnected();
}
return connected;
}
toMain()
如果联网失败则进入主界面,这里SplashActivity涉及到动画的操作,所以获取一下当前系统时间,通过handle发送延迟消息
private void toMain()
{
long currentTime = System.currentTimeMillis();
long delayTime = 3000 - (currentTime - startTime);
if (delayTime < 0)
{
delayTime = 0;
}
handler.sendEmptyMessageDelayed(TO_MAIN, delayTime);
}
2. 联网获取效应数据
如果获取效应数据失败,进入到主界面,如果获取响应数据成功,则判断当前app版本与服务器版本是否一致。
综合1,2两步具体代码如下:
//联网请求更新的地址
public static final String URL_UPDATE = BASE_URL + "update.json";
/**
* 联网更新应用
*/
private void updateApkFile()
{
//获取系统当前时间
startTime = System.currentTimeMillis();
//1.判断手机是否可以联网
boolean connect = isConnect();
if (!connect)
{//没有移动网络
UIUtils.toast("当前没有移动数据网络", false);
toMain();
}
else
{//有移动网络
//联网获取服务器的最新版本数据
AsyncHttpClient client = new AsyncHttpClient();
String url = AppNetConfig.UPDATE;
client.post(url, new AsyncHttpResponseHandler()
{
@Override
public void onSuccess(String content)
{
//解析json数据
updateInfo = JSON.parseObject(content, UpdateInfo.class);
handler.sendEmptyMessage(DOWNLOAD_VERSION_SUCCESS);
}
@Override
public void onFailure(Throwable error, String content)
{
UIUtils.toast("联网请求数据失败", false);
toMain();
}
});
}
}
3. 判断两个版本是否一致
如果版本号一致则进入主界面,若不一致则显示提示下载的Dialog
//获取当前应用的版本信息
String version = getVersion();
//更新页面显示的版本信息
tvWelcomeVersion.setText(version);
//比较服务器获取的最新的版本跟本应用的版本是否一致
if (version.equals(updateInfo.version))//版本一致则进入主界面
{
UIUtils.toast("当前应用已经是最新版本", false);
toMain();
}
else//版本不一致,new一个Dialog提示,点击确定则下载服务器应用数据,取消则进入主界面
{
new AlertDialog.Builder(SplashActivity.this)
.setTitle("下载最新版本")
.setMessage(updateInfo.desc)
.setPositiveButton("确定", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
//下载服务器保存的应用数据
downloadApk();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
toMain();
}
})
.show();
}
获取当前版本号
/**
* 当前版本号
*
* @return
*/
private String getVersion()
{
String version = "未知版本";
PackageManager manager = getPackageManager();
try
{
PackageInfo packageInfo = manager.getPackageInfo(getPackageName(), 0);
version = packageInfo.versionName;
}
catch (PackageManager.NameNotFoundException e)
{
//e.printStackTrace(); //如果找不到对应的应用包信息, 就返回"未知版本"
}
return version;
}
4. 是否要下载最新版
若不下载则进入主界面,如果下载,则启动分线程下载
downloadApk()
这里使用的是HttpURLConnection联网操作和文件的输入输出流,当然也可以使用常用的联网框架!
/**
* 下载APk
*/
private void downloadApk()
{
//初始化水平进度条的dialog
dialog = new ProgressDialog(this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setCancelable(false);
dialog.show();
//初始化数据要保持的位置
File filesDir;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
filesDir = this.getExternalFilesDir("");
}
else
{
filesDir = this.getFilesDir();
}
apkFile = new File(filesDir, "update.apk");
//启动一个分线程联网下载数据:
new Thread()
{
public void run()
{
String path = updateInfo.apkUrl;
InputStream is = null;
FileOutputStream fos = null;
HttpURLConnection conn = null;
try
{
URL url = new URL(path);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.connect();
if (conn.getResponseCode() == 200)
{
dialog.setMax(conn.getContentLength());//设置dialog的最大值
is = conn.getInputStream();
fos = new FileOutputStream(apkFile);
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1)
{
//更新dialog的进度
dialog.incrementProgressBy(len);
fos.write(buffer, 0, len);
SystemClock.sleep(1);
}
handler.sendEmptyMessage(DOWNLOAD_APK_SUCCESS);
}
else
{
handler.sendEmptyMessage(DOWNLOAD_APK_FAIL);
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (conn != null)
{
conn.disconnect();
}
if (is != null)
{
try
{
is.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
if (fos != null)
{
try
{
fos.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
}.start();
}
5.是否下载成功
若下载成功则安装apk
/**
* 安装Apk
*/
private void installApk()
{
Intent intent = new Intent("android.intent.action.INSTALL_PACKAGE");
intent.setData(Uri.parse("file:" + apkFile.getAbsolutePath()));
startActivity(intent);
}
6. 在handle中处理发送过来的消息
private Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case TO_MAIN:
finish();
startActivity(new Intent(SplashActivity.this, MainActivity.class));
break;
case DOWNLOAD_VERSION_SUCCESS:
//获取当前应用的版本信息
String version = getVersion();
//更新页面显示的版本信息
tvWelcomeVersion.setText(version);
//比较服务器获取的最新的版本跟本应用的版本是否一致
if (version.equals(updateInfo.version))//版本一致则进入主界面
{
UIUtils.toast("当前应用已经是最新版本", false);
toMain();
}
else//版本不一致,new一个Dialog提示,点击确定则下载服务器应用数据,取消则进入主界面
{
new AlertDialog.Builder(SplashActivity.this)
.setTitle("下载最新版本")
.setMessage(updateInfo.desc)
.setPositiveButton("确定", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
//下载服务器保存的应用数据
downloadApk();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
toMain();
}
})
.show();
}
break;
case DOWNLOAD_APK_FAIL:
UIUtils.toast("联网下载数据失败", false);
toMain();
break;
case DOWNLOAD_APK_SUCCESS:
UIUtils.toast("下载应用数据成功", false);
dialog.dismiss();//隐藏当前的Dialog
installApk();//安装下载好的应用
finish();//结束当前的welcomeActivity的显示
break;
}
}
};
7. 消息移除
@Override
protected void onDestroy()
{
//把所有的消息和回调移除
handler.removeCallbacksAndMessages(null);
super.onDestroy();
ButterKnife.unbind(this);
}
网友评论