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



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



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



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



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

}
702   9  

9 ответов:

к сожалению, это было ограничение уведомлений Firebase в 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.

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

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

короче решение

это происходит только при отправке сообщений через консоль firebase, а не API

atm они работают над этим вопросом 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"/>

мое решение похоже на атом, но легче реализовать. Вам не нужно создавать класс, который полностью затеняет FirebaseMessagingService, вы можете просто переопределить метод, который получает намерение (который является общедоступным, по крайней мере, в версии 9.6.1), и взять информацию, которая будет отображаться из дополнительных компонентов. "Хакерская" часть заключается в том, что имя метода действительно запутано и будет меняться каждый раз, когда вы обновляете Firebase sdk до новой версии, но вы можете быстро найти его проверка FirebaseMessagingService с помощью Android Studio и поиск общедоступного метода, который принимает намерение в качестве единственного параметра. В версии 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());
    }
}

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

есть способ:

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, метод будет иметь разные имена в разных версиях из-за обфускации.

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

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

enter image description here

Я запускаю свои уведомления с консоли 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);
    }

Comments

    Ничего не найдено.