我有一个SharedPreference:sharedPref.getBoolean("online", false)
如果我在online
为false时收到通知,我想阻止它。通常情况下,如果用户离线,不会有通知,但偶尔我会收到一个通知,我希望将其作为备份以阻止通知。
通知是通过Firebase Cloud Messaging(FCM(发送的,以下是我的应用程序中的处理方式:
class CustomApplication : Application() {
val MATCH_CHANNEL_ID = "MATCH_CHANNEL"
companion object {
var database: AppDatabase? = null
}
override fun onCreate() {
super.onCreate()
val settings: FirebaseFirestoreSettings = FirebaseFirestoreSettings.Builder().setPersistenceEnabled(false).build()
FirebaseFirestore.getInstance().firestoreSettings = settings
CustomApplication.database = Room.databaseBuilder(this, AppDatabase::class.java, "AppDatabase").build()
createNotificationChannel()
}
private fun createNotificationChannel(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
val matchChannel = NotificationChannel(MATCH_CHANNEL_ID, "Nearby matches", NotificationManager.IMPORTANCE_HIGH)
matchChannel.description = "Nearby matches"
val manager: NotificationManager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(matchChannel)
}
}
}
如果SharedPreferences中的online
为false,我有什么方法可以阻止通知进入吗?
编辑:
当我在后台收到通知FCM时,它会调用。FirebaseMessagingService.onCreate()
:
class CustomFirebaseMessagingService : FirebaseMessagingService() {
val db = FirebaseFirestore.getInstance()
override fun onCreate() {
Log.d(TAG, "CustomFirebaseMessagingService onCreate()")
return
super.onCreate()
}
我已经覆盖了onCreate()
以在super.onCreate()
之前返回,希望取消通知。然而,通知仍然会触发。
CustomFirebaseMessagingService()
中是否有另一个我可以覆盖的功能来拦截通知并取消它?
如果我正确理解了你的问题,那么你说的是当你的应用程序不运行时收到推送消息时的情况。您已经提到,只有当您的应用程序处于运行状态时才会调用onMessageReceived()
,但即使系统没有调用此方法,也会显示您的通知。因此,我们可以得出结论,这些通知是由系统自动绘制的。此行为由FCM消息正文中的"通知"one_answers"数据"部分控制。
FCM消息有一个复杂的规范,可以在这里找到。但由于我们只对"通知"one_answers"数据"部分感兴趣,我们可以依赖它们的行为:
第一种情况-同时存在"通知"one_answers"数据"部分
示例:
{
"message":{
"notification": { /*...*/ },
"data": {/*...*/}
}
}
在这种情况下,如果你的应用程序处于后台状态,
- 系统将自动显示通知
- 如果单击此通知,将启动一项活动
- 活动意图将包含"数据"主体和有关FCM消息的一些技术信息
第二种情况-仅存在"通知"部分
示例:
{
"message":{
"notification": { /*...*/ },
}
}
在这种情况下,如果你的应用程序处于后台状态,
- 系统将自动显示通知
- 如果单击此通知,将启动一项活动
- 活动意图仅包含有关FCM消息的技术信息
第三种情况-仅存在"数据"部分
示例:
{
"message":{
"data": {/*...*/}
}
}
在这种情况下,如果你的应用程序处于后台状态,
- 系统不会自动显示通知
- 将调用
onMessageReceived()
因此,在查看了这些信息后,您可以尝试更改FCM消息的正文(即丢弃"通知"部分(,以禁止系统自行处理提取通知。
每次都由onMessageReceived()
处理您的消息,您可以将带有该标志的逻辑放在那里。
查看您的清单文件,将会有类似的服务
<service
android:name=".java.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
然后转到MyFirebaseMessagingService.java
文件,检查您的共享首选项值,并设置通知条件。试试这个。。
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
boolean flag = sharedPref.getBoolean("online", false);
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
if(flag){
//TODO write your code here to set notification and notify
}
}
}
<service
android:name=".fcm.FCMService"
android:enabled="true"
android:exported="false"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
没有很好的记录,但将其设置为false将使服务保持活力,即使应用程序处于后台或已停止https://developer.android.com/reference/android/R.attr.html#stopWithTask
通过这种方式,你可以按照之前海报的建议,在收到消息时处理阻塞
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, Constants.NOTIFICATION_CHANNEL_QA_ID)
.setSmallIcon(R.drawable.icon_notif)
.setColor(getResources().getColor(R.color.primary))
.setContentTitle(title)
.setContentText(text)
.setAutoCancel(true)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(text)
);
Intent intent = new Intent(getApplicationContext(), LauncherActivty.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
//use the bundled url if it is there and we have more then 1 notification for this type
if(amount > 1 && !bundledURL.equals("")){
intent.putExtra("url", bundledURL);
}else{
intent.putExtra("url", url);
}
intent.putExtra("notification_group", notificationGroup);
intent.putExtra("notification_group_id", notificationGroupID);
intent.putExtra("notification_id", notificationID);
intent.putExtra("is_group", isGroup);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationGroup, Constants.NOTIFICATION_ID, notificationBuilder.build());