package com.anthony.library.data.upload; 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.widget.RemoteViews; import com.anthony.library.R; import com.anthony.library.data.RxBus; import com.anthony.library.data.event.UploadEvent; import com.anthony.library.data.event.UploadEventInternal; import com.anthony.library.data.event.UploadFinishEvent; import com.anthony.library.utils.ToastUtils; import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action1; import rx.schedulers.Schedulers; /** * Created by Anthony on 2016/7/8. * Class Note: */ public class UploadService extends Service { public static String UPLOAD_URL = "UPLOAD_URL"; public static String UPLOAD_FILES = "UPLOAD_FILES"; public static String UPLOAD_PARAMS = "UPLOAD_PARAMS"; private static String ACTION = "UPLOAD_ACTION"; private static String UPLOAD_CANCEL_ID = "UPLOAD_CANCEL_ID"; private static int ACTION_CANCEL = 1; private NotificationManager mNotificationManager; private HashMap<Integer, UploadTask> mTaskMap = new HashMap<>(); ToastUtils toastUtils; @Override public void onCreate() { super.onCreate(); mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); RxBus.getDefault().toObserverable(UploadEventInternal.class) .onBackpressureBuffer() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<UploadEventInternal>() { @Override public void call(UploadEventInternal uploadEvent) { uploadEvent.task.progress += uploadEvent.byteCount; float percent = (float) uploadEvent.task.progress / (float) uploadEvent.task.total * 100; if (uploadEvent.task.current_percent != (int) percent) { uploadEvent.task.current_percent = (int) percent; uploadEvent.task.mNotification.contentView .setProgressBar(R.id.progressbar_upload, 100, (int) percent, false); if (mNotificationManager != null) { mNotificationManager.notify(uploadEvent.task.id, uploadEvent.task.mNotification); } Log.v("FileUpload", "Process: " + String.valueOf((int) percent)); RxBus.getDefault().post(new UploadEvent(uploadEvent.task.total, uploadEvent.task.progress, uploadEvent.task)); if ((int) percent == 100) { RxBus.getDefault().post(new UploadFinishEvent(uploadEvent.task, true)); } } } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { throwable.printStackTrace(); } }); RxBus.getDefault().toObserverable(UploadFinishEvent.class) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<UploadFinishEvent>() { @Override public void call(UploadFinishEvent uploadFinishEvent) { if (mNotificationManager != null) { mNotificationManager.cancel(uploadFinishEvent.task.id); } if (!uploadFinishEvent.isSuccess) { toastUtils.showToast("上传失败"); } mTaskMap.remove(uploadFinishEvent.task.id); } }, 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) { int id = intent.getIntExtra(UPLOAD_CANCEL_ID, -1); UploadTask task = mTaskMap.get(id); if (task != null) { if (mNotificationManager != null) { mNotificationManager.cancel(task.id); } task.cancel(); } } else { String url = intent.getStringExtra(UPLOAD_URL); List<UploadParam> fileList = intent.getParcelableArrayListExtra(UPLOAD_FILES); List<UploadParam> paramList = intent.getParcelableArrayListExtra(UPLOAD_PARAMS); if (!TextUtils.isEmpty(url) && fileList != null && fileList.size() > 0) { long total = 0; HashMap<String, File> fileMap = new HashMap<>(); for (UploadParam param : fileList) { File file = new File(param.value); total += file.length(); fileMap.put(param.key, file); } HashMap<String, String> paramMap = new HashMap<>(); if (paramList != null) { for (UploadParam param : paramList) { paramMap.put(param.key, param.value); } } UploadTask task = new UploadTask(mTaskMap.size(), url, fileMap, paramMap); task.total = total; mTaskMap.put(mTaskMap.size(), 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(); UploadTask task = (UploadTask) entry.getValue(); task.cancel(); } } private void createNotification(UploadTask task) { RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.lib_layout_upload_notification); remoteViews.setProgressBar(R.id.progressbar_upload, 100, 0, false); remoteViews.setTextViewText(R.id.tv_title, "正在上传" + task.mFileMap.size() + "个文件"); Intent cancelIntent = new Intent(this, UploadService.class); cancelIntent.putExtra(ACTION, ACTION_CANCEL); cancelIntent.putExtra(UPLOAD_CANCEL_ID, task.id); 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); } }