版本更新说明

这里有调用UpdateService启动服务检查下载安装包等

1. 文件下载,下完后写入到sdcard

2. 如何在通知栏上显示下载进度

3. 下载完毕自动安装

4. 如何判断是否有新版本

版本更新的主类

package com.wei.update;import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.util.HashMap;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.json.JSONException;import org.json.JSONObject;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xmlpull.v1.XmlPullParser;import org.xmlpull.v1.XmlPullParserException;import org.xmlpull.v1.XmlPullParserFactory;import com.wei.util.MyApplication;import android.app.AlertDialog;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.content.pm.PackageManager.NameNotFoundException;import android.os.Handler;/** * 版本更新主类,这里有调用UpdateService启动服务检查下载安装包等 1. 文件下载,下完后写入到sdcard 2. 如何在通知栏上显示下载进度 * 3. 下载完毕自动安装 4. 如何判断是否有新版本 *  * @author david */public class UpdateManager {private static String packageName;// = "com.yipinzhe"; // 应用的包名private static String jsonUrl = "version.txt"; // JSON版本文件URLprivate static String xmlUrl = "version.xml"; // XML版本文件URLprivate static final String DOWNLOAD_DIR = "/"; // 应用下载后保存的子目录private Context mContext;HashMap<String, String> mHashMap;// 保存解析的XML信息int versionCode, isNew;public UpdateManager(Context context) {this.mContext = context;packageName = context.getPackageName();jsonUrl = MyApplication.site + jsonUrl;xmlUrl = MyApplication.site + xmlUrl;checkVersion();}Handler checkHandler = new Handler() {@Overridepublic void handleMessage(android.os.Message msg) {if (msg.what == 1) {// 发现新版本,提示用户更新StringBuffer message = new StringBuffer();message.append(mHashMap.get("note").replace("|", "\n"));AlertDialog.Builder alert = new AlertDialog.Builder(mContext);alert.setTitle("软件升级").setMessage(message.toString()).setPositiveButton("更新",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog,int which) {// 开启更新服务UpdateServiceSystem.out.println("你点击了更新");Intent updateIntent = new Intent(mContext, UpdateService.class);/* * updateIntent.putExtra("downloadDir", * DOWNLOAD_DIR); * updateIntent.putExtra("apkUrl", * mHashMap.get("url")); */mContext.startService(updateIntent);}}).setNegativeButton("取消",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog,int which) {dialog.dismiss();}});alert.create().show();}};};/** 检查是否有新版本 */public void checkVersion() {try {// 获取软件版本号,对应AndroidManifest.xml下android:versionCodeversionCode = mContext.getPackageManager().getPackageInfo(packageName, 0).versionCode;} catch (NameNotFoundException e) {e.printStackTrace();}new Thread() {@Overridepublic void run() {String result = null;/* * try { //如果服务器端是JSON文本文件 result = * MyApplication.handleGet(jsonUrl); if (result != null) { * mHashMap = parseJSON(result); } } catch (Exception e1) { * e1.printStackTrace(); } */InputStream inStream = null;try {// 本机XML文件 inStream =  UpdateManager.class.getClassLoader().getResourceAsStream("version.xml");// 如果服务器端是XML文件inStream = new URL(xmlUrl).openConnection().getInputStream();if (inStream != null)mHashMap = parseXml(inStream);} catch (Exception e1) {e1.printStackTrace();}if (mHashMap != null) {int serviceCode = Integer.valueOf(mHashMap.get("version"));if (serviceCode > versionCode) {// 版本判断,返回true则有新版本isNew = 1;}}checkHandler.sendEmptyMessage(isNew);};}.start();}/** 解析服务器端的JSON版本文件 */public HashMap<String, String> parseJSON(String str) {HashMap<String, String> hashMap = new HashMap<String, String>();try {JSONObject obj = new JSONObject(str);hashMap.put("version", obj.getString("version"));hashMap.put("name", obj.getString("name"));hashMap.put("url", obj.getString("url"));hashMap.put("note", obj.getString("note"));} catch (JSONException e) {e.printStackTrace();}return hashMap;}/** 解析服务器端的XML版本文件 */public HashMap<String, String> parseXml(InputStream inputStream) {HashMap<String, String> hashMap = new HashMap<String, String>();try {XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();parser.setInput(inputStream, "GBK");//设置数据源编码int eventCode = parser.getEventType();//获取事件类型while(eventCode != XmlPullParser.END_DOCUMENT) {System.out.println("循环开始");switch (eventCode){case XmlPullParser.START_DOCUMENT: //开始读取XML文档  System.out.println("START_DOCUMENT");break;case XmlPullParser.START_TAG://开始读取某个标签if("version".equals(parser.getName())) {hashMap.put(parser.getName(), parser.nextText());} else if("name".equals(parser.getName())) {   hashMap.put(parser.getName(), parser.nextText());} else if("url".equals(parser.getName())) {   hashMap.put(parser.getName(), parser.nextText());} else if("note".equals(parser.getName())) {   hashMap.put(parser.getName(), parser.nextText());}break;    case XmlPullParser.END_TAG:    break;}   eventCode = parser.next();//继续读取下一个元素节点,并获取事件码    }System.out.println(hashMap.get("version"));} catch(Exception e) {}return hashMap;/*try {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();Document document = builder.parse(inStream);Element root = document.getDocumentElement();//获取根节点NodeList childNodes = root.getChildNodes();//获得所有子节点,然后遍历for (int j = 0; j < childNodes.getLength(); j++) {Node childNode = childNodes.item(j);if (childNode.getNodeType() == Node.ELEMENT_NODE) {Element childElement = (Element) childNode;if ("version".equals(childElement.getNodeName())) {hashMap.put("version", childElement.getFirstChild().getNodeValue());}else if (("name".equals(childElement.getNodeName()))) {hashMap.put("name", childElement.getFirstChild().getNodeValue());}else if (("url".equals(childElement.getNodeName()))) {hashMap.put("url", childElement.getFirstChild().getNodeValue());} else if (("note".equals(childElement.getNodeName()))) {hashMap.put("note", childElement.getFirstChild().getNodeValue());}}}} catch (Exception e) {e.printStackTrace();}*/}}

版本更新的服务类

package com.wei.update;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import com.wei.util.MyApplication;import com.wei.wotao.R;//import android.annotation.SuppressLint;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.Intent;import android.net.Uri;import android.os.Environment;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.view.View;import android.widget.RemoteViews;/** * 下载安装包的服务类 * @author david */public class UpdateService extends Service {// 文件存储private File saveDir;private File saveFile;private String apkUrl;// 通知栏private NotificationManager updateNotificationManager = null;private Notification updateNotification = null;// 通知栏跳转Intentprivate Intent updateIntent = null;private PendingIntent updatePendingIntent = null;// 下载状态private final static int DOWNLOAD_COMPLETE = 0;private final static int DOWNLOAD_FAIL = 1;private RemoteViews contentView;@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {System.out.println("onStartCommand");contentView = new RemoteViews(getPackageName(), R.layout.activity_app_update);// 获取传值String downloadDir = intent.getStringExtra("downloadDir");apkUrl = MyApplication.site+intent.getStringExtra("apkUrl");// 如果有SD卡,则创建APK文件if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState())) {saveDir = new File(Environment.getExternalStorageDirectory(),downloadDir);saveFile = new File(saveDir.getPath(), getResources().getString(R.string.app_name) + ".apk");}this.updateNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);this.updateNotification = new Notification();// 设置下载过程中,点击通知栏,回到主界面updateIntent = new Intent();updatePendingIntent = PendingIntent.getActivity(this, 0, updateIntent, 0);// 设置通知栏显示内容updateNotification.icon = R.drawable.icon_info;updateNotification.tickerText = "开始下载";updateNotification.contentView.setProgressBar(R.id.progressBar1, 100, 0, true);updateNotification.setLatestEventInfo(this,getResources().getString(R.string.app_name), "0%",updatePendingIntent);// 发出通知updateNotificationManager.notify(0, updateNotification);new Thread(new DownloadThread()).start();return super.onStartCommand(intent, flags, startId);}@Overridepublic IBinder onBind(Intent intent) {return null;}/** 下载的线程 */private class DownloadThread implements Runnable {Message message = updateHandler.obtainMessage();public void run() {message.what = DOWNLOAD_COMPLETE;if (saveDir!=null && !saveDir.exists()) {saveDir.mkdirs();}if (saveFile!=null && !saveFile.exists()) {try {saveFile.createNewFile();} catch (IOException e) {e.printStackTrace();}}try {long downloadSize = downloadFile(apkUrl, saveFile);if (downloadSize > 0) {// 下载成功updateHandler.sendMessage(message);}} catch (Exception ex) {ex.printStackTrace();message.what = DOWNLOAD_FAIL;updateHandler.sendMessage(message);// 下载失败}}public long downloadFile(String downloadUrl, File saveFile)throws Exception {int downloadCount = 0;int currentSize = 0;long totalSize = 0;int updateTotalSize = 0;int rate = 0;// 下载完成比例HttpURLConnection httpConnection = null;InputStream is = null;FileOutputStream fos = null;try {URL url = new URL(downloadUrl);httpConnection = (HttpURLConnection) url.openConnection();httpConnection.setRequestProperty("User-Agent","PacificHttpClient");if (currentSize > 0) {httpConnection.setRequestProperty("RANGE", "bytes="+ currentSize + "-");}httpConnection.setConnectTimeout(200000);httpConnection.setReadTimeout(200000);updateTotalSize = httpConnection.getContentLength();//获取文件大小if (httpConnection.getResponseCode() == 404) {throw new Exception("fail!");}is = httpConnection.getInputStream();fos = new FileOutputStream(saveFile, false);byte buffer[] = new byte[1024 * 1024 * 3];int readsize = 0;while ((readsize = is.read(buffer)) != -1) {fos.write(buffer, 0, readsize);totalSize += readsize;//已经下载的字节数rate = (int) (totalSize * 100 / updateTotalSize);//当前下载进度// 为了防止频繁的通知导致应用吃紧,百分比增加10才通知一次if ((downloadCount == 0) || rate - 0 > downloadCount) {downloadCount += 1;updateNotification.setLatestEventInfo(UpdateService.this, "正在下载", rate + "%",updatePendingIntent);//设置通知的内容、标题等updateNotification.contentView.setProgressBar(R.id.progressBar1, 100, rate, true);updateNotificationManager.notify(0, updateNotification);//把通知发布出去}}} finally {if (httpConnection != null) {httpConnection.disconnect();}if (is != null) {is.close();}if (fos != null) {fos.close();}}return totalSize;}}private Handler updateHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case DOWNLOAD_COMPLETE://当下载完毕,自动安装APK(ps,打电话 发短信的启动界面工作)Uri uri = Uri.fromFile(saveFile);//根据File获得安装包的资源定位符Intent installIntent = new Intent(Intent.ACTION_VIEW);//设置ActioninstallIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//新的Activity会在一个新任务打开,而不是在原先的任务栈installIntent.setDataAndType(uri, "application/vnd.android.package-archive");//设置URI的数据类型startActivity(installIntent);//把打包的Intent传递给startActivity//当下载完毕,更新通知栏,且当点击通知栏时,安装APKupdatePendingIntent = PendingIntent.getActivity(UpdateService.this, 0, installIntent, 0);updateNotification.defaults = Notification.DEFAULT_SOUND;// 铃声提醒updateNotification.setLatestEventInfo(UpdateService.this, getResources().getString(R.string.app_name),"下载完成,点击安装", updatePendingIntent);updateNotificationManager.notify(0, updateNotification);// 停止服务stopService(updateIntent);break;case DOWNLOAD_FAIL:// 下载失败updateNotification.setLatestEventInfo(UpdateService.this,getResources().getString(R.string.app_name),"下载失败,网络连接超时", updatePendingIntent);updateNotificationManager.notify(0, updateNotification);break;default:stopService(updateIntent);break;}}};}


更多相关文章

  1. Android(安卓)Studio 集成NDK 报错Error:No toolchains found in
  2. ADB源码分析(一)
  3. MAC操作系统上搭建Android开发平台环境
  4. Android(安卓)SDK下载安装及配置教程
  5. Android设置通知Notification
  6. android+eclipse+phonegap1.7(cordova)配置项目 .
  7. Android(安卓)Design Support Library使用示例(一)
  8. Android学习笔记10——Android的调试
  9. AndroidManifest.xml 文件里面的内容介绍

随机推荐

  1. Android中使用log4j
  2. Android获取在线视频的缩略图方式对比
  3. Android(安卓)SDK的环境变量配置
  4. Simulate android behaviors on win32
  5. android,No Launcher activity found!
  6. Android事件分发机制
  7. Android(安卓)结束进程的方法
  8. android中的震动
  9. Android(安卓)Studio 之 View组件常用属
  10. Error running app: Instant Run require