首页 > 系统 > Android > 正文

Android App自动更新之通知栏下载

2019-10-22 18:09:51
字体:
来源:转载
供稿:网友

本文实例为大家分享了Android App自动更新通知栏下载的具体代码,供大家参考,具体内容如下

版本更新说明

这里有调用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版本文件URL  private static String xmlUrl = "version.xml"; // XML版本文件URL  private 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() {  @Override  public 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() {    @Override    public void onClick(DialogInterface dialog,    int which) {    // 开启更新服务UpdateService    System.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() {    @Override    public void onClick(DialogInterface dialog,    int which) {    dialog.dismiss();    }   });  alert.create().show();  }  };  };   /**  *检查是否有新版本  */  public void checkVersion() {  try {  // 获取软件版本号,对应AndroidManifest.xml下android:versionCode  versionCode = mContext.getPackageManager().getPackageInfo(   packageName, 0).versionCode;  } catch (NameNotFoundException e) {  e.printStackTrace();  }   new Thread() {  @Override  public 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;   // 通知栏跳转Intent  private Intent updateIntent = null;  private PendingIntent updatePendingIntent = null;   // 下载状态  private final static int DOWNLOAD_COMPLETE = 0;  private final static int DOWNLOAD_FAIL = 1;   private RemoteViews contentView;   @Override  public 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);  }   @Override  public 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() {  @Override  public 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);//设置Action  installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//新的Activity会在一个新任务打开,而不是在原先的任务栈  installIntent.setDataAndType(uri, "application/vnd.android.package-archive");//设置URI的数据类型  startActivity(installIntent);//把打包的Intent传递给startActivity    //当下载完毕,更新通知栏,且当点击通知栏时,安装APK  updatePendingIntent = 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;  }  }  }; } 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表