package com.zeng.update;
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.util.List;
import com.zeng.update.NotificationUpdateActivity.ICallbackResult;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.widget.RemoteViews;
public class DownloadService extends Service {
private static final int NOTIFY_ID = 0;
private int progress;
private NotificationManager mNotificationManager;
private boolean canceled;
// 返回的安装包url
private String apkUrl = "http://softfile.3g.qq.com:8080/msoft/179/24659/43549/qq_hd_mini_1.4.apk";
// private String apkUrl = MyApp.downloadApkUrl;
/* 下载包安装路径 */
private static final String savePath = "/sdcard/updateApkDemo/";
private static final String saveFileName = savePath + "3GQQ_AppUpdate.apk";
private ICallbackResult callback;
private DownloadBinder binder;
private MyApp app;
private boolean serviceIsDestroy = false;
private Context mContext = this;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case 0:
app.setDownload(false);
// 下载完毕
// 取消通知
mNotificationManager.cancel(NOTIFY_ID);
installApk();
break;
case 2:
app.setDownload(false);
// 这里是用户界面手动取消,所以会经过activity的onDestroy();方法
// 取消通知
mNotificationManager.cancel(NOTIFY_ID);
break;
case 1:
int rate = msg.arg1;
app.setDownload(true);
if (rate < 100) {
RemoteViews contentview = mNotification.contentView;
contentview.setTextViewText(R.id.tv_progress, rate + "%");
contentview.setProgressBar(R.id.progressbar, 100, rate, false);
} else {
System.out.println("下载完毕!!!!!!!!!!!");
// 下载完毕后变换通知形式
mNotification.flags = Notification.FLAG_AUTO_CANCEL;
mNotification.contentView = null;
Intent intent = new Intent(mContext, NotificationUpdateActivity.class);
// 告知已完成
intent.putExtra("completed", "yes");
// 更新参数,注意flags要使用FLAG_UPDATE_CURRENT
PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
mNotification.setLatestEventInfo(mContext, "下载完成", "文件已下载完毕", contentIntent);
//
serviceIsDestroy = true;
stopSelf();// 停掉服务自身
}
mNotificationManager.notify(NOTIFY_ID, mNotification);
break;
}
}
};
//
// @Override
// public int onStartCommand(Intent intent, int flags, int startId) {
// // TODO Auto-generated method stub
// return START_STICKY;
// }
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
System.out.println("是否执行了 onBind");
return binder;
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
System.out.println("downloadservice ondestroy");
// 假如被销毁了,无论如何都默认取消了。
app.setDownload(false);
}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
System.out.println("downloadservice onUnbind");
return super.onUnbind(intent);
}
@Override
public void onRebind(Intent intent) {
// TODO Auto-generated method stub
super.onRebind(intent);
System.out.println("downloadservice onRebind");
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
binder = new DownloadBinder();
mNotificationManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);
setForeground(true);// 这个不确定是否有作用
app = (MyApp) getApplication();
}
public class DownloadBinder extends Binder {
public void start() {
if (downLoadThread == null || !downLoadThread.isAlive()) {
progress = 0;
setUpNotification();
new Thread() {
public void run() {
// 下载
startDownload();
};
}.start();
}
}
public void cancel() {
canceled = true;
}
public int getProgress() {
return progress;
}
public boolean isCanceled() {
return canceled;
}
public boolean serviceIsDestroy() {
return serviceIsDestroy;
}
public void cancelNotification() {
mHandler.sendEmptyMessage(2);
}
public void addCallback(ICallbackResult callback) {
DownloadService.this.callback = callback;
}
}
private void startDownload() {
// TODO Auto-generated method stub
canceled = false;
downloadApk();
}
//
Notification mNotification;
// 通知栏
/**
* 创建通知
*/
private void setUpNotification() {
int icon = R.drawable.icon;
CharSequence tickerText = "开始下载";
long when = System.currentTimeMillis();
mNotification = new Notification(icon, tickerText, when);
;
// 放置在"正在运行"栏目中
mNotification.flags = Notification.FLAG_ONGOING_EVENT;
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.download_notification_layout);
contentView.setTextViewText(R.id.name, "腾讯QQ.apk 正在下载...");
// 指定个性化视图
mNotification.contentView = contentView;
Intent intent = new Intent(this, NotificationUpdateActivity.class);
// 下面两句是 在按home后,点击通知栏,返回之前activity 状态;
// 有下面两句的话,假如service还在后台下载, 在点击程序图片重新进入程序时,直接到下载界面,相当于把程序MAIN 入口改了 - -
// 是这么理解么。。。
// intent.setAction(Intent.ACTION_MAIN);
// intent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
// 指定内容意图
mNotification.contentIntent = contentIntent;
mNotificationManager.notify(NOTIFY_ID, mNotification);
}
//
/**
* 下载apk
*
* @param url
*/
private Thread downLoadThread;
private void downloadApk() {
downLoadThread = new Thread(mdownApkRunnable);
downLoadThread.start();
}
/**
* 安装apk
*
* @param url
*/
private void installApk() {
File apkfile = new File(saveFileName);
if (!apkfile.exists()) {
return;
}
Intent i = new Intent(Intent.ACTION_VIEW);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
mContext.startActivity(i);
callback.OnBackResult("finish");
}
private int lastRate = 0;
private Runnable mdownApkRunnable = new Runnable() {
@Override
public void run() {
try {
URL url = new URL(apkUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
int length = conn.getContentLength();
InputStream is = conn.getInputStream();
File file = new File(savePath);
if (!file.exists()) {
file.mkdirs();
}
String apkFile = saveFileName;
File ApkFile = new File(apkFile);
FileOutputStream fos = new FileOutputStream(ApkFile);
int count = 0;
byte buf[] = new byte[1024];
do {
int numread = is.read(buf);
count += numread;
progress = (int) (((float) count / length) * 100);
// 更新进度
Message msg = mHandler.obtainMessage();
msg.what = 1;
msg.arg1 = progress;
if (progress >= lastRate + 1) {
mHandler.sendMessage(msg);
lastRate = progress;
if (callback
yxkfw
- 粉丝: 82
- 资源: 2万+
最新资源
- 恒压供水一拖三实用程序,含FX2N和FX1N版本,配中达优控7寸屏和顾美文本屏,全注释,1000步完美程序,可直接应用 ,成品机器下载出来的,恒压供水一拖三,实用程序,带注释注解 本程序包括FX2N和
- "FX3u轮询27个压力表的简洁程序:实时数据、通讯状态、错误检测与调整功能",FX3u轮训27个压力表程序,思路清晰简洁,备注明确 程序中只用了一条通讯程序轮训, 全部程序加起来步数622, 实现
- 台达PLC与变频器Modbus RTU通讯:触摸屏控制变频器,注释齐全的程序指南,台达PLC与台达VFD变频器modbus 通讯案例 配件:台达DVP 14es的PLC,台达VFD M变频器 昆仑通
- 三菱PLC驱动的自动寻槽铣槽机编程案例解析:从传感器到变频器控制,三菱PLC项目案例学习之自动寻槽铣槽机 器件:三菱FX3UPLC,威纶通触摸屏,三菱伺服,基恩士光纤传感器,三菱变频器等 控制方式
- 松下PLC编程实例:FP-XH 10轴定位控制,RS485通讯,FB块应用与资料全套,松下PLC编程 FP-XH 10轴定位 松下PLC项目实例,两台CPU间通过RS485通讯,10轴定位控制
- "智能电网中配电网孤岛划分与故障重构策略研究",配电网孤岛划分及故障重构 ,配电网孤岛划分; 故障重构; 电力系统稳定性; 能源管理优化; 智能算法应用 ,"智能配电网孤岛划分与故障重构策略研究"
- 永磁同步无刷电机控制器商用方案:配套上位机,适应多种新能源车辆,功能齐全,涵盖老年代步车到环卫旅游车的综合应用,实时控制、自学习与能量回收方案全面解决方案 ,永磁同步无刷电机控制器方案 新能源电机台架
- 交直流可编程电源技术详解:TL494开关电源线路与DDS芯片控制交流变频输出,交直流可编程电源(技术资料) 直流电源是直流输出0-30V 5A TL494 线路; 交流电压是10-120HZ可变频
- 欧姆龙cp1h与NC413模块十轴控制案例,含DD马达控制与详细注释,昆仑通泰触摸屏程序集成,欧姆龙cp1h带两个nc413模块,总共十个轴控制程序案例,还有DD马达控制,内带详细注释,包含nc413
- 台达ES2 PLC与DTA4848V1温控器ASCII通讯程序:功能实现、接线指南、参数设置及注意事项,台达ES2与台达温控器ASCII通讯程序 硬件:台达
- ASIC FPGA异步FIFO小IP:灵活配置、深度位宽可扩展、读写时钟域报告、空满标志与FLUSH操作支持,ASIC FPGA异步FIFO小IP 可用于ASIC设计和FPGA设计 集成简单方便
- FPGA串口闭环收发小程序:高效支持9600与115200波特率,实现稳定数据传输,FPGA串口闭环收发小程序,支持9600和115200速率, ,核心关键词:FPGA;串口闭环收发;小程序;9600
- 无线电能传输电路仿真分析与MATLAB实现方法探索,matlab仿真 无线电能传输电路仿真 ,核心关键词:Matlab仿真; 无线电能传输; 电路仿真;,无线电能传输电路的Matlab仿真研究
- FPGA实现的CRC校验算法:支持CRC16、CRC32多种模式及CRC8算法解析,基于fpga CRC校验算法实现 CRC16 CRC32可任意支持模式 CRC8等 ,基于FPGA的CRC校验算法
- MES系统汽车底盘生产线数据追溯系统源码:基于VB开发,兼容多种PLC,稳定多年运行,可轻松升级至.NET,助力工程师快速开发,节省数月时间!,MES系统汽车底盘生产线数据追溯糸统源码,V B开发,下
- 信捷XD系列PLC通讯设备程序:十二轴控制功能强大,适合电气设计爱好者学习实践的经典案例,两个信捷XD系列PLC通讯设备程序,主站采用的是带十轴的XDM运动型PLC和副站采用的XD2PLC通讯,总共十
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