在过去的几天里,我的应用程序中遇到NotificationManager的问题,而且似乎离解决该问题的距离越来越近。
我有一个非常简单的ThreadPoolExecutor下载多个文件。但是同时我需要在通知栏中显示下载进度。
class DownloadTask implements Runnable{
String url;
String localFile;
DownloadResultUpdateTask resultUpdateTask;
Context mContext;
final int mNotificationId;
NotificationManager notificationManager;
Notification.Builder notificationBuilder;
PendingIntent pendingIntent;
public DownloadTask(String urlIn, String localFileIn,
DownloadResultUpdateTask drUpdateTask,Context context,int notificationId){
url = urlIn;
localFile = localFileIn;
resultUpdateTask = drUpdateTask;
mContext = context;
mNotificationId = notificationId;
}
@Override
public void run() {
String msg;
if(downloadFile(mNotificationId)){
msg = "file downloaded successful "+url;
}else{
msg = "failed to download the file "+url;
notificationBuilder.setContentTitle("Download Failed");
notificationManager.notify(mNotificationId, notificationBuilder.build());
}
//update results download status on the main thread
resultUpdateTask.setBackgroundMsg(msg);
DownloadManager.getDownloadManager().getMainThreadExecutor()
.execute(resultUpdateTask);
}
public boolean downloadFile(int notifId){
try{
//pending intent
Intent intent = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri apkUri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".provider", new File(localFile));
intent.setData(apkUri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
intent.setData(Uri.fromFile(new File(localFile)));
}
pendingIntent = PendingIntent.getActivity(mContext.getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//createing notification
notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
//Set notification information:
notificationBuilder = new Notification.Builder(mContext.getApplicationContext());
notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle("Downloading PDF")
.setContentText("0%")
.setProgress(100, 0, false)
.setAutoCancel(true)
.setPriority(Notification.PRIORITY_MAX)
.build();
//Send the notification:
Notification notification = notificationBuilder.build();
notificationManager.notify(notifId, notification);
//downloading file
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
Response response = client.newCall(request).execute();
InputStream in = response.body().byteStream();
FileOutputStream fileOutput =
new FileOutputStream(localFile);
byte[] buffer = new byte[1024*4];
int bufferLength = 0;
int target = (int) response.body().contentLength();
long downloaded = 0;
int currentPercentage = 0;
while ((bufferLength = in.read(buffer)) != -1) {
downloaded += bufferLength;
currentPercentage = (int)(downloaded * 100) / target;
if (currentPercentage >= 30 && currentPercentage <= 40 || currentPercentage >= 60 && currentPercentage <= 70
|| currentPercentage >= 90 && currentPercentage <= 100) {
notificationBuilder.setProgress(100, currentPercentage, false).setContentText(currentPercentage + "%");
notificationManager.notify(notifId, notificationBuilder.build()); // facing problem in thisl ine
}
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.close();
response.body().close();
notificationBuilder.setContentTitle("Download Completed");
notificationBuilder.setContentText("Click to open " + url.substring(url.lastIndexOf("/")+1));
notificationBuilder.setContentIntent(pendingIntent);
notificationManager.notify(mNotificationId, notificationBuilder.build());
}catch (Exception e){e.printStackTrace(); return false;}
return true;
}
我能够成功下载所有文件。但是在更新进度条时 我一直处于警告之下,因此通知被卡住,即使下载成功也不会显示下载成功。尽管每次我为不同的下载通知传递唯一的通知ID。
W/NotificationManager: notify: id corrupted: sent 519, got back 0
我添加了条件,仅在进度达到40、60或90到100之间时才更新进度,目的是尽量减少进度更新调用的次数以提高性能。
任何帮助表示赞赏。谢谢!