FCM - 在 onMessageReceived 中设置徽章
FCM - Setting badge in onMessageReceived
我有一个 Android 应用程序,我在其中使用某种方法在应用程序图标上显示通知编号。现在我想在收到通知时设置该号码。
我认为我应该在收到通知时设置号码,所以我在 onMessageReceived
方法中设置了它。但是,我的问题是 当我的应用程序处于后台时,onMessageReceived
方法没有被调用,所以通知号码没有设置。
以下是我的代码。我在 onMessageReceived
中设置了数字。我已经测试了 setBadge
方法并且可以验证它是否有效。问题是 onMessageReceived
没有被调用所以 setBadge
也没有被调用,这没有设置数字。
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO(developer): Handle FCM messages here.
Log.d(TAG, "From: " + remoteMessage.getFrom());
Conts.notificationCounter ++;
//I am setting in here.
setBadge(getApplicationContext(),Conts.notificationCounter );
Log.e("notificationNUmber",":"+ Conts.notificationCounter);
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
// [END receive_message]
public static void setBadge(Context context, int count) {
String launcherClassName = getLauncherClassName(context);
if (launcherClassName == null) {
Log.e("classname","null");
return;
}
Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
intent.putExtra("badge_count", count);
intent.putExtra("badge_count_package_name", context.getPackageName());
intent.putExtra("badge_count_class_name", launcherClassName);
context.sendBroadcast(intent);
}
public static String getLauncherClassName(Context context) {
PackageManager pm = context.getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
for (ResolveInfo resolveInfo : resolveInfos) {
String pkgName = resolveInfo.activityInfo.applicationInfo.packageName;
if (pkgName.equalsIgnoreCase(context.getPackageName())) {
String className = resolveInfo.activityInfo.name;
return className;
}
}
return null;
}
当我搜索这个 时,我发现如果即将到来的消息是 显示消息 那么 onMessageReceived
只有在应用程序处于前台时才会被调用。但是,如果即将到来的消息是 数据消息,那么即使应用程序在后台,也会调用 onMessageReceived
。
但是我的朋友告诉我谁在发送通知(服务器端),消息已经作为显示消息和数据消息发送。他说数据对象已填充
以下是 JSON 的来信,它有数据对象.
{
"to":"my_device_id",
"priority":"high",
"notification":{
"body":"Notification Body",
"title":"Notification Title",
"icon":"myicon",
"sound":"default"
},
"data":{
"Nick":"DataNick",
"Room":"DataRoom"
}
}
如果我只使用数据对象,onMessageReceived 会像他们所说的那样被调用,但那个时间通知不会出现在顶部。
现在如果消息也是数据消息,为什么不调用onMessageReceived
。我应该做些不同的事情来处理数据消息吗?它与客户端的显示消息一样工作吗?
如有任何帮助,我们将不胜感激。提前致谢。
无法调用 onMessageReceived 除非即将到来的 json 包含 ONLY 数据负载 正如我从 Firebase 支持中了解到的那样。
所以我必须使用数据负载,但如果您使用数据负载,它不会在顶部显示通知,因此您应该使用数据负载信息创建自定义通知。
因此,当我在 onMessageReceived 中获得数据负载 时,我 向自己发送了通知 。我在向自己发送通知后立即在 onMessageReceived 中设置徽章。
以下代码为最终版本。
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//for data payload
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
title = remoteMessage.getData().get("title");
sendNotification(remoteMessage.getData().get("body"), title);
badge = Integer.parseInt(remoteMessage.getData().get("badge"));
Log.e("notificationNUmber",":"+badge);
setBadge(getApplicationContext(), badge);
}
//for notification payload so I did not use here
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
// [END receive_message]
private void sendNotification(String messageBody, String title) {
Intent intent = new Intent(this, MainMenuActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, notify_no /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
if (notify_no < 9) {
notify_no = notify_no + 1;
} else {
notify_no = 0;
}
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher_3_web)
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notify_no + 2 /* ID of notification */, notificationBuilder.build());
}
谢谢大家。
要在后台接收通知负载时执行操作,只需覆盖 FirebaseMessagingService 中的 zzE。方法名称可能会因版本而异,只需在 class 中键入 @Override 并查看它对您的建议。在我的例子中,我找到了 zzD 和 zzE,通过试用它们我发现 zzE 有我想要的数据。 zzD 在它的附加功能中有一些唤醒锁的东西。 zzE 的 return 值基本上表示通知是否被处理,所以如果你 return 为真,OS 将不会显示通知。我更喜欢 return super.zzE(intent) 在我完成我的事情后,让 OS 处理通知。
不过,更新徽章仅适用于 ShortcutBadger 支持的启动器。不过,您几乎可以随心所欲地做任何事情。
这是我的代码(我的通知在数据负载中包含 "badge"):
public class PushNotificationService extends FirebaseMessagingService
{
@Override
public void onMessageReceived(RemoteMessage remoteMessage)
{
// This is called when the app is in the foreground
// Show a custom notification or send a broadcast to update the UI here
}
@Override
public boolean zzE(Intent intent)
{
if(intent.hasExtra("badge"))
{
try
{
ShortcutBadger.applyCount(getApplicationContext(), Integer.parseInt(intent.getStringExtra("badge"));
}
catch (Exception e)
{
Log.e("failedToParse", "Badge!?");
}
}
// pass the intent through to the non-overriden zzE
// to show the default notification.
return super.zzE(intent);
// You could also show a custom notification here
// and return true instead of this if you
// don't want the default notifications.
}
}
我有一个 Android 应用程序,我在其中使用某种方法在应用程序图标上显示通知编号。现在我想在收到通知时设置该号码。
我认为我应该在收到通知时设置号码,所以我在 onMessageReceived
方法中设置了它。但是,我的问题是 当我的应用程序处于后台时,onMessageReceived
方法没有被调用,所以通知号码没有设置。
以下是我的代码。我在 onMessageReceived
中设置了数字。我已经测试了 setBadge
方法并且可以验证它是否有效。问题是 onMessageReceived
没有被调用所以 setBadge
也没有被调用,这没有设置数字。
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO(developer): Handle FCM messages here.
Log.d(TAG, "From: " + remoteMessage.getFrom());
Conts.notificationCounter ++;
//I am setting in here.
setBadge(getApplicationContext(),Conts.notificationCounter );
Log.e("notificationNUmber",":"+ Conts.notificationCounter);
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
// [END receive_message]
public static void setBadge(Context context, int count) {
String launcherClassName = getLauncherClassName(context);
if (launcherClassName == null) {
Log.e("classname","null");
return;
}
Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
intent.putExtra("badge_count", count);
intent.putExtra("badge_count_package_name", context.getPackageName());
intent.putExtra("badge_count_class_name", launcherClassName);
context.sendBroadcast(intent);
}
public static String getLauncherClassName(Context context) {
PackageManager pm = context.getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
for (ResolveInfo resolveInfo : resolveInfos) {
String pkgName = resolveInfo.activityInfo.applicationInfo.packageName;
if (pkgName.equalsIgnoreCase(context.getPackageName())) {
String className = resolveInfo.activityInfo.name;
return className;
}
}
return null;
}
当我搜索这个 onMessageReceived
只有在应用程序处于前台时才会被调用。但是,如果即将到来的消息是 数据消息,那么即使应用程序在后台,也会调用 onMessageReceived
。
但是我的朋友告诉我谁在发送通知(服务器端),消息已经作为显示消息和数据消息发送。他说数据对象已填充
以下是 JSON 的来信,它有数据对象.
{
"to":"my_device_id",
"priority":"high",
"notification":{
"body":"Notification Body",
"title":"Notification Title",
"icon":"myicon",
"sound":"default"
},
"data":{
"Nick":"DataNick",
"Room":"DataRoom"
}
}
如果我只使用数据对象,onMessageReceived 会像他们所说的那样被调用,但那个时间通知不会出现在顶部。
现在如果消息也是数据消息,为什么不调用onMessageReceived
。我应该做些不同的事情来处理数据消息吗?它与客户端的显示消息一样工作吗?
如有任何帮助,我们将不胜感激。提前致谢。
无法调用 onMessageReceived 除非即将到来的 json 包含 ONLY 数据负载 正如我从 Firebase 支持中了解到的那样。
所以我必须使用数据负载,但如果您使用数据负载,它不会在顶部显示通知,因此您应该使用数据负载信息创建自定义通知。
因此,当我在 onMessageReceived 中获得数据负载 时,我 向自己发送了通知 。我在向自己发送通知后立即在 onMessageReceived 中设置徽章。
以下代码为最终版本。
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//for data payload
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
title = remoteMessage.getData().get("title");
sendNotification(remoteMessage.getData().get("body"), title);
badge = Integer.parseInt(remoteMessage.getData().get("badge"));
Log.e("notificationNUmber",":"+badge);
setBadge(getApplicationContext(), badge);
}
//for notification payload so I did not use here
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
// [END receive_message]
private void sendNotification(String messageBody, String title) {
Intent intent = new Intent(this, MainMenuActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, notify_no /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
if (notify_no < 9) {
notify_no = notify_no + 1;
} else {
notify_no = 0;
}
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher_3_web)
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notify_no + 2 /* ID of notification */, notificationBuilder.build());
}
谢谢大家。
要在后台接收通知负载时执行操作,只需覆盖 FirebaseMessagingService 中的 zzE。方法名称可能会因版本而异,只需在 class 中键入 @Override 并查看它对您的建议。在我的例子中,我找到了 zzD 和 zzE,通过试用它们我发现 zzE 有我想要的数据。 zzD 在它的附加功能中有一些唤醒锁的东西。 zzE 的 return 值基本上表示通知是否被处理,所以如果你 return 为真,OS 将不会显示通知。我更喜欢 return super.zzE(intent) 在我完成我的事情后,让 OS 处理通知。
不过,更新徽章仅适用于 ShortcutBadger 支持的启动器。不过,您几乎可以随心所欲地做任何事情。
这是我的代码(我的通知在数据负载中包含 "badge"):
public class PushNotificationService extends FirebaseMessagingService
{
@Override
public void onMessageReceived(RemoteMessage remoteMessage)
{
// This is called when the app is in the foreground
// Show a custom notification or send a broadcast to update the UI here
}
@Override
public boolean zzE(Intent intent)
{
if(intent.hasExtra("badge"))
{
try
{
ShortcutBadger.applyCount(getApplicationContext(), Integer.parseInt(intent.getStringExtra("badge"));
}
catch (Exception e)
{
Log.e("failedToParse", "Badge!?");
}
}
// pass the intent through to the non-overriden zzE
// to show the default notification.
return super.zzE(intent);
// You could also show a custom notification here
// and return true instead of this if you
// don't want the default notifications.
}
}