如果推送通知包含特定元素,如何隐藏它?

13

如果接收到的推送通知含有例如关键字update,我不会在用户的通知菜单中显示。目前,如果我收到此关键字的通知,所有的通知都会显示在通知栏中。我希望不向用户展示这些通知。

我正在使用WakefulBroadcastReceiver来处理通知,如下所示:

public class PusherReceiver extends WakefulBroadcastReceiver {
    private boolean isAppOnForeground(Context context) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
        if (appProcesses == null) 
            return false;

        final String packageName = context.getPackageName();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
                return true;
            }
        }

        return false;
    }

    public void onReceive(final Context context, Intent intent) {
        Log.i("SimpleWakefulReceiver", "Starting service @ " + SystemClock.elapsedRealtime());
        if (!isAppOnForeground((context))) {
            String pushNotificationBody = intent.getStringExtra("alert");

            try {
                JSONObject notificationData = new JSONObject(pushNotificationBody);

                // This is the Intent to deliver to our service.
                Intent service = new Intent(context, BackgroundService.class);
                // Put here your data from the json as extra in in the intent
                service.putExtra("notification", pushNotificationBody);

                Log.i("PUSH_NOTIFICATION_JSON", "RECEIVED JSON " + notificationData);

                // Start the service, keeping the device awake while it is launching.
                if (!notificationData.has("update")) {
                    startWakefulService(context, service);
                } else {
                    // Do nothing
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
}

更新:

我对项目进行了一些更改,使用了Onesignal和他的NotificationExtenderService,我做了类似下面这样的事情:

public class NotificationNotDisplayingExtender extends NotificationExtenderService {
    @Override
    protected boolean onNotificationProcessing(OSNotificationReceivedResult receivedResult) {
        String notification = receivedResult.toString();
        String notificationBody = receivedResult.payload.body;
        JSONObject notificationBodyJSON = null;
        try {
            notificationBodyJSON = new JSONObject(notificationBody);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        JSONObject pushNotificationData = notificationBodyJSON;
        boolean hidden = false;

        if (pushNotificationData.has("update")) {
            Log.i("NOTIFICATION MANAGER", "PREVENT DISPLAY NOTIFICATION");

            hidden = true;
        }


        // Return true to stop the notification from displaying.
        return hidden;
    }
}

它阻止使用更新键显示通知,但现在我没有收到它在我的 PusherReceiver 中启动服务。有没有简单的方法将数据从我的 NotificationNotDisplayingExtender receivedResult 发送到我的 PusherReceiver?

目前看来,我的 PusherReceiver 没有触发他的 onReceive 方法。

非常感谢提前帮助。


你应该注意到,自 API 26 起已弃用此内容:https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html - user1209216
@user1209216 是的,我知道,对于更新的API,我会进行更新,但现在我需要找到通知的解决方案。 :/ - Robson
2
如果我理解你的问题正确,你只需要停止调用NotificationManager来停止显示通知。通知只会在构建它们并调用notify时显示。只需使用您的服务处理数据而不构建通知即可。 - emirua
4个回答

2

如果在实施过程中遇到任何问题,请告诉我。 - KKSINGLA

1
事情基本上是我们有两种类型的通知。
一种可以称为通知类型,即推送在发送/接收包中具有notification对象,在其中您必须在应用程序在前台且接收到通知时处理它。在这种情况下,如果您的应用程序在前台,则可以处理它并执行任何您喜欢的操作,而不显示通知。但是,如果应用程序在后台,则谷歌将自动创建通知,并使用接收到的推送包中的预定义titlemessage对象来生成通知。
第二种类型可以称为数据类型,在发送/接收包中没有任何notification对象。在这种情况下,无论您的应用程序是在前台还是在后台,都应该处理所有内容。因此,如果您将数据放入推送通知消息的data对象中,则一切都将掌握在您手中。
简而言之,只需将数据放入推送通知的data对象中,并实现所需的逻辑即可。

1
我没有看到你提到的JSON数据。然而,我猜测你的JSON中的update键包含null。在你的代码中,你正在检查JSON数据是否有update键。如果这个键存在于JSON主体中,这个函数将始终返回true。你可能有一个带有null值的字段,这表明你不应该在系统托盘中显示通知。
在这种情况下,你可以考虑使用isNull函数。如果这个对象没有update的映射或者它有一个映射的值是null,它将返回true。
// Start the service, keeping the device awake while it is launching.
if (!notificationData.isNull("update")) {
    startWakefulService(context, service);
} else {
    // Do nothing
}

是的,请使用您收到的通知中的数据有效负载。


嗯,它防止了运行唤醒服务,但通知仍然显示。重要的是,这个问题只存在于应用程序处于后台/关闭状态时。 - Robson

0
每次您使用NotificationManager显示通知时,都会提供一个ID以便稍后编辑或取消该通知。如果您使用manager.notify(notificationId, notification)显示通知,则可以使用manager.cancel(notificationId)取消它。
如果您想要删除所有通知,可以使用NotificationManager.cancelAll()

感谢您的建议,Adib。取消通知确实有效,但当用户收到带有振动的通知后立即被取消时,看起来很奇怪。我更新了我的问题,希望只剩下一个问题了。 - Robson
1
据我所知,您已经解决了之前的问题,现在您有一个未被调用的“BroadcastReceiver”,并且您想要调用它?如果是这种情况,您可以像这样调用广播接收器: Intent intent = new Intent("my.action.string"); context.sendBroadcast(intent);. 您需要根据所需的接收器更改意图操作。 - Adib Faramarzi
我是通过发送广播来实现的,关于您的建议,如果通知具有NotificationNotDisplayingExtender中的更新键,则创建了一个意图并执行了以下操作:Intent intent = new Intent(); 我设置了与清单文件中设置的意图相同的操作intent.setAction("MY_NOTIFICATION"); 然后我向我的意图添加了数据并发送了广播intent.putExtra("data", notificationBody); sendBroadcast(intent); 谢谢,它有效! :) - Robson
@Robson 这是实现的方法,首先创建通知,然后再将其删除。 - KKSINGLA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接