android通知栏应用程序更新,Android App自动更新之通知栏下载
本文实例为大家分享了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 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 parseJSON(String str) {
HashMap hashMap = new HashMap();
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 parseXml(InputStream inputStream) {
HashMap hashMap = new HashMap();
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;
}
}
};
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
android通知栏应用程序更新,Android App自动更新之通知栏下载相关推荐
- Android如何实现APP自动更新
先来看看要实现的效果图: 对于安卓用户来说,手机应用市场说满天飞可是一点都不夸张,比如小米,魅族,百度,360,机锋,应用宝等等,当我们想上线一款新版本APP时,先不说渠道打包的麻烦,单纯指上传APP ...
- Android APP 自动更新实现(适用Android9.0)
Android App自动更新基本上是每个App都需具备的功能,参考网上各种资料,自己整理了下,先来看看大致的界面: 一.实现思路: 1.发布Android App时,都会生成output-metad ...
- Android App自动更新解决方案(DownloadManager)
Android App自动更新解决方案(DownloadManager) 参考文章: (1)Android App自动更新解决方案(DownloadManager) (2)https://www.cn ...
- Android Studio开发环境下让App自动签名
Android Studio开发环境下让App自动签名 前言: 分享这个的原因有两个: 第一,在开发的过程中我们会发现关于微信的分享支付或者是支付宝的支付等一些功能的时候必须是要签名包,否则会失败,每 ...
- 安卓APP自动更新实现
一.参考文献 简单实现安卓app自动更新功能 - 简书 安卓app自动更新功能完美实现_白云天的博客-CSDN博客_android 自动更新 Android 实现自动更新及强制更新功能_farley的 ...
- web app升级—带进度条的App自动更新
带进度条的App自动更新,效果如下图所示: 技术:vue.vant-ui.5+ 封装独立组件AppProgress.vue: <template><div><van- ...
- flutter APP自动更新
flutter APP自动更新 前言 在pubspec.yaml中安装依赖 在main.dart文件中,初始化FlutterDownLoader 配置网络 在AndroidManifest.xml新增 ...
- 安卓APP自动更新功能实现
安卓APP自动更新功能实现 前言 代码实现 前言 安卓App自动更新基本上是每个App都需要具备的功能,接下来介绍一下实现自动更新的步骤. 代码实现 App自动更新主要分为新版本检测.升级弹窗.下载升 ...
- android app 自动更新,AndroidUpdateDemo
Android课程-App更新策略 @(Android) 第一节 课程介绍 概述 App更新是应用当中很常见的一个功能,基本上联网的app都应该具备这样的功能,对于更新迭代比较快速的产品,应用更新升级 ...
最新文章
- Python rstrip()方法 删除 string 字符串末尾的指定字符(默认为空格).
- 如何写出让 CPU 跑得更快的代码?
- IPSec 之 Server2003Cisco路由器(1)
- 关于Silverlight安装问题之二
- keras 多维时间序列预测
- nacos oaut服务地址_用户认证的例子:Spring Security oAuth2 + Spring Cloud Gateway + Nacos + Dubbo...
- SpringBoot入门 (一) HelloWorld
- ASP.NET MVC3数据绑定到VIEW的方式
- hog函数的用法 python_Python常见内置函数用法(三)
- 接口测试工具--apipost如何取消json参数中转义字符
- 遇劣势变蠢、发语音嘲讽人类……OpenAI这些奇葩DOTA操作跟谁学的?
- [转]谈谈团队的凝聚力
- Nginx负载均衡与反向代理——基础功能
- 车内看车头正不正技巧_交规理论最全技巧口诀,学会后100%过关!
- covariance matrix r语言_R语言 第2章 数据对象与数据读写(3)
- SAP BW常用后台事务码
- 开放、数字化、创新、合作……华为云发力ing!
- 杭电 2072 单词数(题解+代码)
- 15.2. logrotate - rotates, compresses, and mails system logs
- Go语言:模拟鼠标操作(go-vgo/robotgo)
热门文章
- Vue packages version mismatch:- vue@2.6.14 - vue-template-compiler@2.6.11解决方法
- 不是外部命令也不是可运行程序_手机运行内存4G和6G有什么不同?差别不是一般大...
- 什么水平的java工程师月薪3万起?
- Ruby小白入门笔记之Rubymine工具的快捷键
- 程序员编程艺术:第五章、寻找满足和为定值的两个或多个数
- Android每日一记
- Oracle 写存储过程的一个模板还有一些基本的知识点
- 《SEO的艺术(原书第2版)》——3.3 理解搜索引擎流量和用户意图
- RR调度(Round-robin scheduling)简单介绍
- 《软件工程(第4版?修订版)》—第2章2.9节本章对研究人员的意义