Cordova app更新
app更新一般大的分为两种:
- 用第三方SDk(例:腾讯的bugly,以前的友盟)。
- 第二种,访问自己的服务器下载。
第一种的话,在原生里面很好用,注意的是友盟的现在这个业务已经下线了,所以有的cordova,Ionic里的app更新用的友盟的SDk是不能用了的。
第二种的话,在任何环境都可以,思想是一样的,就是比对版本,访问服务器更新,大型的公司应该会做推送之类的。
好了,思路+代码
一,获取安装的app版本
public class GetAppVersion {
public static int getVersionCode(Context context) {
PackageManager manager;
PackageInfo info = null;
manager = context.getPackageManager();
try {
info = manager.getPackageInfo(context.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
int versionCode=info.versionCode;
String versionName=info.versionName;
String packageName=info.packageName;
Signature[] signatures=info.signatures;
return versionCode;
}
public static String getVersionName(Context context) {
PackageManager manager;
PackageInfo info = null;
manager = context.getPackageManager();
try {
info = manager.getPackageInfo(context.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
int versionCode=info.versionCode;
String versionName=info.versionName;
String packageName=info.packageName;
Signature[] signatures=info.signatures;
return versionName;
}
public static String getPackageName(Context context) {
PackageManager manager;
PackageInfo info = null;
manager = context.getPackageManager();
try {
info = manager.getPackageInfo(context.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
int versionCode=info.versionCode;
String versionName=info.versionName;
String packageName=info.packageName;
Signature[] signatures=info.signatures;
return packageName;
}
}
二,获取最新的app版本和信息
服务器端接口代码:
@WebServlet("/update")
public class Login extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out=resp.getWriter();
String string=" {\"version\":2,\"message\":\"haha\",\"url\":\"http://www.woxiangwoxiang.com...//clientdownload/android/woxiangwoxiang.apk\"} ";
out.write(string);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(req, resp);
}
}
Android端代码:
解析版本代码:
public class VersionService {
public static UpdateEntity VersionService() {
UpdateEntity update = null;
try {
URL url = new URL(API.UPDATE_URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream in = conn.getInputStream();
byte[] data = StreamTool.read(in);
String json = new String(data);
JSONObject jsonObject = new JSONObject(json);
update = new UpdateEntity();
update.setVersionCode(jsonObject.getInt("version"));
update.setMessage(jsonObject.getString("message"));
update.setUrlLoadDown(jsonObject.getString("url"));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return update;
}
private static List<UpdateEntity> parseJSON(InputStream inStream) throws Exception{
List<UpdateEntity> list=new ArrayList<>();
byte[] data = StreamTool.read(inStream);
String json = new String(data);
JSONObject jsonObject = new JSONObject(json);
UpdateEntity update = new UpdateEntity();
update.setVersionCode(jsonObject.getInt("version"));
update.setMessage(jsonObject.getString("message"));
update.setUrlLoadDown(jsonObject.getString("url"));
list.add(update);
LogUtils.LogUtils(update.getVersionCode() + update.getMessage() + update.getUrlLoadDown());
return list;
}
}
对比版本代码:
/*
* 检查更新
* */
public void checkUpdate(){
UpdateEntity entity=VersionService.VersionService();
if (entity!=null){
int newVersion=entity.getVersionCode();
String message=entity.getMessage();
String url=entity.getUrlLoadDown();
LogUtils.LogUtils(entity.getVersionCode()+"....version..."+ entity.getMessage()+"..message.."+ entity.getUrlLoadDown()+"...url...");
int oldVersion=GetAppVersion.getVersionCode(MainActivity.this);
if (oldVersion!=newVersion){
UpdateDialog updateDialog=new UpdateDialog(MainActivity.this);
updateDialog.setText(message);
updateDialog.setUpdateUrl(url);
updateDialog.show();
}
}
return;
}
下载最新apk代码:
public class DownLoadFileUtils {
public static File downLoadFile(String urlStr, ProgressBar progressBar) {
final String rootDirectry = Environment
.getExternalStorageDirectory().getPath() + "/Download";
final String fileName = "woxiangwoxiang.apk"; //apk name
File tmpFile = new File(rootDirectry);
if (!tmpFile.exists()) {
tmpFile.mkdir();
}
final File file = new File(rootDirectry + "/" + fileName);
try {
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
InputStream inputStream = connection.getInputStream();
int size = connection.getContentLength();
progressBar.setMax(size);
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[1024];
connection.connect();
Long starttime = System.currentTimeMillis();
while (true) {
if (inputStream != null) {
int numRead = inputStream.read(buffer);
if (numRead <= 0) {
break;
} else {
fos.write(buffer, 0, numRead);
progressBar.setProgress((int) file.length());
Long stoptime = System.currentTimeMillis();
Long time = (stoptime - starttime) / 1000;
if (time != 0) {
Message msg = new Message();
int baifenbi = (int) (file.length() * 100 / size);
int speed = (int) ((file.length() / 1024) / time);
int spendTime = (int) (stoptime - starttime) / 1000;
msg.obj = speed;
msg.arg1 = baifenbi;
msg.arg2 = spendTime;
}
}
}
}
connection.disconnect();
fos.close();
inputStream.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return file;
}
}
下载后自动安装apk代码:
public void checkAppFile(){
final File file = new File(rootDirectry + "/" + fileName);
if (file!=null){
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
LogUtils.LogUtils("安装。。。。。。。。。。。。。。。。");
//跳转安装 startActivity(intent);
getContext().startActivity(intent);
}
return;
}
清除下载的app代码:
//删除原来apk文件
public void deleteApk(){
final File file = new File(rootDirectry + "/" + fileName);
if (file!=null){
deleteDatabase(file.toString());
}
}
注意点代码:
//在show之前调用
public void setText(String messageStr){
if (null==messageStr){
messageStr="修复已知bug";
}
message.setText(messageStr);
}
public void setUpdateUrl(String urlStr){
this.urlStr=urlStr;
}
整个流程就是,进去访问服务器,接受json数据,解析对比版本号,不同,则把服务器发的信息里的message(更新内容信息)和下载地址保存,message加载到更新对话框显示,url给子线程下载保存到本地download目录,下载完后自动安装,然后删除下载的安装包。
三,优化
Android端代码优化,减少访问加载和网络不好带来的体验问题
服务器端,代码优化,增强服务器访问的安全性
注意这种方法代码要注意,多测试,因为不会像第三方SDk会用崩溃反馈和检测统计,所以优化和逻辑处理要注意。