【声明:】本文是作者(蘑菇v5)原创,版权归作者 蘑菇v5所有,侵权必究。本文首发在简书。如若转发,请注明作者和来源地址!未经授权,严禁私自转载!
当服务器上有新版本的应用时,客户端程序发送https请求,服务器端在接受到请求以后,给客户端返回数据(json,xml),json数据从数据库中读取出来,读取数据拼接成json,语法规则如下:
服务器端json数据
{
"version_name": "2.0",
"version_code": 2,
"description": "最新版xxx,快来下载体验吧!",
"download_url": "http://10.0.2.2:8080/xx2.0.apk"
}
注意: 保存文本为 "UTF-8 无BOM" 格式
客户端通过获取本地的版本号,检测升级(本地版本号<小于服务器版本号,服务器有一个更高版本的应用),获取本地版本号代码如下:
获取版本信息
//获取版本信息
private String getVersion() {
PackageManager pm = getPackageManager();
try {
PackageInfo info = pm.getPackageInfo(getPackageName(), 0);
String versionName = info.versionName;
int versionCode = info.versionCode;
return versionName;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return "";
}
当服务器版本号大于本地版本的时候,则需要本地弹出是否更新的对话框,当点击更新的时候,下载服务器最新版本的apk.
-
下载apk
-
使用xutils框架进行下载
// 下载apk protected void downloadApk() { //判断SDcard是否挂载 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath() +File.separator+"xx.apk"; HttpUtils httpUtils = new HttpUtils(); //(下载地址,下载应用存放位置(sd卡),下载过程中方法的回调) httpUtils.download( mDownloadUrl, sdPath, new RequestCallBack<File>() { @Override public void onSuccess(ResponseInfo<File> responseInfo) { Log.i(tag, "下载成功"); //下载过后从服务端获取到的apk File file = responseInfo.result; //安装apk过程,android源码中找到apk安装过程,android系统在安装应用,开启一个activity, installApk(file); } @Override public void onFailure(HttpException arg0, String arg1) { Log.i(tag, "下载失败"); } @Override public void onLoading(long total, long current, boolean isUploading) { super.onLoading(total, current, isUploading); Log.i(tag, "下载过程中"); } @Override public void onStart() { super.onStart(); Log.i(tag, "下载开始"); } }); } }
-
-
卸载apk
public void uninstall(View v){ Intent intent = new Intent(); intent.setAction(Intent.ACTION_DELETE); intent.setData(Uri.parse("package:com.njupt.htmlui1")); startActivity(intent); }
- 安装apk
查看PackageInstaller源码, 查看AndroidManifest.xml文件中Activity的配置, 从而决定在跳转系统安装界面的Activity时应该传哪些参数.
// 安装apk
public void installApk(File file) {
//通过隐式意图去开启activity
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
/*intent.setData(Uri.fromFile(file));
intent.setType("application/vnd.android.package-archive");*/
//这一句话中,第一个参数是要安装的apk的路径,第二个参数是apk
// 所对应的类型。可以在tomcat的安装目录下的conf目录下的web.xml中找到
intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
//startActivity(intent);
startActivityForResult(intent,0);
}
//接收后一个界面返回结果的方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
enterHome();
super.onActivityResult(requestCode, resultCode, data);
}
/**
* 进入应用程序主界面
*/
public void enterHome() {
//activity跳转
Intent intent = new Intent(this,HomeActivity.class);
startActivity(intent);
finish();
}
安装失败
在Android手机里不允许有两个应用程序有相同的包名;
假设A应用的包名:com.xxx.xxA;
A应用已经在系统中存在了。
这个时候再去安装一个应用B ,他的包名也叫 con.xxx.xxA
系统就会去检查这两应用的签名是否相同。如果相同,B会把A给覆盖安装掉;
如果不相同 B安装失败;
要想自动安装成功,必须保证应用程序不同版本的签名完成一样。
- 签名
默认签名
直接在studio里运行项目是, 会采用默认签名debug.keystore. 查找方式: Window->Preference->Android->Build, 可以看到默认签名文件的路径, 默认是: C:\Users\tt\.android\debug.keystore
默认签名的特点:
1. 不同电脑,默认签名文件都不一样
2. 有效期比较短, 默认是1年有效期
3. 有默认密码: android, 别名:androiddebugkey
正式签名
正式签名特点:
1. 发布应用市场时, 统一使用一个签名文件
2. 有效期比较长, 一般25年以上
3. 正式签名文件比较重要,需要开发者妥善保存签名文件和密码
使用正式签名文件,分别打包1.0和2.0, 安装运行1.0版本,测试升级是否成功
签名文件丢失后, 肿么办?
1. 让用户卸载旧版本, 重新在应用市场上下载最新版本, 会导致用户流失
2. 更换包名, 重新发布, 会出现两个xx, 运行新版xx, 卸载旧版本
3. 作为一名有经验的开发人员, 最好不要犯这种低级错误!
中午不睡,下午崩溃...it's truth..