最近要做一个更新sdk,里面用到了service后台下载,自定义通知提示下载进度,下面直接贴上代码.

下面是UpdateUtils.java ,告诉你如何使用

package com.cnziz.updatelib;import com.cnziz.updatelib.download.DownloadServices;
import com.cnziz.updatelib.utils.Listener.onUpdateListener;import android.content.Context;
import android.content.Intent;public class UpdateUtils {public static UpdateUtils mUpdateUtils;public static UpdateUtils getInstanse(){if (null == mUpdateUtils) {mUpdateUtils = new UpdateUtils();}return mUpdateUtils;}public void update(Context context, String appInfo, onUpdateListener mUpdateListener){String url = "https://qd.myapp.com/myapp/qqteam/AndroidQQ/mobileqq_android.apk";String filePath = "/sdcard/download";download(context, url, filePath, mUpdateListener);}/*** 下载更新* @param context* @param url           下载地址* @param filePath      保存目录* @param mUpdateListener*/public void download(Context context, String url, String filePath, onUpdateListener mUpdateListener){Intent intent = new Intent(context, DownloadServices.class);intent.putExtra("url", url);intent.putExtra("file_path", filePath);context.startService(intent);}
}

DownloadService.java

package com.cnziz.updatelib.download;import java.io.File;
import java.io.IOException;import android.app.Notification;
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.util.Log;import com.cnziz.updatelib.R;
import com.cnziz.updatelib.utils.Listener.onUpdateListener;
import com.cnziz.updatelib.utils.LogUtils;public class DownloadServices extends Service {private final static int DOWNLOAD_COMPLETE = -2;private final static int DOWNLOAD_FAIL = -1;// 自定义通知栏类MyNotification myNotification;String filePathString; // 下载文件绝对路径(包括文件名)// 通知栏跳转Intentprivate Intent updateIntent = null;private PendingIntent updatePendingIntent = null;DownFileThread downFileThread; // 自定义文件下载线程private onUpdateListener mUpdateListener;private Handler updateHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case DOWNLOAD_COMPLETE:// 点击安装PendingIntentUri uri = Uri.fromFile(downFileThread.getApkFile());Intent installIntent = new Intent(Intent.ACTION_VIEW);installIntent.setDataAndType(uri,"application/vnd.android.package-archive");installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(installIntent);
//              updatePendingIntent = PendingIntent.getActivity(
//                      DownloadServices.this, 0, installIntent, 0);
//              myNotification.changeContentIntent(updatePendingIntent);
//              myNotification.notification.defaults = Notification.DEFAULT_SOUND;// 铃声提醒
//              myNotification.changeNotificationText("下载完成,请点击安装!");// 停止服务// myNotification.removeNotification();stopSelf();break;case DOWNLOAD_FAIL:// 下载失败// myNotification.changeProgressStatus(DOWNLOAD_FAIL);myNotification.changeNotificationText("文件下载失败!");mUpdateListener.downloadFail();stopSelf();break;default: // 下载中LogUtils.e("service", "index" + msg.what);// myNotification.changeNotificationText(msg.what+"%");myNotification.changeProgressStatus(msg.what);}}};public DownloadServices() {// TODO Auto-generated constructor stub// mcontext=context;LogUtils.e("service", "DownloadServices1");}@Overridepublic void onCreate() {// TODO Auto-generated method stubLogUtils.e("service", "onCreate");super.onCreate();}@Overridepublic void onDestroy() {// TODO Auto-generated method stubLogUtils.e("service", "onDestroy");if (downFileThread != null)downFileThread.interuptThread();
//      if (null != myNotification) {
//          myNotification.removeNotification();
//      }stopSelf();super.onDestroy();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Auto-generated method stubLogUtils.e("service", "onStartCommand");String url = intent.getStringExtra("url");String filePath = intent.getStringExtra("file_path");mUpdateListener = (onUpdateListener) intent.getParcelableExtra("listener");// updateIntent = new Intent(this, MainActivity.class);// PendingIntent updatePendingIntent = PendingIntent.getActivity(this,// 0,// updateIntent, 0);myNotification = new MyNotification(this, updatePendingIntent, 1);// myNotification.showDefaultNotification(R.drawable.ic_launcher, "测试",// "开始下载");myNotification.showCustomizeNotification(R.drawable.ic_launcher,"测试下载", R.layout.notification);if (!filePath.endsWith("/")) {filePath = filePath +"/";}File path = new File(filePath);if (!path.exists()) {path.mkdir();}String[] s = url.split("/");filePathString = filePath + s[s.length-1];File file = new File(filePathString);if (!file.exists()) {try {file.createNewFile();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}// 开启一个新的线程下载,如果使用Service同步下载,会导致ANR问题,Service本身也会阻塞downFileThread = new DownFileThread(updateHandler,url,filePathString);new Thread(downFileThread).start();return super.onStartCommand(intent, flags, startId);}@Override@Deprecatedpublic void onStart(Intent intent, int startId) {// TODO Auto-generated method stubLogUtils.e("service", "onStart");super.onStart(intent, startId);}@Overridepublic IBinder onBind(Intent arg0) {// TODO Auto-generated method stubLogUtils.e("service", "onBind");return null;}}

下载线程 DownFileThread.java

package com.cnziz.updatelib.download;import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;import com.cnziz.updatelib.utils.LogUtils;import android.annotation.SuppressLint;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.util.Log;public class DownFileThread implements Runnable {public final static int DOWNLOAD_COMPLETE = -2;public final static int DOWNLOAD_FAIL = -1;public final static String TAG = "DownFileThread";Handler mHandler; // 传入的Handler,用于像Activity或service通知下载进度String urlStr; // 下载URLFile apkFile; // 文件保存路径boolean isFinished; // 下载是否完成boolean interupted = false; // 是否强制停止下载线程public DownFileThread(Handler handler, String urlStr, String filePath) {LogUtils.i(TAG, urlStr);this.mHandler = handler;this.urlStr = urlStr;apkFile = new File(filePath);isFinished = false;}public File getApkFile() {if (isFinished)return apkFile;elsereturn null;}public boolean isFinished() {return isFinished;}/*** 强行终止文件下载*/public void interuptThread() {interupted = true;}@SuppressLint("NewApi")@Overridepublic void run() {// TODO Auto-generated method stubif (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {java.net.URL url = null;HttpURLConnection conn = null;InputStream iStream = null;// if (DEVELOPER_MODE){StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork() // or .detectAll() for all// detectable problems.penaltyLog().build());StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());}try {url = new java.net.URL(urlStr);conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(5 * 1000);conn.setReadTimeout(20 * 1000);iStream = conn.getInputStream();} catch (MalformedURLException e) {LogUtils.e(TAG, "MalformedURLException");e.printStackTrace();} catch (Exception e) {LogUtils.e(TAG, "获得输入流失败");e.printStackTrace();}FileOutputStream fos = null;try {fos = new FileOutputStream(apkFile);} catch (FileNotFoundException e) {LogUtils.i(TAG, "获得输出流失败:new FileOutputStream(apkFile);");e.printStackTrace();}BufferedInputStream bis = new BufferedInputStream(iStream);byte[] buffer = new byte[1024];int len;// 获取文件总长度int length = conn.getContentLength();double rate = (double) 100 / length; // 最大进度转化为100int timeLoad = length/100/1024;int total = 0;int times = 0;// 设置更新频率,频繁操作UI线程会导致系统奔溃try {LogUtils.e("threadStatus", "开始下载");while (false == interupted && ((len = bis.read(buffer)) != -1)) {fos.write(buffer, 0, len);// 获取已经读取长度total += len;int p = (int) (total * rate);// Log.e("num", rate + "," + total + "," + p);if (times >= timeLoad || p == 100) {/** 这是防止频繁地更新通知,而导致系统变慢甚至崩溃。 非常重要。。。。。*/LogUtils.e("time", String.valueOf(times));times = 0;Message msg = Message.obtain();msg.what = p;mHandler.sendMessage(msg);}times++;}fos.close();bis.close();iStream.close();if (total == length) {isFinished = true;mHandler.sendEmptyMessage(DOWNLOAD_COMPLETE);LogUtils.e(TAG, "下载完成结束");return;}LogUtils.e(TAG, "强制中途结束");// mhandler.sendEmptyMessage(4);} catch (IOException e) {LogUtils.e(TAG, "异常中途结束");mHandler.sendEmptyMessage(DOWNLOAD_FAIL);e.printStackTrace();}} else {LogUtils.e(TAG, "外部存储卡不存在,下载失败!");mHandler.sendEmptyMessage(DOWNLOAD_FAIL);}}
}

自定义通知 MyNotification.java

package com.cnziz.updatelib.download;import com.cnziz.updatelib.R;import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.widget.RemoteViews;public class MyNotification {public final static int DOWNLOAD_COMPLETE = -2;public final static int DOWNLOAD_FAIL = -1;Context mContext; // Activity或Service上下文Notification notification; // notificationNotificationManager nm;String titleStr; // 通知标题String contentStr; // 通知内容PendingIntent contentIntent; // 点击通知后的动作int notificationID; // 通知的唯一标示IDint iconID; // 通知栏图标long when = System.currentTimeMillis();RemoteViews remoteView = null; // 自定义的通知栏视图/*** * @param context*            Activity或Service上下文* @param contentIntent*            点击通知后的动作* @param id*            通知的唯一标示ID*/public MyNotification(Context context, PendingIntent contentIntent, int id) {// TODO Auto-generated constructor stubmContext = context;notificationID = id;this.contentIntent = contentIntent;this.nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);}/*** 显示自定义通知* * @param icoId*            自定义视图中的图片ID* @param titleStr*            通知栏标题* @param layoutId*            自定义布局文件ID*/public void showCustomizeNotification(int icoId, String titleStr,int layoutId) {this.titleStr = titleStr;notification = new Notification(R.drawable.ic_launcher, titleStr, when);notification.flags = Notification.FLAG_ONLY_ALERT_ONCE;notification.flags |= Notification.FLAG_AUTO_CANCEL;notification.contentIntent = this.contentIntent;// 1、创建一个自定义的消息布局 view.xml// 2、在程序代码中使用RemoteViews的方法来定义image和text。然后把RemoteViews对象传到contentView字段if (remoteView == null) {remoteView = new RemoteViews(mContext.getPackageName(), layoutId);remoteView.setImageViewResource(R.id.ivNotification, icoId);remoteView.setTextViewText(R.id.tvTitle, titleStr);remoteView.setTextViewText(R.id.tvTip, "开始下载");remoteView.setProgressBar(R.id.pbNotification, 100, 0, false);notification.contentView = remoteView;}nm.notify(notificationID, notification);}/*** 更改自定义布局文件中的进度条的值* * @param p*            进度值(0~100)*/public void changeProgressStatus(int p) {if (notification.contentView != null) {if (p == DOWNLOAD_FAIL)notification.contentView.setTextViewText(R.id.tvTip, "下载失败! ");else if (p == 100)notification.contentView.setTextViewText(R.id.tvTip,"下载完成,请点击安装");elsenotification.contentView.setTextViewText(R.id.tvTip, "进度(" + p+ "%)");notification.contentView.setProgressBar(R.id.pbNotification, 100,p, false);}nm.notify(notificationID, notification);}public void changeContentIntent(PendingIntent intent) {this.contentIntent = intent;notification.contentIntent = intent;}/*** 显示系统默认格式通知* * @param iconId*            通知栏图标ID* @param titleText*            通知栏标题* @param contentStr*            通知栏内容*/public void showDefaultNotification(int iconId, String titleText,String contentStr) {this.titleStr = titleText;this.contentStr = contentStr;this.iconID = iconId;notification = new Notification();notification.tickerText = titleStr;notification.icon = iconID;notification.flags = Notification.FLAG_INSISTENT;notification.flags |= Notification.FLAG_AUTO_CANCEL;notification.contentIntent = this.contentIntent;// 添加声音效果// notification.defaults |= Notification.DEFAULT_SOUND;// 添加震动,后来得知需要添加震动权限 : Virbate Permission// mNotification.defaults |= Notification.DEFAULT_VIBRATE ;// 添加状态标志// FLAG_AUTO_CANCEL 该通知能被状态栏的清除按钮给清除掉// FLAG_NO_CLEAR 该通知能被状态栏的清除按钮给清除掉// FLAG_ONGOING_EVENT 通知放置在正在运行// FLAG_INSISTENT 通知的音乐效果一直播放notification.flags = Notification.FLAG_ONLY_ALERT_ONCE;changeNotificationText(contentStr);}/*** 改变默认通知栏的通知内容* * @param content*/public void changeNotificationText(String content) {notification.setLatestEventInfo(mContext, titleStr, content,contentIntent);// 设置setLatestEventInfo方法,如果不设置会App报错异常// NotificationManager mNotificationManager = (NotificationManager)// getSystemService(Context.NOTIFICATION_SERVICE);// 注册此通知// 如果该NOTIFICATION_ID的通知已存在,会显示最新通知的相关信息 ,比如tickerText 等nm.notify(notificationID, notification);}/*** 移除通知*/public void removeNotification() {// 取消的只是当前Context的Notificationnm.cancel(notificationID);}
}

主要代码都在这了,下面是完整的项目链接
https://github.com/yan1348/ServiceDownLoad

Android Service下载文件并自定义通知提示下载相关推荐

  1. 下载文件时火狐总是提示“已屏蔽:可能含有病毒或间谍软件”

    下载文件时火狐总是提示"已屏蔽:可能含有病毒或间谍软件",这可能是windows defender做的好事. windows defender会把winloader等软件当作是间谍 ...

  2. php下载apk文件源码下载,PHP_php下载文件源代码(强制任意文件格式下载),一个简单的php文件下载源代码 - phpStudy...

    php下载文件源代码(强制任意文件格式下载) 一个简单的php文件下载源代码,虽不支持断点续传等,但是可以满足一些常用的需求了.php下载文件其实用一个a标签就能实现,比如 magento-1.8.1 ...

  3. python下载文件加上日期_Python实现给下载文件显示进度条和下载时间代码

    本篇文章小编给大家分享一下Python实现给下载文件显示进度条和下载时间代码,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 该模块调用了三个库: 1. ...

  4. C++ vs2017 - libcurl - http请求 代码大全(请求数据,上传下载文件,多线程上传下载文件)

    在网上搜寻各种libcurl的用法,将代码集合于此! 目录 一.配置curl项目 二.Curl 请求参数 1. CURLOPT_POST 2. CURLOPT_URL 3. CURLOPT_HTTPH ...

  5. uniapp下载文件保存自定义目录

    uniapp文件操作依赖IO模块,网上很多小白都不知道怎么下载文件到手机自定义目录, 看官方文档下载文件永久保存uni.downloadFile和uni.saveFile,文件存放的位置开始时临时的, ...

  6. android 从本地服务器下载文件,Retrofit2-如何从服务器下载文件

    在这篇博客中,将会讲述使用Retrofit十分需要的一个功能:怎么去下载文件,下面会展示一些下载文件需要写的代码片段,从小的 png 图片到大的 zip文件.

  7. java后台批量下载文件并压缩成zip下载

    因项目需要,将服务器上的图片文件压缩打包zip,下载到本地桌面. 首先,前端js: function doQueryPic() {var picsDate = $("#picsDate&qu ...

  8. 微信H5下载文件、微信浏览器无法下载文件解决方案

    手机端的微信访问网页的时候,是禁止直接下载文件的 但是IOS端可以预览.txt/.doc/.docx/.xls/xlsx/.pdf等格式的文件,Android端在下载这些格式的文件时,可以唤起 '即将 ...

  9. php通过ajax下载文件,通过ajax调用php下载文件

    我有一个按钮,点击它会调用ajax函数. 这是我的ajax功能 function csv(){ ajaxRequest = ajax();//ajax() is function that has a ...

最新文章

  1. 你真的看懂招聘要求了?
  2. sm4 的s盒_SM4国密算法Java版
  3. python中if的效率_Python算法效率和增长量级,经典题目回顾
  4. 执行计划--为查询指定查询计划
  5. 为什么有必要对网站开启https?
  6. Gearman + Nodejs + MySQL UDF异步实现 MySQL 到 Redis 的数据同步
  7. JMeter性能测试工具简介
  8. java 泛型 多态_Java 多态
  9. 10月10日见!官方再曝OPPO K5外观配置细节:6400万超清四摄加持
  10. hdu 3371 Connect the Cities(prim算法)
  11. IBM OmniFind Enterprise Starter Edition
  12. 显示器尺寸对照表_怎样知道自己的电脑显示器是多少寸的
  13. hive清空外部表的三种方式
  14. 程序员老了之后练太极最合适了
  15. 最保险的“跳槽理由”
  16. 实用工具篇 | PPT图表制作软件
  17. 常见面试题及解答|计算机网络
  18. html按钮扁平化,HTML5和CSS3扁平化风格博客教程的资源分享
  19. 微信开发:NAT穿透
  20. QQ邮箱如何获得邮我代码

热门文章

  1. poj2418map或者字典树
  2. 【C 语言】结构体 ( 结构体 数组 作为函数参数 | 数组 在 堆内存创建 )
  3. 【BLE MIDI】推荐一个 Android 平台开源 MIDI 软件 MidiSheetMusic ( 相关资料 | Android Studio 中导入 Eclipse 源码 )
  4. 【Android CPU 优化】Android CPU 调优 ( Trace 文件分析 | Android Profiler 工具 | CPU Profiler 工具 )
  5. 【计算理论】自动机 示例 ( 自动机示例 | 自动机表示方式 | 自动机计算流程简介 )
  6. 【数据挖掘】贝叶斯分类 ( 贝叶斯分类器 | 贝叶斯推断 | 逆向概率 | 贝叶斯公式 | 贝叶斯公式推导 | 使用贝叶斯公式求逆向概率 )
  7. 如何使用Bootstrap4显示和隐藏元素
  8. p1209 Barn Repair
  9. [hiho1159] Poker
  10. 一种比较兼容的Excel报表导出方法