package com.anthony.library.data.download; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.IBinder; import android.support.annotation.Nullable; import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.RemoteViews; import android.widget.Toast; import com.anthony.library.R; import com.anthony.library.data.RxBus; import com.anthony.library.utils.FileUtil; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action1; import rx.schedulers.Schedulers; /** * Created by Anthony on 2016/6/12. * Class Note: * Download Service to load {@link NotificationManager} */ public class DownloadService extends Service { public static String DOWNLOAD_URL = "DOWNLOAD_URL"; private static String ACTION = "DOWNLOAD_ACTION"; private static int ACTION_CANCEL = 1; private NotificationManager mNotificationManager; private HashMap<String, DownloadTask> mTaskMap = new HashMap<>(); @Override public void onCreate() { super.onCreate(); mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); RxBus.getDefault() .toObserverable(DownloadEvent.class) .onBackpressureBuffer() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<DownloadEvent>() { @Override public void call(DownloadEvent downloadEvent) { if (downloadEvent.total != -1) { float percent = (float) downloadEvent.progress / (float) downloadEvent.total * 100; //整数值未变没就不更新通知栏,否则通知栏更新太频繁会导致卡顿 if (downloadEvent.task.current_percent != (int) percent) { downloadEvent.task.current_percent = (int) percent; downloadEvent.task.mNotification.contentView .setProgressBar(R.id.progressbar_download, 100, (int) percent, false); if (mNotificationManager != null) { mNotificationManager.notify(downloadEvent.task.id, downloadEvent.task.mNotification); } Log.v("FileDownload", "Process: " + String.valueOf((int) percent)); } } else { if (!downloadEvent.task.isUnknownLength) { downloadEvent.task.isUnknownLength = true; downloadEvent.task.mNotification.contentView .setViewVisibility(R.id.progressbar_download, View.INVISIBLE); downloadEvent.task.mNotification.contentView .setViewVisibility(R.id.progressbar_download_unknown, View.VISIBLE); if (mNotificationManager != null) { mNotificationManager.notify(downloadEvent.task.id, downloadEvent.task.mNotification); } } } } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { throwable.printStackTrace(); } }); RxBus.getDefault() .toObserverable(DownloadFinishEvent.class) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<DownloadFinishEvent>() { @Override public void call(DownloadFinishEvent downloadFinishEvent) { if (mNotificationManager != null) { mNotificationManager.cancel(downloadFinishEvent.task.id); mNotificationManager = null; } if (!downloadFinishEvent.isSuccess) { Toast.makeText(getApplicationContext(), "下载失败", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "下载成功", Toast.LENGTH_SHORT).show(); } mTaskMap.remove(downloadFinishEvent.task.mUrl); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { throwable.printStackTrace(); } }); } @Override public int onStartCommand(Intent intent, int flags, int startId) { int action = intent.getIntExtra(ACTION, 0); if (action == ACTION_CANCEL) { String url = intent.getStringExtra(DOWNLOAD_URL); DownloadTask task = mTaskMap.get(url); if (mNotificationManager != null) { mNotificationManager.cancel(task.id); } task.cancel(); } else { String url = intent.getStringExtra(DOWNLOAD_URL); if (!TextUtils.isEmpty(url)) { if (mTaskMap.containsKey(url)) { Toast.makeText(getApplicationContext(), "正在下载中...", Toast.LENGTH_SHORT).show(); } else { DownloadTask task = new DownloadTask(mTaskMap.size(), url, getApplicationContext()); mTaskMap.put(url, task); task.start(); createNotification(task); } } } return super.onStartCommand(intent, flags, startId); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { mNotificationManager = null; cancelAll(); super.onDestroy(); } private void cancelAll() { Iterator iterator = mTaskMap.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); DownloadTask task = (DownloadTask) entry.getValue(); task.cancel(); } } private void createNotification(DownloadTask task) { RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.lib_layout_download_notification); remoteViews.setProgressBar(R.id.progressbar_download, 100, 0, false); remoteViews.setTextViewText(R.id.tv_title, "正在下载" + FileUtil.getUrlFileName(task.mUrl)); Intent cancelIntent = new Intent(this, DownloadService.class); cancelIntent.putExtra(ACTION, ACTION_CANCEL); cancelIntent.putExtra(DOWNLOAD_URL, task.mUrl); PendingIntent intent = PendingIntent.getService(this, task.id, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.layout_btn_cancel, intent); NotificationCompat.Builder builder = new NotificationCompat.Builder(this) .setContent(remoteViews) .setSmallIcon(R.mipmap.ic_launcher) .setAutoCancel(false) //将AutoCancel设为true后,当你点击通知栏的notification后,它会自动被取消消失 .setPriority(NotificationCompat.PRIORITY_MAX) //从Android4.1开始,可以设置notification的优先级,优先级越高的,通知排的越靠前,优先级低的,不会在手机最顶部的状态栏显示图标 .setOngoing(true) //将Ongoing设为true 那么notification将不能滑动删除 .setTicker("下载中,请稍等..."); task.mNotification = builder.build(); mNotificationManager.notify(task.id, task.mNotification); } }