如何在Android中更新前台服务的通知文本?
我在安卓系统中安装了前台服务。我想更新通知文本。我正在创建如下所示的服务 如何更新此前台服务中设置的通知文本?更新通知的最佳做法是什么?任何示例代码都将不胜感激如何在Android中更新前台服务的通知文本?,android,service,notifications,foreground,Android,Service,Notifications,Foreground,我在安卓系统中安装了前台服务。我想更新通知文本。我正在创建如下所示的服务 如何更新此前台服务中设置的通知文本?更新通知的最佳做法是什么?任何示例代码都将不胜感激 public class NotificationService extends Service { private static final int ONGOING_NOTIFICATION = 1; private Notification notification; @Override pub
public class NotificationService extends Service {
private static final int ONGOING_NOTIFICATION = 1;
private Notification notification;
@Override
public void onCreate() {
super.onCreate();
this.notification = new Notification(R.drawable.statusbar, getText(R.string.app_name), System.currentTimeMillis());
Intent notificationIntent = new Intent(this, AbList.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
this.notification.setLatestEventInfo(this, getText(R.string.app_name), "Update This Text", pendingIntent);
startForeground(ONGOING_NOTIFICATION, this.notification);
}
我正在我的主要活动中创建服务,如下所示:
// Start Notification Service
Intent serviceIntent = new Intent(this, NotificationService.class);
startService(serviceIntent);
我认为再次使用相同的唯一ID调用
startForeground()
,并使用新信息发出通知将是可行的,尽管我没有尝试过这种情况
更新:根据评论,您应该使用NotifcationManager更新通知,并且您的服务将继续处于前台模式。请看下面的答案。以下是在您的服务中执行此操作的代码。创建新通知,但要求通知管理器通知您在startForeground中使用的相同通知id
Notification notify = createNotification();
final NotificationManager notificationManager = (NotificationManager) getApplicationContext()
.getSystemService(getApplicationContext().NOTIFICATION_SERVICE);
notificationManager.notify(ONGOING_NOTIFICATION, notify);
有关完整示例代码,您可以在此处查看:
当您想更新startForeground()设置的通知时,只需构建一个新的通知,然后使用NotificationManager通知它即可
关键是使用相同的通知id
我没有测试重复调用startForeground()来更新通知的场景,但我认为使用NotificationManager.notify会更好
更新通知不会将服务从前台状态删除(这只能通过调用stopForground来完成)
例如:
private static final int NOTIF_ID=1;
@Override
public void onCreate (){
this.startForeground();
}
private void startForeground() {
startForeground(NOTIF_ID, getMyActivityNotification(""));
}
private Notification getMyActivityNotification(String text){
// The PendingIntent to launch our activity if the user selects
// this notification
CharSequence title = getText(R.string.title_activity);
PendingIntent contentIntent = PendingIntent.getActivity(this,
0, new Intent(this, MyActivity.class), 0);
return new Notification.Builder(this)
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.ic_launcher_b3)
.setContentIntent(contentIntent).getNotification();
}
/**
* This is the method that can be called to update the Notification
*/
private void updateNotification() {
String text = "Some text that will update the notification";
Notification notification = getMyActivityNotification(text);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(NOTIF_ID, notification);
}
美国
要设置通知以便更新,请使用
通过调用NotificationManager.notify()
获得通知ID。更新
发出此通知后,请更新或创建
NotificationCompat.Builder
对象,从
然后,使用您以前使用的相同ID发出通知
。
如果以前的通知仍然可见,系统将更新它
从通知
对象的内容。如果以前的
通知已被取消,将创建一个新通知
相反
在android 8.0+中改进Luca Manzo answer,更新通知时会发出声音并显示为提示。
要防止出现这种情况,您需要添加setonlylertonce(true)
因此,代码是:
private static final int NOTIF_ID=1;
@Override
public void onCreate(){
this.startForeground();
}
private void startForeground(){
startForeground(NOTIF_ID,getMyActivityNotification(""));
}
private Notification getMyActivityNotification(String text){
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
((NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(
NotificationChannel("timer_notification","Timer Notification",NotificationManager.IMPORTANCE_HIGH))
}
// The PendingIntent to launch our activity if the user selects
// this notification
PendingIntent contentIntent=PendingIntent.getActivity(this,
0,new Intent(this,MyActivity.class),0);
return new NotificationCompat.Builder(this,"my_channel_01")
.setContentTitle("some title")
.setContentText(text)
.setOnlyAlertOnce(true) // so when data is updated don't make sound and alert in android 8.0+
.setOngoing(true)
.setSmallIcon(R.drawable.ic_launcher_b3)
.setContentIntent(contentIntent)
.build();
}
/**
* This is the method that can be called to update the Notification
*/
private void updateNotification(){
String text="Some text that will update the notification";
Notification notification=getMyActivityNotification(text);
NotificationManager mNotificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(NOTIF_ID,notification);
}
似乎没有一个现有的答案显示如何处理完整的案例-如果是第一次呼叫,则从startForeground开始,但更新后续呼叫的通知
您可以使用以下模式来检测正确的情况:
private void notify(@NonNull String action) {
boolean isForegroundNotificationVisible = false;
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
StatusBarNotification[] notifications = notificationManager.getActiveNotifications();
for (StatusBarNotification notification : notifications) {
if (notification.getId() == FOREGROUND_NOTE_ID) {
isForegroundNotificationVisible = true;
break;
}
}
Log.v(getClass().getSimpleName(), "Is foreground visible: " + isForegroundNotificationVisible);
if (isForegroundNotificationVisible){
notificationManager.notify(FOREGROUND_NOTE_ID, buildForegroundNotification(action));
} else {
startForeground(FOREGROUND_NOTE_ID, buildForegroundNotification(action));
}
}
此外,您还需要像其他答案中一样构建通知和通道:
private Notification buildForegroundNotification(@NonNull String action) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel();
}
//Do any customization you want here
String title;
if (ACTION_STOP.equals(action)) {
title = getString(R.string.fg_notitifcation_title_stopping);
} else {
title = getString(R.string.fg_notitifcation_title_starting);
}
//then build the notification
return new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setOngoing(true)
.build();
}
@RequiresApi(Build.VERSION_CODES.O)
private void createNotificationChannel(){
NotificationChannel chan = new NotificationChannel(CHANNEL_ID, getString(R.string.fg_notification_channel), NotificationManager.IMPORTANCE_DEFAULT);
chan.setLightColor(Color.RED);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
}
你能给我举个例子,说明我在活动中如何称呼它吗?我还没有找到一个关于如何在前台服务中调用方法的好例子。@Luke:有很多种使用服务的模式,我不知道你的下面是什么。如果要调用startService()
将命令传递给服务,则只需再次调用startService()
,告诉它更新其文本。或者,如果您正在调用bindService()
,请向API添加一个方法,让服务更新其文本。或者,考虑服务本身是否应该是决定是否更新文本的决策者。或者,该文本可能是服务具有侦听器的SharedReference
。抽象地给你提供准确的建议是不可能的。进一步澄清一下:你不能cancel()
由startForeground()
设置的通知。您必须删除服务本身的前台状态(使用stopfrogent()如果你想让记号文本再次出现。我失去了几个小时,因为这些答案使我相信它实际上是可能的。我已经否决了这个答案,因为它显然是错误的:请@大众SWARE考虑删除这个答案,因为你的高信誉分数使得这个答案是“神圣真理”。对于临时浏览器。谢谢。对我来说不起作用(尽管我记得在以前的项目中使用了相同的方法)。使用NotificationManager
的工作与我预期的一样。我不确定这是否会保持startService的前台状态。@Daniel Kao如果我错了,您的解决方案不会启动前台服务请更正我,但投票否决此答案的人能否更详细地说明问题所在?问题不在于如何启动启动前台服务,但如何更新前台服务的通知。这实际上与Luca的答案相同,人们都同意Luca可以工作并保持前台状态。@t它不工作。对于创建的前台
消息,通知的状态变为非前台
。这将导致重复重复通知,因为已调用startForeground()。这是正确的答案!上面的答案非常错误且具有误导性。您不需要为了更新愚蠢的通知而重新启动服务。@Radu,尽管我同意这是最佳答案(它避免了Commonware的答案所采用的稍长的代码路径)您对Commonware的答案的理解是错误的-启动/停止Foregound而不是启动/停止服务,它们只会影响服务的前瞻性。@Stevie谢谢您的回答Stevie您可能是对的。不过我也不会搞砸这一点!调用notify()
或startForeground()
都会导致调用onStartCommand()
。使用NotificationManager
更新用startForeground
显示的通知的问题是调用stopForeground
将不再删除通知。使用另一个调用startForeground
更新通知将避免该问题。缺少关键字,应该有new N