Android 程序自动更新
来源:互联网 发布:python实现二叉树 编辑:程序博客网 时间:2024/06/04 18:30
原理相当简单,检查更新的时候,通过指定的URL获取服务器端版本信息。比较版本,如果更新,访问服务器端返回的apk的URL地址,下载,安装。各种 Makert 也是通过类似的机制实现的。原理搞清楚了,代码就相当简单了。
获取apk的VesionName,即AndroidManifest.xml中定义的android:versionName
public String getVesionName(Context context)
{ String versionName = null;
try {
versionName = context.getPackageManager().getPackageInfo("net.vpntunnel", 0).versionName;
} catch (NameNotFoundException e) {
Log.e(TAG, e.getMessage());
}
return versionName;
}
更新以及安装程序需要的权限,在AndroidManifest.xml
中添加
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
<uses-permission android:name="android.permission.INSTALL_PACKAGES"></uses-permission>
获取apk的versionCode
,即AndroidManifest.xml
中定义的android:versionCode
public int getVersionCode(Context context) {
int versionCode = 0;
try {
versionCode = context.getPackageManager().getPackageInfo("net.vpntunnel", 0).versionCode;
} catch (NameNotFoundException e) {
Log.e(TAG, e.getMessage());
}
return versionCode;
}
服务器端version.JSON,包含apk路径以及版本信息
{
"ApkName":"NAME",
"ApkFullName":"NAME_1.0.5.apk",
"VersionName":"1.0.5",
"VersionCode":3
}
获取远程服务器的版本信息
private void getRemoteJSON(string host) throws ClientProtocolException, IOException, JSONException {
String url = String.format("http://%s/%s", host, VER_JSON);
StringBuilder sb = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpParams httpParams = client.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 3000);
HttpConnectionParams.setSoTimeout(httpParams, 5000);
HttpResponse response = client.execute(new HttpGet(url));
HttpEntity entity = response.getEntity();
if (entity != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"), 8192);
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
reader.close();
}
JSONObject object = (JSONObject) new JSONTokener(sb.toString()).nextValue();
this.apkFullName = object.getString("ApkFullName");
this.versionName = object.getString("VersionName");
this.versionCode = Integer.valueOf(object.getInt("VersionCode"));
}
发现更新的提醒窗口,通过AlertDialog
实现
private void shoVersionUpdate(String newVersion, final String updateURL) {
String message = String.format("%s: %s, %s", mContext.getString(R.string.found_newversion), newVersion, mContext.getString(R.string.need_update));
AlertDialog dialog = new AlertDialog.Builder(mContext).setTitle(mContext.getString(R.string.alertdialog_title)).setMessage(message)
// update
.setPositiveButton(mContext.getString(R.string.alertdialog_update_button), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
pBar = new ProgressDialog(mContext);
pBar.setTitle(mContext.getString(R.string.progressdialog_title));
pBar.setMessage(mContext.getString(R.string.progressdialog_message));
pBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.dismiss();
downFile(updateURL);
}
// cancel
}).setNegativeButton(mContext.getString(R.string.alertdialog_cancel_button), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
}).create();
dialog.show();
}
下载新版的apk文件,存放地址可以放到SD卡中。通过Environment.getExternalStorageDirectory()
获取SD卡中的路径
private void downFile(final String url) {
pBar.show();
new Thread() {
public void run() {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
HttpResponse response;
try {
response = client.execute(get);
HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
InputStream is = entity.getContent();
FileOutputStream fileOutputStream = null;
if (is != null) {
File f = new File(UPDATE_DIR);
if (!f.exists()) {
f.mkdirs();
}
fileOutputStream = new FileOutputStream(new File(UPDATE_DIR, updateFileName));
byte[] buf = new byte[1024];
int ch = -1;
int count = 0;
while ((ch = is.read(buf)) != -1) {
fileOutputStream.write(buf, 0, ch);
count += ch;
Log.d(TAG, String.valueOf(count));
if (length > 0) {
}
}
}
fileOutputStream.flush();
if (fileOutputStream != null) {
fileOutputStream.close();
}
handler.post(new Runnable() {
public void run() {
pBar.cancel();
installUpdate();
}
});
} catch (Exception e) {
pBar.cancel();
Log.e(TAG, e.getMessage());
}
}
}.start();
}
安装更新
private void installUpdate() {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(UPDATE_DIR, updateFileName)), "application/vnd.android.package-archive");
mContext.startActivity(intent);
}
至此更新需要函数就完成了,根据自己的业务逻辑组合一下,更新功能就搞定了。也可以稍微封装下,写成一个通用类,下次就可以直接用了。
- 【Android】Android程序自动更新
- android自动更新程序
- Android程序自动更新
- Android 程序自动更新
- Android 程序自动更新
- Android实现程序自动更新
- android程序自动更新
- Android实现程序自动更新
- android 程序自动更新
- Android 程序自动更新
- Android 程序自动更新功能模块实现
- Android 程序自动更新功能模块实现
- Android实现程序自动更新实例教程
- android程序自动更新安装详解
- android为程序添加版本自动更新
- android之程序自动更新的实现
- android之程序自动更新的实现
- android之程序自动更新的实现
- 手机SIM卡的详细介绍
- Linux设备驱动-中断处理笔记
- 频繁打开数据库连接是否影响性能的疑惑
- CLR via c# 装箱与拆箱
- 解除苹果的appleID绑定的信用卡
- Android 程序自动更新
- Android动画及图片的缩放和旋转
- 未能从程序 集'Microsoft.VisualStudio.DataDesign.SyncDesigner.DslPackage,Version=9.0.0.0,Culture=neutral
- JS MVC 用例子来说明他的好处
- ASP.NET连接数据库并获取数据
- 关于JAVA Static的初始化顺序(及递归错误)
- 经典面试之n线分割最多面与n面分割最多空间
- android EditText限制输入长度
- 如何获取系统的应用程序的相关信息