我有一项服务,该服务将在前台运行上传任务,然后在通知中显示进度。由于用户可能使用不同的id请求多次上传,因此将运行两个或多个前台服务。一切正常,但是我想要的是显示所有任务的通知以及此代码的进度。
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID_DEFAULT)
.setSmallIcon(R.drawable.ic_file_upload_white_24dp)
.setContentTitle(getString(R.string.app_name))
.setContentText(caption)
.setProgress(100, percentComplete, false)
.setContentInfo(String.valueOf(percentComplete +"%"))
.setOngoing(true)
.setAutoCancel(false);
NotificationManager manager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(code, builder.build());
startForeground(code,builder.build());
但是不幸的是,通知只是被覆盖,但是如果我删除了startForeground(),那么一切都会正常进行,因为它根据正在进行的任务数量显示了多个进度通知,但是如果内存不足,系统可能会终止该进程,这就是为什么我希望它在前台运行。那么,如何显示与前台中正在进行的任务数量相等的通知数量?
答案 0 :(得分:1)
在致电startForeground之前,您需要致电ServiceCompat.stopForeground(service, ServiceCompat.STOP_FOREGROUND_DETACH)
来保留旧的通知。
下面是一个实用程序类,您可以在前台服务中使用它来管理通知:
class ForegroundNotifications(
private val context: Context,
private val foregroundServiceHelper: ForegroundServiceHelper,
private val notificationService: NotificationService
) {
var activeNotificationId: Int? = null
private set
val notificationIds: Set<Int>
get() = entries.keys
val isEmpty: Boolean
get() = entries.isEmpty()
private val entries: LinkedHashMap<Int, Notification> = LinkedHashMap()
fun notifyAndDetachPrevious(notificationId: Int, notification: Notification) {
synchronized(this) {
foregroundServiceHelper.startForegroundAndDetachPreviousNotification(
notificationId,
notification
)
entries[notificationId] = notification
activeNotificationId = notificationId
}
}
fun cancel(notificationId: Int) {
synchronized(this) {
if (notificationId == activeNotificationId) {
val newActiveNotificationId = entries.keys.findLast { it != activeNotificationId }
val notification = entries[newActiveNotificationId]
if (newActiveNotificationId != null && notification != null) {
notifyAndDetachPrevious(newActiveNotificationId, notification)
}
}
entries.remove(notificationId)
if (isEmpty) {
foregroundServiceHelper.stopForeground()
} else {
notificationService.cancel(context, id = notificationId)
}
}
}
}
interface NotificationService {
fun createDefaultChannel(context: Context)
fun notify(context: Context, tag: String? = null, id: Int, notification: Notification)
fun cancel(context: Context, tag: String? = null, id: Int)
}
interface ForegroundServiceHelper {
fun startForegroundAndDetachPreviousNotification(
notificationId: Int,
notification: Notification
)
fun stopForeground()
}
class ForegroundServiceHelperImpl(
private val service: Service
) : ForegroundServiceHelper {
override fun startForegroundAndDetachPreviousNotification(
notificationId: Int,
notification: Notification
) {
ServiceCompat.stopForeground(service, ServiceCompat.STOP_FOREGROUND_DETACH)
service.startForeground(notificationId, notification)
}
override fun stopForeground() {
ServiceCompat.stopForeground(service, ServiceCompat.STOP_FOREGROUND_REMOVE)
}
}
答案 1 :(得分:0)
对不同的通知使用不同的ID。在此代码中,您使用相同的默认ID,因此新通知将替换旧通知。
答案 2 :(得分:0)
您应该传递不同的 Id 以获得不同的通知。
在您的代码中:
使用getId()
方法为每个通知获取不同的ID:
private static final AtomicInteger c = new AtomicInteger(0);
public static int getID() {
return c.incrementAndGet();
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID_DEFAULT)
.setSmallIcon(R.drawable.ic_file_upload_white_24dp)
.setContentTitle(getString(R.string.app_name))
.setContentText(caption)
.setProgress(100, percentComplete, false)
.setContentInfo(String.valueOf(percentComplete +"%"))
.setOngoing(true)
.setAutoCancel(false);
NotificationManager manager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(getId(), builder.build());
startForeground(getId(),builder.build()); // you need to pass different id here. Or i think this method is not there.
对于Android O ,您需要通知频道:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_HIGH);
// Configure the notification channel.
notificationChannel.setDescription("Channel description");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableVibration(true);
notificationChannel.setImportance(NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setSound(notification, Notification.AUDIO_ATTRIBUTES_DEFAULT);
notificationManager.createNotificationChannel(notificationChannel);
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
notificationBuilder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSound(notification)
.setContentIntent(pendingIntent)
.setContentText(message)
.setContentTitle(getResources().getString(R.string.app_name))
.setSmallIcon(R.drawable.ic_visualogyx_notification)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message).setBigContentTitle(getResources().getString(R.string.app_name)))
.setTicker("Hearty365")
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher_round));
notificationManager.notify(getID(),notificationBuilder.build());
答案 3 :(得分:0)
最后我弄清楚了怎么做。 首先,我需要稍稍延迟地在onCreate内运行它。
//Notification provider
private Notification getMyActivityNotification(String caption, long completedUnits, long totalUnits){
int percentComplete = 0;
if (totalUnits > 0) {
percentComplete = (int) (100 * completedUnits / totalUnits);
}
//Return the latest progress of task
return new NotificationCompat.Builder(this, CHANNEL_ID_DEFAULT)
.setSmallIcon(R.drawable.ic_file_upload_white_24dp)
.setContentTitle(getString(R.string.app_name))
.setContentText(caption)
.setProgress(100, percentComplete, false)
.setContentInfo(String.valueOf(percentComplete +"%"))
.setOngoing(true)
.setAutoCancel(false)
.build();
}
然后创建一个通知提供程序方法。
/**
* Show notification with a progress bar.
* Updating the progress happens here
*/
protected void showProgressNotification(String caption, long completedUnits, long totalUnits, int code) {
createDefaultChannel();
mCaption = caption;
requestCode = code;
completedParts = completedUnits;
totalSize = totalUnits;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (mNotificationManager != null) {
//Update the notification bar progress
mNotificationManager.notify(requestCode, getMyActivityNotification(caption,completedUnits,totalUnits));
}
}
然后将更新通知进度与调用前台分开。
{{1}}