如何在 Oreo 中创建下载进度通知?
How to create download progress notification in Oreo?
我正在创建一个可以从服务器下载文件并在状态栏中显示进度的应用程序。这是我的代码:
private void startDownload(final String fileUrl) {
Thread thread = new Thread() {
@Override
public void run() {
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(DownloadsActivity.this);
String contentTitle = "Start downloading";
Intent notifyIntent = new Intent();
PendingIntent notifyPendingIntent = PendingIntent.getActivity(DownloadsActivity.this, DOWNLOAD_NOTIFICATION_ID, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = createNotificationBuilder("downloader_channel");
notificationBuilder.setContentIntent(notifyPendingIntent);
notificationBuilder.setTicker("Start downloading from the server");
notificationBuilder.setOngoing(true);
notificationBuilder.setAutoCancel(false);
notificationBuilder.setSmallIcon(android.R.drawable.stat_sys_download);
notificationBuilder.setContentTitle(contentTitle);
notificationBuilder.setContentText("0%");
notificationBuilder.setProgress(100, 0, false);
notificationManagerCompat.notify(DOWNLOAD_NOTIFICATION_ID, notificationBuilder.build());
boolean success;
try {
String fileName = DownloadUtils.getInstance().getFullFileName(fileUrl);
File tmpFile = new File(fileName + ".tmp");
URL url = new URL(fileUrl);
URLConnection conection = url.openConnection();
conection.connect();
int fileLength = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream(tmpFile);
byte data[] = new byte[1024];
long total = 0;
int count, tmpPercentage = 0;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
int percentage = (int) ((total * 100) / fileLength);
if (percentage > tmpPercentage) {
notificationBuilder.setContentText(percentage + "%");
notificationBuilder.setProgress(100, percentage, false);
notificationManagerCompat.notify(DOWNLOAD_NOTIFICATION_ID, notificationBuilder.build());
tmpPercentage = percentage;
}
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
// rename file but cut off .tmp
File newFile = new File(fileName);
success = tmpFile.renameTo(newFile);
} catch (Exception e) {
showLog("[Download Error]: " + e.getMessage());
success = false;
}
showLog("Download finished");
contentTitle = "Downloaded";
String statusText = success ? "Done" : "Fail";
int resId = success ? android.R.drawable.stat_sys_download_done : android.R.drawable.stat_notify_error;
notificationBuilder.setContentTitle(contentTitle);
notificationBuilder.setSmallIcon(resId);
notificationBuilder.setOngoing(false);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setContentText(statusText);
notificationBuilder.setProgress(0, 0, false);
notificationManagerCompat.notify(DOWNLOAD_NOTIFICATION_ID, notificationBuilder.build());
isDownloading = false;
}
};
isDownloading = true;
thread.start();
}
private NotificationCompat.Builder createNotificationBuilder(String channelId) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
String channelName = getString(R.string.app_name);
NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setLightColor(Color.BLUE);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.createNotificationChannel(notificationChannel);
}
}
return new NotificationCompat.Builder(this, channelId);
}
在下载过程中,它会正确显示进度,但每完成一个百分比就会发出通知声音。还有一个问题是下载完成后,它仍然显示进度并且用户无法清除通知。
注意:它在旧版本上运行良好。只发生在 Android 8.
我在创建通知渠道时通过将 NotificationManager.IMPORTANCE_DEFAULT
更改为 NotificationManager.IMPORTANCE_LOW
解决了这个问题。
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setOnlyAlertOnce();
您不必设置通知 IMPORTANCE_LOW 您只需设置它 notification.setAlertOnlyOnce(true)。
下载完成后,可以使用新标题或说明更新通知,也可以关闭此通知并使用不同的通知 ID 创建新通知。
我正在创建一个可以从服务器下载文件并在状态栏中显示进度的应用程序。这是我的代码:
private void startDownload(final String fileUrl) {
Thread thread = new Thread() {
@Override
public void run() {
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(DownloadsActivity.this);
String contentTitle = "Start downloading";
Intent notifyIntent = new Intent();
PendingIntent notifyPendingIntent = PendingIntent.getActivity(DownloadsActivity.this, DOWNLOAD_NOTIFICATION_ID, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = createNotificationBuilder("downloader_channel");
notificationBuilder.setContentIntent(notifyPendingIntent);
notificationBuilder.setTicker("Start downloading from the server");
notificationBuilder.setOngoing(true);
notificationBuilder.setAutoCancel(false);
notificationBuilder.setSmallIcon(android.R.drawable.stat_sys_download);
notificationBuilder.setContentTitle(contentTitle);
notificationBuilder.setContentText("0%");
notificationBuilder.setProgress(100, 0, false);
notificationManagerCompat.notify(DOWNLOAD_NOTIFICATION_ID, notificationBuilder.build());
boolean success;
try {
String fileName = DownloadUtils.getInstance().getFullFileName(fileUrl);
File tmpFile = new File(fileName + ".tmp");
URL url = new URL(fileUrl);
URLConnection conection = url.openConnection();
conection.connect();
int fileLength = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream(tmpFile);
byte data[] = new byte[1024];
long total = 0;
int count, tmpPercentage = 0;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
int percentage = (int) ((total * 100) / fileLength);
if (percentage > tmpPercentage) {
notificationBuilder.setContentText(percentage + "%");
notificationBuilder.setProgress(100, percentage, false);
notificationManagerCompat.notify(DOWNLOAD_NOTIFICATION_ID, notificationBuilder.build());
tmpPercentage = percentage;
}
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
// rename file but cut off .tmp
File newFile = new File(fileName);
success = tmpFile.renameTo(newFile);
} catch (Exception e) {
showLog("[Download Error]: " + e.getMessage());
success = false;
}
showLog("Download finished");
contentTitle = "Downloaded";
String statusText = success ? "Done" : "Fail";
int resId = success ? android.R.drawable.stat_sys_download_done : android.R.drawable.stat_notify_error;
notificationBuilder.setContentTitle(contentTitle);
notificationBuilder.setSmallIcon(resId);
notificationBuilder.setOngoing(false);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setContentText(statusText);
notificationBuilder.setProgress(0, 0, false);
notificationManagerCompat.notify(DOWNLOAD_NOTIFICATION_ID, notificationBuilder.build());
isDownloading = false;
}
};
isDownloading = true;
thread.start();
}
private NotificationCompat.Builder createNotificationBuilder(String channelId) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
String channelName = getString(R.string.app_name);
NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setLightColor(Color.BLUE);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.createNotificationChannel(notificationChannel);
}
}
return new NotificationCompat.Builder(this, channelId);
}
在下载过程中,它会正确显示进度,但每完成一个百分比就会发出通知声音。还有一个问题是下载完成后,它仍然显示进度并且用户无法清除通知。
注意:它在旧版本上运行良好。只发生在 Android 8.
我在创建通知渠道时通过将 NotificationManager.IMPORTANCE_DEFAULT
更改为 NotificationManager.IMPORTANCE_LOW
解决了这个问题。
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setOnlyAlertOnce();
您不必设置通知 IMPORTANCE_LOW 您只需设置它 notification.setAlertOnlyOnce(true)。 下载完成后,可以使用新标题或说明更新通知,也可以关闭此通知并使用不同的通知 ID 创建新通知。