截至2019年7月
Android compileSdkVersion 28, buildToolsVersion 28.0.3和firebase-messaging:19.0.1
经过许多小时的研究,通过所有其他StackOverflow问题和答案,并尝试无数过时的解决方案,这个解决方案设法在以下3个场景中显示通知:
—应用程序在前台:
通知是由我的MyFirebaseMessagingService类的onmessagerreceived方法接收的
应用程序已经被杀死(它不在后台运行)
FCM自动将通知发送到通知托盘。当用户触摸通知时,应用程序通过调用manifest中有android.intent.category.LAUNCHER的活动来启动。你可以在onCreate()方法中使用getIntent(). getextras()来获取通知的数据部分。
- App is in background:
the notification is sent to the notification tray automatically by FCM. When the user touches the notification the app is brought to the foreground by launching the activity that has android.intent.category.LAUNCHER in the manifest. As my app has launchMode="singleTop" in that activity, the onCreate() method is not called because one activity of the same class is already created, instead the onNewIntent() method of that class is called and you get the data part of the notification there by using intent.getExtras().
步骤:
1-如果你这样定义你的应用程序的主活动:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:largeHeap="true"
android:screenOrientation="portrait"
android:launchMode="singleTop">
<intent-filter>
<action android:name=".MainActivity" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
2-在MainActivity.class的onCreate()方法中添加这些行
Intent i = getIntent();
Bundle extras = i.getExtras();
if (extras != null) {
for (String key : extras.keySet()) {
Object value = extras.get(key);
Log.d(Application.APPTAG, "Extras received at onCreate: Key: " + key + " Value: " + value);
}
String title = extras.getString("title");
String message = extras.getString("body");
if (message!=null && message.length()>0) {
getIntent().removeExtra("body");
showNotificationInADialog(title, message);
}
}
和这些方法到同一个MainActivity.class:
@Override
public void onNewIntent(Intent intent){
//called when a new intent for this class is created.
// The main case is when the app was in background, a notification arrives to the tray, and the user touches the notification
super.onNewIntent(intent);
Log.d(Application.APPTAG, "onNewIntent - starting");
Bundle extras = intent.getExtras();
if (extras != null) {
for (String key : extras.keySet()) {
Object value = extras.get(key);
Log.d(Application.APPTAG, "Extras received at onNewIntent: Key: " + key + " Value: " + value);
}
String title = extras.getString("title");
String message = extras.getString("body");
if (message!=null && message.length()>0) {
getIntent().removeExtra("body");
showNotificationInADialog(title, message);
}
}
}
private void showNotificationInADialog(String title, String message) {
// show a dialog with the provided title and message
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(title);
builder.setMessage(message);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
3-像这样创建MyFirebase类:
package com.yourcompany.app;
import android.content.Intent;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
public MyFirebaseMessagingService() {
super();
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(Application.APPTAG, "myFirebaseMessagingService - onMessageReceived - message: " + remoteMessage);
Intent dialogIntent = new Intent(this, NotificationActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dialogIntent.putExtra("msg", remoteMessage);
startActivity(dialogIntent);
}
}
4-创建一个新类NotificationActivity.class,如下所示:
package com.yourcompany.app;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ContextThemeWrapper;
import com.google.firebase.messaging.RemoteMessage;
public class NotificationActivity extends AppCompatActivity {
private Activity context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
Bundle extras = getIntent().getExtras();
Log.d(Application.APPTAG, "NotificationActivity - onCreate - extras: " + extras);
if (extras == null) {
context.finish();
return;
}
RemoteMessage msg = (RemoteMessage) extras.get("msg");
if (msg == null) {
context.finish();
return;
}
RemoteMessage.Notification notification = msg.getNotification();
if (notification == null) {
context.finish();
return;
}
String dialogMessage;
try {
dialogMessage = notification.getBody();
} catch (Exception e){
context.finish();
return;
}
String dialogTitle = notification.getTitle();
if (dialogTitle == null || dialogTitle.length() == 0) {
dialogTitle = "";
}
AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(context, R.style.myDialog));
builder.setTitle(dialogTitle);
builder.setMessage(dialogMessage);
builder.setPositiveButton(getResources().getString(R.string.accept), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
5-添加这些行到你的应用程序清单,在你的标签
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id"/>
<activity android:name=".NotificationActivity"
android:theme="@style/myDialog"> </activity>
<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/color_accent" />
6-在Application.java的onCreate()方法或MainActivity.class的onCreate()方法中添加这些行:
// notifications channel creation
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Create channel to show notifications.
String channelId = getResources().getString("default_channel_id");
String channelName = getResources().getString("General announcements");
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(new NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_LOW));
}
完成了。
现在,为了在上述3个场景中很好地工作,你必须以以下方式从Firebase web控制台发送通知:
In the Notification section:
Notification Title = Title to display in the notification dialog (optional)
Notification text = Message to show to the user (required)
Then in the Target section:
App = your Android app
and in Additional Options section:
Android Notification Channel = default_channel_id
Custom Data
key: title value: (same text here than in the Title field of the Notification section)
key: body value: (same text here than in the Message field of the Notification section)
key:click_action value: .MainActivity
Sound=Disabled
Expires=4 weeks
你可以在模拟器中调试它与API 28谷歌播放。
编码快乐!