英文:
Canceling Notififcations Android Java
问题
我开始使用通知,并且为了改善用户体验,我在通知中添加了一个名为“标记为已读”的按钮,因此当按下按钮时,消息将会被隐藏。
我遇到了一些问题,在数据库中,每条消息都有一个名为“read”的布尔字段,在“onDataChange()”方法中,我循环遍历并检查是否有任何消息的该字段为false,如果是,则调用“makeNotification()”,看起来没问题,问题出在哪里?举个例子,我有2条通知,我取消了其中一条(应用程序访问数据库并将字段更改为true,因此现在会调用“onDataChange()”),但另一条没有被取消,因为“onDataChange()”被调用,现在同样的通知出现了两次.....
我试图通过构建已读且已显示消息的数组来解决这个问题,我认为这不是最好的解决方案,但即使之前的问题在某种程度上得到了解决,这个问题还是有点奇怪。当通知出现在通知列表中时,它有一个名为“标记为已读”的按钮,当我按下它时,通知会被隐藏,但前提是我必须从最高的开始往较低的方向按,所以如果我先按下第二条通知,然后再按下第一条,如果我按下第三条通知,然后再按下第一条,通知会隐藏...
在“onCreate()”方法中,计数器设置为1;
public void makeNotification() {
Intent activityIntent = new Intent(this, Notifications.class);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, activityIntent, 0);
Intent broadcastIntent = new Intent(getApplicationContext(), NotifUpdater.class);
broadcastIntent.putExtra("seconds", message.getSeconds());
broadcastIntent.putExtra("id", String.valueOf(counter));
PendingIntent actionIntent = PendingIntent.getBroadcast(this, 0,
broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this, App.CHANNEL_ID)
.setVibrate(new long[]{100, 0, 100})
.setSmallIcon(R.drawable.ic_shield)
.setContentTitle(message.getTime() + " | " + message.getClient())
.setContentText(message.getMessage())
.setContentIntent(contentIntent)
.setAutoCancel(true)
.setOnlyAlertOnce(true)
.addAction(0, "MARK AS READ", actionIntent)
.build();
notificationManager.notify(counter, notification);
counter += 1;
}
// 由按钮触发的广播
public class NotifUpdater extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
FirebaseDatabase database = FirebaseDatabase.getInstance();
String seconds = intent.getStringExtra("seconds");
int id = Integer.parseInt(intent.getStringExtra("id"));
database.getReference("latest").child(seconds).child("read").setValue(true);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(id);
}
}
英文:
I started working with Notifications and to improve user expirirence I added button to notification "MARK AS READ", so when it is pressed - message will hide;
I had a few problems, in database each message has "read" field which is boolean, in method onDataChange() I loop and check if any of messages have this field as false if they have I call makeNotification(), looks fine, where is problem??? - e.x. I have 2 notifications, I cancel one(the app goes to database and change field to true, so now onDataChange() will be called), but another isn't cancelled and because onDataChange() was called now I have same notification appeared twice.....
I tried to fix this by building array of messages that are read and already displayed, not the best solution I think, but even previous problem was somehow solved this is a wierd one.
When notitifcation appears in notification list it has button "MARK AS READ", when I press it notififcation hides, but only if I start from the highest to the lower ones, so if I press second notification first foldes, if I press third first folds..
In onCreate() counter is set to 1;
public void makeNotification()
{
Intent activityIntent = new Intent(this, Notifications.class);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, activityIntent, 0);
Intent broadcastIntent = new Intent(getApplicationContext(), NotifUpdater.class);
broadcastIntent.putExtra("seconds", message.getSeconds());
broadcastIntent.putExtra("id", String.valueOf(counter));
PendingIntent actionIntent = PendingIntent.getBroadcast(this, 0,
broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this, App.CHANNEL_ID)
.setVibrate(new long[]{100, 0, 100})
.setSmallIcon(R.drawable.ic_shield)
.setContentTitle(message.getTime() + " | " + message.getClient())
.setContentText(message.getMessage())
.setContentIntent(contentIntent)
.setAutoCancel(true)
.setOnlyAlertOnce(true)
.addAction(0, "MARK AS READ", actionIntent)
.build();
notificationManager.notify(counter, notification);
counter += 1;
}
// Broadcast which is triggered by pressing button
public class NotifUpdater extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
FirebaseDatabase database = FirebaseDatabase.getInstance();
String seconds = intent.getStringExtra("seconds");
int id = Integer.parseInt(intent.getStringExtra("id"));
database.getReference("latest").child(seconds).child("read").setValue(true);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
notificationManager.cancel(id);
}
}
答案1
得分: 0
关于您提出的第一个问题,我会为每个通知设置一个指示器,“wasShown”或类似的内容,该指示器仅在您显示通知后设置为true,每当您迭代通知时,只显示那些“wasShown”设置为false的通知。
关于您的第二个问题,我对FirebaseDatabase不太熟悉,但听起来像是一个ID问题。您确定从意图中获取的ID是正确的吗?
英文:
Regarding your first issue, I'd just set an indicator for each notification, "wasShown" or something of the sort that is only set to true once you have showed the notification and when ever you are iterating your notifications, only show those who has "wasShown" set to false.
Regarding your 2nd problem, I'm not familiar with FirebaseDatabase but it sounds like its an ID problem. Did you make sure the ID you are getting from the intent is the right one?
答案2
得分: 0
你应该使用:FLAG_CANCEL_CURRENT
就像这样:
PendingIntent actionIntent = PendingIntent.getBroadcast(this, NOTIFICATION_ID, buttonIntent, PendingIntent.FLAG_CANCEL_CURRENT);
而不是使用 FLAG_UPDATE_CURRENT
。
英文:
You should have : FLAG_CANCEL_CURRENT
like :
PendingIntent actionIntent = PendingIntent.getBroadcast(this, NOTIFICATION_ID, buttonIntent, PendingIntent.FLAG_CANCEL_CURRENT);
not FLAG_UPDATE_CURRENT
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论