it-roy-ru.com

Значок уведомления с новой системой Firebase Cloud Messaging

Вчера Google представил в Google I/O новую систему уведомлений, основанную на новой Firebase. Я попробовал этот новый FCM (Firebase Cloud Messaging) с примером на Github.

Значок уведомления всегда является ic_launcher , несмотря на то, что я объявил конкретный объект рисования

Зачем ? Здесь ниже официальный код для обработки сообщения

public class AppFirebaseMessagingService extends FirebaseMessagingService {

    /**
     * Called when message is received.
     *
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    // [START receive_message]
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // If the application is in the foreground handle both data and notification messages here.
        // 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.
        sendNotification(remoteMessage);
    }
    // [END receive_message]

    /**
     * Create and show a simple notification containing the received FCM message.
     *
     * @param remoteMessage FCM RemoteMessage received.
     */
    private void sendNotification(RemoteMessage remoteMessage) {

        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

// this is a my insertion looking for a solution
        int icon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop ? R.drawable.myicon: R.mipmap.myicon;
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(icon)
                .setContentTitle(remoteMessage.getFrom())
                .setContentText(remoteMessage.getNotification().getBody())
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }

}
107
marco

К сожалению, это было ограничением Firebase Notifications в SDK 9.0.0-9.6.1. Когда приложение находится в фоновом режиме, значок запуска запускается из манифеста (с тонировкой Android) для сообщений, отправляемых с консоли.

Однако в SDK 9.8.0 вы можете переопределить значение по умолчанию! В вашем AndroidManifest.xml вы можете установить следующие поля для настройки значка и цвета:

<meta-data
        Android:name="com.google.firebase.messaging.default_notification_icon"
        Android:resource="@drawable/notification_icon" />
<meta-data Android:name="com.google.firebase.messaging.default_notification_color"
        Android:resource="@color/google_blue" />

Обратите внимание, что если приложение находится на переднем плане (или отправлено сообщение с данными), вы можете полностью использовать собственную логику для настройки отображения. Вы также всегда можете настроить значок, если отправляете сообщение из API HTTP/XMPP.

224
Ian Barber

Используйте реализацию сервера для отправки сообщений вашему клиенту и используйте data тип сообщений вместо уведомление тип сообщений.

Это поможет вам получить обратный вызов onMessageReceived, независимо от того, находится ли ваше приложение в фоновом режиме или на переднем плане, и тогда вы можете сгенерировать свое собственное уведомление.

31
geekoraul

они работают над этим вопросом https://github.com/firebase/quickstart-Android/issues/4

когда вы отправляете уведомление из консоли Firebase, по умолчанию используется значок вашего приложения, а система Android будет превращать этот значок в белый цвет, когда он находится в панели уведомлений.

Если вы недовольны этим результатом, вам следует реализовать FirebaseMessagingService и создавать уведомления вручную при получении сообщения. Мы работаем над тем, чтобы улучшить это, но пока это единственный путь.

Правка: с помощью SDK 9.8.0 добавить в AndroidManifest.xml

<meta-data Android:name="com.google.firebase.messaging.default_notification_icon" Android:resource="@drawable/my_favorite_pic"/>
7
Jan Hartwig

Мое решение похоже на решение ATom, но проще в реализации. Вам не нужно создавать класс, полностью скрывающий FirebaseMessagingService, вы можете просто переопределить метод, который получает Intent (который является общедоступным, по крайней мере, в версии 9.6.1), и получать информацию, которая будет отображаться из дополнений. "Хакерская" часть заключается в том, что имя метода действительно запутано и будет меняться каждый раз, когда вы обновляете Firebase SDK до новой версии, но вы можете быстро найти его, проверив FirebaseMessagingService с Android Studio и посмотрев для открытого метода, который принимает Intent в качестве единственного параметра. В версии 9.6.1 это называется zzm. Вот как выглядит мой сервис:

public class MyNotificationService extends FirebaseMessagingService {

