android 显示Notification,我们是要获取progress来让它显示具体的进度。
在下载或上传时,
while
((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
localSize += len;
float nowProcess = localSize/step;
if (nowProcess > process) {
process = nowProcess;
}
}
随着localSize的不断增加,计算所要的progress,会在一个工作线程下完成。
当然,Notification是可以在工作线程中创建的,但那些UI组件就不行了,必须在主线程进行更新。
如在上面创建Notification并使用progress,
if
(nowProcess > process) {
process = nowProcess;
mBuilder.setProgress(100,
process
,
false
);
nm
.notify(notificationId, mBuilder.build());
try
{
Thread.
sleep
(500);
} catch (InterruptedException e) {e.printStackTrace();}
}
在上传或下载过程中sleep一下,显然不太好。如果不sleep的话,太频繁调用nm.notify,UI会卡。
所以就打算把显示Notification放到UI线程上创建了,自然用到handler。
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case
SHOW_NOTIFICATION
:
....
showUploadNotification(id);
break;
}
};
};
handler 处理消息时,一个下载请求时没问题的,但多个请求同时处理的话,progress的值会不稳定。
所以,解决的方法就是,(id, handler) 配套来进行更新:)
弄个类先:
public class MutipleNotification {
private Context mContext;
private int notificationId;
private int oldId;
private String fileName;
private int process;
private Handler mHandler;
private ProgressDialog progressDialog;
private NotificationManager nm;
private boolean isDone;
public static final int TASK_DONE = 5;
public MutipleNotification(final Context context, NotificationManager nm) {
this.nm = nm;
mContext = context;
mHandler = new Handler(context.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case FileListActivity.SHOW_PROGRESS_DIALOG:
initProgressDialog(context);
break;
case FileListActivity.SHOW_NOTIFICATION:
process = msg.arg1;
progressDialog.setProgress(process);
notificationId = msg.arg2;
fileName = (String)msg.obj;
if (oldId < notificationId) {
showUploadNotification(notificationId);
oldId = notificationId;
}
break;
case TASK_DONE:
isDone = true;
break;
}
}
};
}
private void showUploadNotification(final int notificationId) {
new Thread(new Runnable(){public void run() {
Intent resultIntent = new Intent(mContext, WiFiDirectActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, resultIntent, 0);
final Notification.Builder mBuilder = new Notification.Builder(mContext);
mBuilder.setSmallIcon(R.drawable.upload)
.setContentTitle("Upload File " + fileName)
.setContentText("Upload in progress")
.setContentIntent(pendingIntent)
.setAutoCancel(true);
int level = 0;
int count = 0;
while(true) {
mBuilder.setProgress(100, process, false);
nm.notify(notificationId, mBuilder.build());
count++;
if (count % 3 == 0) {
level++;
if (level == 3) level = 0;
mBuilder.setSmallIcon(R.drawable.notification_view, level);
}
if (process >= 100 || isDone) {
mBuilder.setContentText("Upload finish").setProgress(0, 0, false);
nm.notify(notificationId, mBuilder.build());
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
break;
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};}).start();
}
private void initProgressDialog(Context context) {
progressDialog = new ProgressDialog(context);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setTitle(context.getString(R.string.progeress_title));
progressDialog.setCancelable(true);
progressDialog.show();
}
public int getNotificationId() {
return notificationId;
}
public void setNotificationId(int notificationId) {
this.notificationId = notificationId;
}
public int getProcess() {
return process;
}
public void setProcess(int process) {
this.process = process;
}
public Handler getmHandler() {
return mHandler;
}
public void setmHandler(Handler mHandler) {
this.mHandler = mHandler;
}
}
上传时:
new Thread(new Runnable(){@Override
public
void
run() {
countThread
++;
map.put(countThread,
new
MutipleNotification(FileListActivity.
this
,
nm
).getmHandler());
uploadFile(deviceIp, fileName, countThread);
}}).start();
这个map就是管理(id, handler)的,在工作线程中:
while
((len = raf.read(buffer)) != -1) {
out.write(buffer, 0, len);
localReadBytes += len;
if (localReadBytes/step != process) {
process = localReadBytes/step;
Message msg = ((Handler)map.get(id)).obtainMessage();
msg.what = SHOW_NOTIFICATION;
msg.arg1 = Float.valueOf(process).intValue();
msg.arg2 = id;
msg.obj = fileName;
((Handler) map.get(id)).sendMessage(msg);
}
}
看到没,每个id都能获得相对应的handler,都会到每个
MutipleNotification实例中去处理,这就不会混淆呢。