本教程旨在指导开发者如何在android应用中,根据用户当前所处的特定activity状态,动态地控制firebase推送通知的显示。通过引入一个全局静态标志,结合activity的生命周期方法,我们可以在用户处于指定界面时,有效阻止不必要的通知弹窗,从而优化用户体验。
在开发诸如聊天应用等实时通信的Android应用时,一个常见的需求是当用户正处于某个特定界面(例如,正在查看某个聊天室的对话)时,避免重复显示来自该聊天室的新消息推送通知。虽然系统级的通知管理允许用户手动关闭通知,但为了提供更流畅的用户体验,我们希望应用能够智能地判断当前上下文,自动抑制不必要的通知弹窗。本教程将详细介绍一种简单而有效的方法来实现这一功能。
实现此功能的核心思想是利用一个全局可访问的静态变量作为状态标志。当用户进入我们不希望显示通知的特定Activity时,我们将该标志设置为禁用通知;当用户离开该Activity时,再将标志重置为允许通知。FirebaseMessagingService在接收到消息时,只需检查这个标志的状态,即可决定是否构建并显示通知。
以下是实现动态控制推送通知显示功能的具体步骤:
首先,创建一个简单的Java类,其中包含一个静态的布尔变量,用于表示是否应该显示通知。
public class NotificationHelper {
public static boolean shouldShowNotification = true;
}在这个类中,shouldShowNotification 变量的默认值为 true,表示在没有特殊指令的情况下,通知是允许显示的。
接下来,在您不希望显示通知的特定Activity中(例如,聊天界面),您需要覆盖 onResume() 和 onPause() 生命周期方法,以根据Activity的可见性来更新 shouldShowNotification 标志。
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class ChatActivity extends AppCompatActivity { // 假设这是您的聊天界面Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置您的布局
// setContentView(R.layout.activity_chat);
}
@Override
protected void onResume() {
super.onResume();
// 当Activity可见并处于前台时,禁用通知显示
NotificationHelper.shouldShowNotification = false;
}
@Override
protected void onPause() {
super.onPause();
// 当Activity不再处于前台时,重新启用通知显示
// 这确保了当用户离开聊天界面后,其他消息通知能够正常弹出
NotificationHelper.shouldShowNotification = true;
}
}最后,修改您的 MyFirebaseMessagingService 类中的 onMessageReceived() 方法,在构建和显示通知之前,添加一个条件判断来检查 NotificationHelper.shouldShowNotification 的状态。
import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Intent; import android.os.Build; import android.provider.Settings; import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; import java.util.Objects; public class MyFirebaseMessagingService extends FirebaseMessagingService { @Override public void onMessageReceived(@NonNull RemoteMessage message) { super.onMessageReceived(message); // 核心:在显示通知前检查全局标志 if (NotificationHelper.shouldShowNotification) { int requestID = (int) System.currentTimeMillis(); String title = message.getNotification().getTitle(); String body = message.getNotification().getBody(); String click_action = message.getNotification().getClickAction(); NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), "Notification"); builder.setContentTitle(title); builder.setContentText(body); builder.setSound(Settings.System.DEFAULT_NOTIFICATION_URI); builder.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000}); // 确保R.color.chitchat存在于您的项目中 // builder.setLights(getResources().getColor(R.color.chitchat), 3000, 3000); builder.setSmallIcon(R.drawable.logowhite); // 确保R.drawable.logowhite存在 Intent intent = null; if (Objects.requireNonNull(message.getData().get("type")).equalsIgnoreCase("privatechat")) { intent = new Intent(click_action); // 确保您的click_action与Manifest中的Activity intent-filter匹配 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.putExtra("GCKey", message.getData().get("GCKey")); intent.putExtra("GCNameKey", message.getData().get("GCNameKey")); } // 确保 intent 不为 null,否则 PendingIntent 会抛出异常 if (intent == null) { // 如果没有匹配的type,可以创建一个默认的intent,或者直接返回不显示通知 intent = new Intent(this, MainActivity.class); // 示例:跳转到主Activity intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); } PendingIntent pendingIntent = PendingIntent.getActivity(this, requestID, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); builder.setAutoCancel(true); builder.setContentIntent(pendingIntent); NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel("Notification", "Default channel", NotificationManager.IMPORTANCE_DEFAULT); notificationManager.createNotificationChannel(channel); } notificationManager.notify(69, builder.build()); } } }
通过将所有的通知构建和显示逻辑包裹在 if (NotificationHelper.shouldShowNotification) 条件判断中,我们实现了在特定Activity活跃时,完全跳过通知的显示过程。
通过引入一个简单的静态布尔标志,并结合Android Activity的生命周期管理,我们能够有效地在用户处于特定应用界面时,动态地控制Firebase推送通知的显示。这种方法简单、直接且易于实现,极大地提升了用户在使用应用时的体验,避免了不必要的打扰。在实际开发中,根据项目的复杂度和具体需求,可以进一步扩展和优化此方案。