android 应用升级模块解析

一共就用到一个类:

 

假定当前为第1版,通过对后台的请求,收到第2版的更新通知。代码如:

package com.example.ex_templete;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.MalformedURLException;

import java.net.URL;

import java.net.URLConnection;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.os.Environment;

import android.app.Activity;

import android.app.AlertDialog;

import android.app.Notification;

import android.app.NotificationManager;

import android.app.PendingIntent;

import android.content.Context;

import android.content.DialogInterface;

import android.content.Intent;

import android.content.pm.PackageInfo;

import android.content.pm.PackageManager;

import android.content.pm.PackageManager.NameNotFoundException;

import android.support.v4.app.NotificationCompat;

import android.view.Menu;

import android.view.View;

import android.widget.RemoteViews;

public class MainActivity extends Activity {

private static final String PATH_APK_UPGROUP = Environment.getExternalStorageDirectory()

+ "/myapp/download/myapp.apk";

private static final int NOTIFY_ID = 1234;

private RemoteViews remoteViews;

private Notification notification;

private NotificationManager manager;

private int fileLen;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

autoupgrade();

}

private void autoupgrade() {

//获取当前应用版本号

int vc = getVersionCode();

/*通常每次打开app都会向后台请求一个版本号,若与当前版本相同,则不提醒,若大于当前版本,则提示升级*/

int newVc = 2;//假定从后台获取的版本为第2版,大于当前版本

final String apkUrl = "http://meishipic.qiniudn.com/2010052615045178.jpg";//apk下载地址,暂用一张图片代替

String apkMessage = "1、增加了XXX \n2、修改了XXX";  //增加的新特性

if(vc < newVc)

{

new AlertDialog.Builder(this).setTitle("更新升级")

.setMessage(apkMessage)

.setPositiveButton("升级", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

//升级

new MyTask().execute(apkUrl);

}

}).setNegativeButton("取消", null).create().show();

}

}

class MyTask extends AsyncTask<String, Integer, Boolean>

