app自动更新(android)
更新插件代码:https://github.com/shixy/UpdateApp
来源:http://aspoems.iteye.com/blog/1897300
检查更新的时候,通过指定的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);
- }
复制代码
至此更新需要函数就完成了
app自动更新(android)的更多相关文章
- Android学习系列(3)--App自动更新之自定义进度视图和内部存储
友好的视觉感知和稳定的不出错表现,来自于我们追求美感和考虑的全面性,博客园从技术的角度,一直我都很欣赏.这篇文章是android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用. 这 ...
- H5+app -- 自动更新
一.最近做了一个app自动更新功能,用的基本都是网上找得到的. 1.h5+ 规范 : http://www.html5plus.org/doc/zh_cn/maps.html 2.环形进度条插件:h ...
- web app升级—带进度条的App自动更新
带进度条的App自动更新,效果如下图所示: 技术:vue.vant-ui.5+ 封装独立组件AppProgress.vue: <template> <div> <va ...
- Web APP自动更新
我们的手机软件每天都要经营,经常需要更新,比如程序的Bug,好的功能,好的洁面... ... 这就需要我们的用户打开web app时候自动更新客户端程序,而不是再去应用程序商店从新下载.今天的笔记就是 ...
- Android App自动更新解决方案(DownloadManager)
一开始,我们先向服务器请求数据获取版本 public ObservableField<VersionBean> appVersion = new ObservableField<&g ...
- Android 云服务器的搭建和友盟APP自动更新功能的实现
setContentView(R.layout.activity_splash); //Bmob SDK初始化--只需要这一段代码即可完成初始化 //请到Bmob官网(http://www.bmob. ...
- 安卓---app自动更新
主要参考:http://blog.csdn.net/jdsjlzx/article/details/46356013/ 效果如下: 大致思路:[原文] 首先,我们要有一个可以被手机访问的后台. 这里有 ...
- App自动更新(DownloadManager下载器)
一.开门见山 代码: object AppUpdateManager { const val APP_UPDATE_APK = "update.apk" private var b ...
- 解决“iOS 7 app自动更新,无法在app中向用户展示更新内容”问题
转自cocoachina iOS 7能在后台自动app,这对开发者来说和用户都很方便,但是还是有一些缺点.用户不会知道app本次更新的内容,除非他们上到app的App Store页面去查看.开发者也会 ...
随机推荐
- sql server update时,是行锁还是表锁
https://bbs.csdn.net/topics/120000749 http://www.cnblogs.com/s021368/articles/2148659.html 问题: udpat ...
- 论4.1loli模拟赛
论如何合理的挂.... T1: 后缀数组+找规律...没了,别的就没什么了.... T2: 树链剖分+lca....没了, 别的没什么了..... T3: 平衡树可过..然后数据有两组错的... 实际 ...
- 手机APP和微信小程序能否取代域名?
有人说现在App是主流,手机上装几个App就可以了,以后域名的重要性会越来越低,直至App完全取代域名的域名无用论.真的是这样吗? 关于这个话题已经有很多先人前辈探讨过,这次誉名网从另外一个角度给各位 ...
- SoapUI使用方法-01发送http请求
soap ui http://blog.csdn.net/russ44/article/details/51680083 一.发送HTTP请求消息 1.打开soapUI. 2.新建一个项目,实例如下: ...
- this关键字详解
在java中,编译器会为每个对象分配一个this关键字.在代码中使用关键字可以使代码更优雅.下面我就列举一下this关键字常见的几种场景. 1.this代表当前对象调用成员变量和方法,也是用的最多的地 ...
- Java执行过程
Java的运行原理 在Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器.这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口.编译程序只需要面向虚拟机,生成虚拟机能 ...
- [Kafka] - Kafka内核理解:分布式机制
一个Topic中的所有数据分布式的存储在kafka集群的所有机器(broker)上,以分区(partition)的的形式进行数据存储:每个分区允许存在备份数据/备份分区(存储在同一kafka集群的其它 ...
- swoole帮助文档
入门指引 [编辑本页] Swoole虽然是标准的PHP扩展,实际上与普通的扩展不同.普通的扩展只是提供一个库函数.而swoole扩展在运行后会接管PHP的控制权,进入事件循环.当IO事件发生后,swo ...
- Template、ItemsPanel、ItemContainerStyle、ItemTemplate(包括ListBox的Item子项是横向排列)
Template.ItemsPanel.ItemContainerStyle.ItemTemplate 分类: WPF2011-10-12 10:13 4716人阅读 评论(0) 收藏 举报 data ...
- hbase_异常_04_util.FSUtils: Waiting for dfs to exit safe mode...
一.异常现象 启动hbase的时,hbase的日志中可以发现: Waiting for dfs to exit safe mode... 然后就抛异常了 2018-03-22 17:00:28,994 ...