FCM - 在onMessageReceived中设置徽章 [英] FCM - Setting badge in onMessageReceived

查看:184
本文介绍了FCM - 在onMessageReceived中设置徽章的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Android应用程序,我正在使用某种方法在应用程序图标上显示通知号码。



我认为我应该在收到通知时设置数字,所以我将它设置在 onMessageReceived 方法。但是,我的问题是当我的应用程序处于后台时,未调用 onMessageReceived 方法,因此未设置通知编号。



以下是我的代码。我在 onMessageReceived 中设置了数字。我已经测试过 setBadge 方法,并且可以验证它是否正在工作。问题是 onMessageReceived 没有被调用,所以 setBadge 也没有被调用,它不会设置数字。 p>

  @Override 
public void onMessageReceived(RemoteMessage remoteMessage){

// TODO(developer) :在这里处理FCM消息。
Log.d(TAG,From:+ remoteMessage.getFrom());
Conts.notificationCounter ++;
//我在这里设置。
setBadge(getApplicationContext(),Conts.notificationCounter);
Log.e(notificationNUmber,:+ Conts.notificationCounter);

//检查消息是否包含数据有效载荷。
if(remoteMessage.getData()。size()> 0){
Log.d(TAG,Message data payload:+ remoteMessage.getData());
}

//检查消息是否包含通知负载。
if(remoteMessage.getNotification()!= null){
Log.d(TAG,Message Notification Body:+ remoteMessage.getNotification()。getBody());
}

//同样,如果您打算根据收到的FCM
//消息生成您自己的通知,那么这里是应该启动的地方。请参阅下面的sendNotification方法。
}
// [END receive_message]



public static void setBadge(Context context,int count){
String launcherClassName = getLauncherClassName(上下文);
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;
}
}
返回null;
}

当我搜索这个 issue ,我发现如果接下来的消息是 display message 那么仅当应用程序为前景时才调用 onMessageReceived 。但是如果接收到消息是数据消息,那么即使应用程序是后台,也会调用 onMessageReceived



但是我的朋友告诉我谁在发送通知(服务器端),该消息已经作为显示和数据消息发送。他表示数据对象已填充。



以下是即将发布消息 JSON ,它具有数据对象



  {
to:my_device_id,
priority :高,

通知:{
body:Notification Body,
title:通知标题,
icon:myicon,
sound:default
},

data:{
Nick:DataNick,
房间:DataRoom
}
}

如果我只使用数据对象,onMessageReceived被调用,因为他们说,但时间通知不会出现在顶部。



现在为什么 onMessageReceived 。我应该做一些不同的事情来处理数据信息吗?它是否与客户端显示消息一致?



任何帮助将不胜感激。

解决方案

没有办法调用 onMessageReceived ,除非未来的json包含 ONLY所以我必须使用数据有效载荷,但是如果您使用数据有效载荷,它不会显示通知 / strong>,因此您应该使用数据有效负载信息来创建您的自定义通知。因此,我向我自己发送通知 onMessageReceived 中的数据有效内容。在发送通知给我自己后,我在onMessageReceived中设置了徽章。



以下代码是最终版本。

  @Override 
public void onMessageReceived(RemoteMessage remoteMessage){
//用于数据有效载荷
//检查消息是否包含数据有效载荷。
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);

}
//用于通知负载,所以我没有在这里使用
//检查消息是否包含通知负载。
if(remoteMessage.getNotification()!= null){

Log.d(TAG,Message Notification Body:+ remoteMessage.getNotification()。getBody());

}

//同样,如果您打算通过接收到的FCM
//消息生成您自己的通知,那么这里是应该启动的地方。请参阅下面的sendNotification方法。
}
// [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 / *请求代码* /,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 * /,notificationBuilder.build());
}

感谢所有人。


I have an Android application, where I'm using some method to show notification number on app icon. Now I want to set that number when notification is received.

I thought that I should set the number when notification received so I set it inside onMessageReceived method. But, my problem is when my app is in background, onMessageReceived method not called, so the notification number isn't set.

Following is my code. I set the number inside onMessageReceived. I already tested setBadge method and can verify that it is working. The problem is onMessageReceived is not called so setBadge is also not called, which doesn't set the number.

@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;
}

When I searched this issue, I found that if the coming message is display message then onMessageReceived is called only if app is foreground. But if coming message is data message then onMessageReceived is called even if the app is background.

But my friend told me who is sending the notification(server side), the message already goes as both display and data message. He said that data object is filled.

Following is the JSON for coming message, it has data object.

{  
   "to":"my_device_id",
   "priority":"high",

   "notification":{  
      "body":"Notification Body",
      "title":"Notification Title",
      "icon":"myicon",
      "sound":"default"
   },

   "data":{  
      "Nick":"DataNick",
      "Room":"DataRoom"
   }
}

If I only use data object, onMessageReceived is called as they said but that time notification does not appear at the top.

Now why onMessageReceived is not called if the message is also data message. Should I do something different to handle data message? Is it working same with display messaging in client side.

Any help would be appreciated. Thanks in advance.

解决方案

No way to call onMessageReceived unless the coming json includes ONLY data payload as I learned from Firebase support.

So I have to use data payload but if you use data payload it does not show notification at the top so you should create your custom notification using data payload information.

So I sent notification to myself when I get the data payload in onMessageReceived. And I set the badge in onMessageReceived right after sending notification to myself.

Following code is the final version.

@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());
}

Thanks for all.

这篇关于FCM - 在onMessageReceived中设置徽章的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