{

@Override

protected void onPreExecute() {

super.onPreExecute();

//通知

showNotifi();

}

@Override

protected Boolean doInBackground(String... params) {

//下载apk

InputStream is = null;

FileOutputStream fos = null;

try {

URL url = new URL(params[0]);

HttpURLConnection openConnection = (HttpURLConnection) url.openConnection();

fileLen = openConnection.getContentLength();//获得文件长度

int responseCode = openConnection.getResponseCode();

if(responseCode != HttpURLConnection.HTTP_OK)

{

//提示

return null;

}

//判断文件路径是否存在

File file =new File(PATH_APK_UPGROUP);

if(!file.getParentFile().exists())

{

file.getParentFile().mkdirs();

}

is = openConnection.getInputStream();

int len = 0;

byte[] buffer = new byte[1024];

//已下载大小

int loadLen = 0;

fos = new FileOutputStream(PATH_APK_UPGROUP);

int num = 1;

while(-1 != (len = is.read(buffer)))

{

//Thread.sleep(100);

fos.write(buffer, 0, len);

loadLen += len;

if(loadLen *100 / fileLen >= 1*num)

{

num++;

publishProgress(loadLen);

}

}

fos.flush();

} catch (MalformedURLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

finally{

if(is != null)

{

try {

is.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

if(fos != null)

{

try {

fos.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

return null;

}

@Override

protected void onProgressUpdate(Integer... values) {

super.onProgressUpdate(values);

//更新通知

int len = values[0];

notification.contentView.setTextViewText(R.id.tv12, "更新了"+ len*100/fileLen +"%");

notification.contentView.setProgressBar(R.id.progressBar1, fileLen, len, false);

manager.notify(NOTIFY_ID, notification);

}

@Override

protected void onPostExecute(Boolean result) {

super.onPostExecute(result);

//完善通知

//设置点击通知安装

Intent intent = new Intent(Intent.

ACTION_VIEW);

intent.setDataAndType(Uri.parse("file://"+

PATH_APK_UPGROUP),

"application/vnd.android."

+ "package-archive");

notification.contentView.setTextViewText(R.id.tv12, "更新完成,点击安装");

notification.contentView.setViewVisibility(R.id.progressBar1, View.GONE);

PendingIntent ic = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);

notification.contentIntent = ic;

manager.notify(NOTIFY_ID, notification);

//startActivity(intent);

}

}

private int getVersionCode() {

PackageManager manager = getPackageManager();

try {

PackageInfo packageInfo =

manager.getPackageInfo(getPackageName(), 0);

return packageInfo.versionCode;

} catch (NameNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return 0;

}

public void showNotifi() {

manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Intent intent = new Intent();

intent.setClass(this, MainActivity.class);//点击设置跳转的页面

PendingIntent contentIntent = PendingIntent.getActivity(this, 0,

intent, 0);

remoteViews = new

RemoteViews(getPackageName(), R.layout.notification);

notification =

new NotificationCompat.Builder(this)

.setSmallIcon(R.drawable.ic_launcher).setContentTitle("通知")

.setTicker("标题1").setContent(remoteViews).setContentText("内容1")

.setWhen(System.currentTimeMillis())

.setContentIntent(contentIntent).

build();

manager.notify(NOTIFY_ID, notification);

}

}

这样就实现了app检查版本提示更新的功能。权限不要漏了。

时间: 12-21

android 应用升级模块解析的相关文章

【直接拿来用のandroid公共代码模块解析与分享】の Notification和NotificationManager

本文源代码托管在https://github.com/ASCE1885/asce-common,欢迎fork Android项目做得多了.会发现原来非常多基础的东西都是能够复用,这个系列介绍一些自己项目中经常使用到的公共模块代码(当然仅仅谈技术不谈业务),一来整理好了自己以后能够直接用,二来也分享给大家,希望能略微降低大家的加班时间,提高些许效率. Android Notification的原理和作用这里就不作说明了,相信是个android开发人员都用过不止一次了,下面仅仅介绍怎样封装成公共的模

Android在线升级相关笔记一(解析服务器版本与当前版本比较)

大概流程:Android客户端去访问服务器上的封装了版本号等信息的xml文件,对服务器上的版本和当前版本进行比较, 如果低于服务器的版本,则下载服务器上的新版软件,进行安装替换,完成升级. 一.首先用tomcat搭建服务器,用于开发测试. 下载tomcat请参考:http://blog.csdn.net/only_tan/article/details/25110625 1.在tomcat中新建自己的项目: \apache-tomcat-6.0.39\webapps 目录下新建自己的项目文件夹,

Android中使用Gson解析JSON数据的两种方法

Json是一种类似于XML的通用数据交换格式,具有比XML更高的传输效率;本文将介绍两种方法解析JSON数据,需要的朋友可以参考下 Json是一种类似于XML的通用数据交换格式,具有比XML更高的传输效率. 从结构上看,所有的数据(data)最终都可以分解成三种类型: 第一种类型是标量(scalar),也就是一个单独的字符串(string)或数字(numbers),比如"北京"这个单独的词. 第二种类型是序列(sequence),也就是若干个相关的数据按照一定顺序并列在一起,又叫做数组

Eclipse,到了说再见的时候了——Android Studio最全解析

去年的Google大会上,Google带给我们一个小玩具--Android Studio,说它是玩具,是因为它确实比较菜,界面过时,操作不流畅,效率也不高,但是现在,虽然版本还是0.6,甚至都没到1.0,但是我们可以发现亲儿子到底是亲儿子,现在的Android Studio已经今非昔比,用了一段时间,简直爱不释手,我觉得,It's time to say goodbye eclipse!本文将带领大家彻底的了解一下Android Studio,注意:由于天朝的原因,我们的了解过程会比较曲折,但是

Android开发之json解析

目前正在尝试着写app,发现看懂代码和能写出来差距很大,最关键的是java基础比较的差,因为只会python,java基础只学习了一个礼拜就过了.感觉java写出来的代码不如python简单明了. 上面废话了.现在开发app肯定会涉及到与服务器的交互的,目前的首选是json.用到的解析json的包可以选择gson,fastjson等. 现在分析下把我难倒了好几天的一个bug,就是json的解析. 用到的API:http://fanyi.youdao.com/openapi.do?keyfrom=

解决android模块化升级的办法

关于原生android版本更新升级必须整个apk更新安装,不能实现部分模块化升级的解决思路: 原生+web混合型APP~ 具体应客户要求,程序必须实现模块化升级,不管用何种办法,我是这么做的,每个功能首页写成html放本地(asset),html里面action操作全部请求服务器端的,之间的传值使用签名+验签方式确保信息安全 [首页放本地而不放服务端是解决即使没网情况下,也可以很友好的给用户展示一个页面] 这个只是我想到的一种解决方案,还有好的方案,请一起分享 public class Main

(Android review)XML的解析与序列化

这篇博客主要用来介绍对XML文件的操作:解析与生成. Android手机内部的解析就是pull解析官网:http://xmlpull.org/所谓的解析,我们可以理解为:利用XML文件的内容来生成一个对象导出生成的xml文件后不要对其格式化,否则会出异常 1.MainActivity package com.example.xmlparsertest1; import android.os.Bundle; import android.app.Activity; import android.v

Android异步载入全解析之大图处理

Android异步载入全解析之大图处理 异步载入中很重要的一部分就是对图像的处理,这也是我们前面用异步载入图像做示例的原因. 一方面是由于图像处理不好的话会很占内存,并且easyOOM,还有一方面,图像也比文字要大,载入比較慢.所以,在解说了怎样进行多线程.AsyncTask进行多线程载入后,先暂停下后面的学习.来对图像的异步处理进行一些优化工作. 为什么要对图像处理 为什么要对图像进行处理,这是一个很直接的问题.一张图像.无论你拿手机.相机.单反还是什么玩意拍出来,它就有一定的大小,可是在不同

Android中XML数据解析

转载请注明出处:http://blog.csdn.net/yegongheng/article/details/38296207 XML初步 今天我们来学习另一种非常重要的数据交换格式-XML.XML(Extensible Markup Language的缩写,意为可扩展的标记语言),它是一种元标记语言,即定义了用于定义其他特定领域有关语义的.结构化的标记语言,这些标记语言将文档分成许多部件并对这些部件加以标识.XML 文档定义方式有:文档类型定义(DTD)和XML Schema.DTD定义了文

Android异步载入全解析之使用多线程

异步载入之使用多线程 初次尝试 异步.异步,事实上说白了就是多任务处理.也就是多线程执行.多线程那就会有各种问题,我们一步步来看.首先.我们创建一个class--ImageLoaderWithoutCaches,从命名上.大家也看出来,这个类,我们实现的是不带缓存的图像载入,不多说,我们再创建一个方法--showImageByThread,通过多线程来载入图像: /** * Using Thread * @param imageView * @param url */ public void s