    public void onMessageReceived(RemoteMessage remoteMessage) {
        // do nothing
    }

    @Override
    public void zzm(Intent intent) {
        Intent launchIntent = new Intent(this, SplashScreenActivity.class);
        launchIntent.setAction(Intent.ACTION_MAIN);
        launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* R    equest code */, launchIntent,
                PendingIntent.FLAG_ONE_SHOT);
        Bitmap rawBitmap = BitmapFactory.decodeResource(getResources(),
                R.mipmap.ic_launcher);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_notification)
                .setLargeIcon(rawBitmap)
                .setContentTitle(intent.getStringExtra("gcm.notification.title"))
                .setContentText(intent.getStringExtra("gcm.notification.body"))
                .setAutoCancel(true)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager)     getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
}
6
Carlo Conserva

Есть еще один уродливый, но рабочий путь Декомпилируйте FirebaseMessagingService.class и измените его поведение. Затем просто поместите класс в нужный пакет в вашем приложении, и Декс использует его вместо класса в самой библиотеке сообщений. Это довольно легко и работает.

Есть метод:

private void zzo(Intent intent) {
    Bundle bundle = intent.getExtras();
    bundle.remove("Android.support.content.wakelockid");
    if (zza.zzac(bundle)) {  // true if msg is notification sent from FirebaseConsole
        if (!zza.zzdc((Context)this)) { // true if app is on foreground
            zza.zzer((Context)this).zzas(bundle); // create notification
            return;
        }
        // parse notification data to allow use it in onMessageReceived whe app is on foreground
        if (FirebaseMessagingService.zzav(bundle)) {
            zzb.zzo((Context)this, intent);
        }
    }
    this.onMessageReceived(new RemoteMessage(bundle));
}

Этот код из версии 9.4.0, метод будет иметь разные имена в другой версии из-за запутывания.

3
ATom

Просто установите для targetSdkVersion значение 19. Значок уведомления будет окрашен. Затем подождите, пока Firebase исправит эту проблему.

3
rattisuk

если ваше приложение находится в фоновом режиме, значок уведомления будет установлен на метод приема сообщений, но если ваше приложение находится на переднем плане, значок уведомления будет тем, который вы определили в манифесте.

enter image description here

2
brook

Я запускаю свои уведомления из консоли FCM и через HTTP/JSON ... с тем же результатом.

Я могу обработать заголовок, полное сообщение, но значок всегда является белым кружком по умолчанию:

скриншот уведомления

Вместо моего собственного значка в коде (setSmallIcon или setSmallIcon) или значка по умолчанию из приложения:

 Intent intent = new Intent(this, MainActivity.class);
    // use System.currentTimeMillis() to have a unique ID for the pending intent
    PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, 0);

    if (Build.VERSION.SDK_INT < 16) {
        Notification n  = new Notification.Builder(this)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(pIntent)
                .setAutoCancel(true).getNotification();
        NotificationManager notificationManager =
                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        //notificationManager.notify(0, n);
        notificationManager.notify(id, n);
    } else {
        Bitmap bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);

        Notification n  = new Notification.Builder(this)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setSmallIcon(R.drawable.ic_stat_ic_notification)
                .setLargeIcon(bm)
                .setContentIntent(pIntent)
                .setAutoCancel(true).build();

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        //notificationManager.notify(0, n);
        notificationManager.notify(id, n);
    }
2
Gonzalo

Я подумал, что добавлю ответ на этот вопрос, так как моя проблема проста, но ее трудно заметить. В частности, я скопировал/вставил существующий элемент метаданных при создании моего com.google.firebase.messaging.default_notification_icon, который использовал тег Android:value, чтобы указать его значение. Это не будет работать для значка уведомления, и как только я изменил его на Android:resource, все заработало как положено.

0
Charles A.

напиши это

<meta-data 
         Android:name="com.google.firebase.messaging.default_notification_icon"
         Android:resource="@drawable/ic_notification" />

прямо вниз <application.....>

enter image description here

0
dmarquina