Wczoraj Google zaprezentował na Google I / O nowy system powiadomień oparty na nowym Firebase. Wypróbowałem ten nowy FCM (Firebase Cloud Messaging) z przykładem na Github.
Ikoną powiadomienia jest zawsze ic_launcher, mimo że zadeklarowałem konkretny wyciąg
Czemu ? Poniżej oficjalny kod do obsługi wiadomości
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());
}
}
Odpowiedzi:
Niestety było to ograniczenie Powiadomień Firebase w SDK 9.0.0-9.6.1. Gdy aplikacja działa w tle, dla wiadomości wysyłanych z konsoli używana jest ikona programu uruchamiającego z manifestu (z wymaganym podbarwieniem systemu Android).
Jednak dzięki SDK 9.8.0 możesz zastąpić ustawienie domyślne! W pliku AndroidManifest.xml możesz ustawić następujące pola, aby dostosować ikonę i kolor:
<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" />
Zwróć uwagę, że jeśli aplikacja jest na pierwszym planie (lub zostanie wysłana wiadomość z danymi), możesz całkowicie użyć własnej logiki, aby dostosować wyświetlacz. Możesz także zawsze dostosować ikonę, jeśli wysyłasz wiadomość z interfejsów API HTTP / XMPP.
źródło
Użyj implementacji serwerowej, aby wysyłać wiadomości do klienta i używać typów danych wiadomości zamiast typów powiadomień .
Pomoże Ci to uzyskać oddzwonienie
onMessageReceived
niezależnie od tego, czy Twoja aplikacja działa w tle, czy na pierwszym planie, a następnie możesz wygenerować niestandardowe powiadomienieźródło
atm, że pracują nad tym problemem https://github.com/firebase/quickstart-android/issues/4
edytuj: za pomocą SDK 9.8.0 dodaj do AndroidManifest.xml
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/my_favorite_pic"/>
źródło
Moje rozwiązanie jest podobne do rozwiązania ATom, ale jest łatwiejsze do wdrożenia. Nie musisz tworzyć klasy, która całkowicie przesłania FirebaseMessagingService, możesz po prostu zastąpić metodę, która odbiera Intent (która jest publiczna, przynajmniej w wersji 9.6.1) i pobrać informacje, które mają być wyświetlane z dodatków. „Hacky” część polega na tym, że nazwa metody jest rzeczywiście zaciemniona i będzie się zmieniać za każdym razem, gdy zaktualizujesz pakiet SDK Firebase do nowej wersji, ale możesz ją szybko sprawdzić, sprawdzając usługę FirebaseMessagingService w Android Studio i szukając metody publicznej, która wymaga intencja jako jedyny parametr. W wersji 9.6.1 nazywa się zzm. Oto jak wygląda moja usługa:
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()); } }
źródło
Po prostu ustaw targetSdkVersion na 19. Ikona powiadomienia będzie kolorowa. Następnie poczekaj, aż Firebase rozwiąże ten problem.
źródło
Jest też jeden brzydki, ale działający sposób. Zdekompiluj FirebaseMessagingService.class i zmodyfikuj jego zachowanie. Następnie po prostu umieść klasę w odpowiednim pakiecie w aplikacji yout i dex użyj jej zamiast klasy w samej bibliotece wiadomości. Jest to dość łatwe i działa.
Jest metoda:
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)); }
Ten kod pochodzi z wersji 9.4.0, metoda będzie miała różne nazwy w różnych wersjach z powodu zaciemnienia.
źródło
jeśli Twoja aplikacja działa w tle, ikona powiadomienia zostanie ustawiona na metodę odbioru wiadomości, ale jeśli aplikacja jest na pierwszym planie, ikona powiadomienia będzie tą, którą zdefiniowałeś w manifeście
źródło
Uruchamiam powiadomienia z konsoli FCM i przez HTTP / JSON ... z tym samym wynikiem.
Potrafię obsłużyć tytuł, pełną wiadomość, ale ikona jest zawsze domyślnym białym kółkiem:
Zrzut ekranu powiadomienia
Zamiast mojej niestandardowej ikony w kodzie (setSmallIcon lub setSmallIcon) lub domyślnej ikony z aplikacji:
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); }
źródło
Napisz to
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_notification" />
w dół
<application.....>
źródło
Pomyślałem, że dodam odpowiedź do tego, ponieważ mój problem był prosty, ale trudny do zauważenia. W szczególności podczas tworzenia
com.google.firebase.messaging.default_notification_icon
pliku my skopiowałem / wkleiłem istniejący element metadanych , który używałandroid:value
znacznika do określenia jego wartości. To nie zadziała dla ikony powiadomienia, a gdy ją zmieniłem,android:resource
wszystko działało zgodnie z oczekiwaniami.źródło
default_notification_color
meta, musi to byćandroid:resource
- ustawienie,android:value
które nie zadziała