Gestern hat Google bei Google I/O das neue Benachrichtigungssystem vorgestellt, das auf der neuen Firebase basiert. Ich habe dieses neue FCM (Firebase Cloud Messaging) am Beispiel von Github ausprobiert.
Das Icon der Benachrichtigung ist immer der ic_launcher , obwohl ich ein bestimmtes Drawable deklariert habe
Warum ? Hier unten der offizielle Code für die Bearbeitung der Nachricht
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());
}
}
Leider war dies eine Einschränkung von Firebase Notifications in SDK 9.0.0-9.6.1. Wenn sich die App im Hintergrund befindet, wird das Startsymbol aus dem Manifest (mit der erforderlichen Tönung Android)) für von der Konsole gesendete Nachrichten verwendet.
Mit SDK 9.8.0 können Sie jedoch die Standardeinstellung überschreiben! In Ihrer AndroidManifest.xml können Sie die folgenden Felder festlegen, um das Symbol und die Farbe anzupassen:
<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" />
Beachten Sie, dass Sie, wenn sich die App im Vordergrund befindet (oder eine Datennachricht gesendet wird), Ihre eigene Logik verwenden können, um die Anzeige anzupassen. Sie können das Symbol auch jederzeit anpassen, wenn Sie die Nachricht über die HTTP/XMPP-APIs senden.
Verwenden Sie eine Serverimplementierung, um Nachrichten an Ihren Client zu senden, und verwenden Sie data Nachrichtentyp anstatt notification Nachrichtentyp.
Dies hilft Ihnen dabei, einen Rückruf an onMessageReceived
zu erhalten, unabhängig davon, ob sich Ihre App im Hintergrund oder im Vordergrund befindet, und Sie können dann Ihre benutzerdefinierte Benachrichtigung generieren
atm sie arbeiten an diesem Problem https://github.com/firebase/quickstart-Android/issues/4
wenn Sie eine Benachrichtigung über die Firebase-Konsole senden, wird standardmäßig Ihr App-Symbol verwendet, und das Android System wird dieses Symbol in der Benachrichtigungsleiste durchgehend weiß.
Wenn Sie mit diesem Ergebnis nicht zufrieden sind, sollten Sie FirebaseMessagingService implementieren und die Benachrichtigungen manuell erstellen, wenn Sie eine Nachricht erhalten. Wir arbeiten an einer Möglichkeit, dies zu verbessern, aber im Moment ist dies der einzige Weg.
edit: mit SDK 9.8.0 zu AndroidManifest.xml hinzufügen
<meta-data Android:name="com.google.firebase.messaging.default_notification_icon" Android:resource="@drawable/my_favorite_pic"/>
Es gibt auch einen hässlichen, aber funktionierenden Weg. Dekompilieren Sie FirebaseMessagingService.class und ändern Sie dessen Verhalten. Dann setzen Sie einfach die Klasse in das richtige Paket in Ihrer App und verwenden Sie sie anstelle der Klasse in der Messaging-Bibliothek. Es ist ganz einfach und funktioniert.
Es gibt Methode:
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));
}
Dieser Code ist ab Version 9.4.0, die Methode hat aufgrund der Verschleierung in verschiedenen Versionen unterschiedliche Namen.
Setzen Sie einfach targetSdkVersion auf 19. Das Benachrichtigungssymbol wird farbig. Warten Sie dann, bis Firebase dieses Problem behoben hat.
Ich starte meine Benachrichtigungen über die FCM-Konsole und über HTTP/JSON ... mit demselben Ergebnis.
Ich kann mit dem Titel und der vollständigen Nachricht umgehen, aber das Symbol ist immer ein weißer Standardkreis:
Anstelle meines benutzerdefinierten Symbols im Code (setSmallIcon oder setSmallIcon) oder des Standardsymbols aus der App:
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);
}
Dachte, ich würde eine Antwort auf diese hinzufügen, da mein Problem einfach, aber schwer zu bemerken war. Insbesondere hatte ich beim Erstellen meines com.google.firebase.messaging.default_notification_icon
- Tags ein vorhandenes Metadatenelement kopiert/eingefügt, das einen Wert mit einem Android:value
- Tag angab. Dies funktioniert nicht für das Benachrichtigungssymbol, und nachdem ich es auf Android:resource
Geändert habe, hat alles wie erwartet funktioniert.