昨日グーグルはグーグルI/Oで新しいFirebaseに基づく新しい通知システムを発表した。私はGithubの例でこの新しいFCM(Firebase Cloud Messaging)を試しました。
通知のアイコンは、私が特定のdrawableを宣言したにもかかわらず、常に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());
}
}
残念ながら、これはSDK 9.0.0-9.6.1のFirebase Notificationsの制限でした。アプリがバックグラウンドで実行されているときは、コンソールから送信されたメッセージに対して、ランチャーアイコンがマニフェストから(必要な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" />
アプリがフォアグラウンドにある(またはデータメッセージが送信される)場合は、独自のロジックを使用して表示をカスタマイズできます。 HTTP/XMPP APIからメッセージを送信する場合は、いつでもアイコンをカスタマイズできます。
クライアントにメッセージを送信するためにサーバー実装を使い、 notification typeではなく data typeのメッセージを使うメッセージ.
これは、アプリがバックグラウンドまたはフォアグラウンドのどちらにあるかに関係なく、onMessageReceived
へのコールバックを取得するのに役立ちます。その後、カスタム通知を生成できます。
atm彼らはその問題に取り組んでいます https://github.com/firebase/quickstart-Android/issues/4
firebase consoleから通知を送信すると、デフォルトでアプリのアイコンが使用されます。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"/>
私の解決策はATomのものと似ていますが、実装が簡単です。 FirebaseMessagingServiceを完全に隠すクラスを作成する必要はありません。Intentを受け取るメソッド(少なくともバージョン9.6.1ではパブリック)をオーバーライドして、エキストラから表示される情報を取得することができます。 「ハッキー」な部分は、Firebase sdkを新しいバージョンに更新するたびに、メソッド名が実際には難読化されて変更されることですが、Android StudioでFirebaseMessagingServiceを調べてパブリックメソッドを取得することですばやく検索できます唯一のパラメータとしての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());
}
}
醜いけれども働く方法も1つあります。 FirebaseMessagingService.classを逆コンパイルして動作を変更します。それから、yout appの正しいパッケージにクラスを入れて、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がこの問題を解決するのを待ちます。
私は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);
}
私の問題は単純だが気づきにくいので、私はこれに答えを追加すると思いました。特に、com.google.firebase.messaging.default_notification_icon
を作成するときに既存のメタデータ要素をコピー/貼り付けしていました。これは、値を指定するためにAndroid:value
タグを使用していました。これは通知アイコンでは機能しません。そして、それをAndroid:resource
に変更すると、すべて正常に機能しました。