当应用程序处于前台时需要关闭点击通知 - android
Posted
技术标签:
【中文标题】当应用程序处于前台时需要关闭点击通知 - android【英文标题】:Need to dismiss the notification on tap when App is in foreground - android 【发布时间】:2019-11-02 21:09:46 【问题描述】:我正在用我的应用测试推送通知。
当App在前台时:
Step 1. Received the notification (in system tray).
2. now, I'm in some other screen than the home screen.
3. Actual Problem: On tap on the notification, it is going to the home screen.
4. Expected: If the app is in the foreground, just I need to cancel on tap of the notification. (No need to swipe.)
当应用程序在后台/被杀死时:(运行良好)
Step 1. Received the notification (in the system tray)
2. On tap, open the home screen of the app.
尝试在意图中设置启动模式标志。没有帮助。下面是我的代码。请各位大侠提出解决方案。
Intent resultIntent = new Intent(this, MainActivity.class);
//resultIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// resultIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this);
mBuilder.setContentIntent(resultPendingIntent);
mBuilder.setSmallIcon(R.mipmap.ic_launcher);
mBuilder.setContentTitle(title);
mBuilder.setContentText(body);
mBuilder.setAutoCancel(true);
mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(body));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
mBuilder.setChannelId(TestUtils.creatChanel(this).getId());
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(642, mBuilder.build());
【问题讨论】:
您想一直取消通知吗?应用在前台时取消的目的是什么? 没有。我不想总是取消通知。通知的目的不应影响应用导航。如果我在屏幕 3 中并且我点击通知,它现在会将我带到主屏幕。 如果导航不应该影响应用导航,那么您必须在应用中取消所有通知。 【参考方案1】:不确定点击时关闭通知,但因为您担心导航错误。
我们可以检查应用是否在前台,如果应用在前台,我们可以防止点击通知打开新的活动。
//If app is in foreground setting pending intent to null
PendingIntent pendingIntent;
Intent notificationIntent = new Intent(getApplicationContext(), Main2Activity.class);
if(isAppInForeground())
Log.e("--^","inForeground");
pendingIntent = null;
else
Log.e("--^","inBackground");
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
添加此功能(来源:link)
private boolean isAppInForeground()
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> services = activityManager.getRunningAppProcesses();
boolean isActivityFound = false;
if (services.get(0).processName
.equalsIgnoreCase(getPackageName()) && services.get(0).importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
isActivityFound = true;
return isActivityFound;
在这种情况下,如果应用程序在前台时收到通知,则单击它不会执行任何操作。所以用户只有一个选项可以滑动删除。
【讨论】:
这行不通。根据@Samp 功能,如果您在前台并且收到通知,然后如果您关闭应用程序然后点击该通知,则不会发生任何事情。由于未决意图为空,它不会打开应用程序。 @Nik yes..在那种情况下,我们需要找到其他解决方案。谢谢 @Nik 是的。你是对的。此解决方案将影响背景灵魂。 (At)Naitik 感谢您试用 有什么办法可以用我通过的意图设置标志吗? 是的,使用 RemoteView 将按钮放在通知上是击球手的想法。【参考方案2】:您可以使用关闭按钮创建自定义通知以使用 RemoteViews 关闭通知
// 使用 RemoteViews 创建通知:
RemoteViews remoteViews= new RemoteViews(getApplicationContext().getPackageName(), R.layout.your_custom_notification);
Intent closeIntent = new Intent(context, CloseNotificationService.class);
hangUpIntent.setAction("close");
PendingIntent pendingCloseIntent = PendingIntent.getBroadcast(this, 0, closeNotification, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.cancel_notification, pendingCloseIntent);
// create notification here..
Notification customNotification = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
.setCustomContentView(remoteViews)
.build();
关闭按钮的 OnClick 将重定向到服务类:
public class CloseNotificationService extends IntentService
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*/
public CloseNotificationService()
super("notificationIntentService");
@Override
protected void onHandleIntent(@Nullable Intent intent)
switch (intent.getAction())
case "close":
Handler hangUpHandler = new Handler(Looper.getMainLooper());
hangUpHandler.post(new Runnable()
@Override
public void run()
NotificationManager notifManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notifManager.cancel(notificationId); // get notification id from intent.
);
break;
RemoteViews的更多信息可以参考谷歌官方开发者网站https://developer.android.com/training/notify-user/custom-notification
【讨论】:
【参考方案3】:而不是这个:
Intent resultIntent = new Intent(this, MainActivity.class);
这样做:
Intent resultIntent = getPackageManager().getLaunchIntentForPackage("your.package.name");
并将其放入您的Notification
。如果应用程序尚未运行,这将启动应用程序,否则它只会将应用程序的任务以用户上次使用它时的任何状态带到前台。如果用户已经在应用程序中(即:在另一个屏幕上),当用户单击Notification
时,这将不会执行任何操作。
应该正是您正在寻找的。p>
【讨论】:
@David:刚刚试过。在空对象引用上获取 NullpointerException 'boolean android.content.Intent.migrateExtraStreamToClipData()'。我只是按照你的建议做了。对此有什么想法吗? 这个错误不可能是由于我建议的更改。查看堆栈跟踪以了解该错误来自何处 @大卫:其实在那之后我没有尝试过。当应用程序处于前台时,通过传递空意图来实现相同的功能。按照我的要求工作。 致命异常:Firebase-MyFirebaseMessagingService java.lang.NullPointerException:尝试在 android.app.PendingIntent.getActivity 的空对象引用上调用虚拟方法“boolean android.content.Intent.migrateExtraStreamToClipData()” (PendingIntent.java:346) 在 android.app.PendingIntent.getActivity(PendingIntent.java:309) 在 my.pkg.MyFirebaseMessagingService.sendNotification(MyFirebaseMessagingService.java:101)。 101中的行是: Intent resultIntent = getPackageManager().getLaunchIntentForPackage("my.package"); contentIntent = PendingIntent.getActivity(this, INAPP_MESSAGE_REQUEST_ID, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);【参考方案4】:在您的启动器活动中,您是否尝试过通知管理器类 cancelAll() 方法?? 这样,如果启动时已经有通知,则会自动取消
【讨论】:
我需要取消点击通知。所以你提到的方式行不通:(以上是关于当应用程序处于前台时需要关闭点击通知 - android的主要内容,如果未能解决你的问题,请参考以下文章