您的位置:首页 > 移动开发 > Android开发

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

2018-06-13 08:52 896 查看

本文实例为大家分享了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;
}
}
};
}

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

您可能感兴趣的文章:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android App 自动更新