这是我的舱单:
<service android:name=".fcm.PshycoFirebaseMessagingServices">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".fcm.PshycoFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
当应用程序在后台和通知到达,然后默认通知来,不运行我的onmessagerreceived代码。
这是我的onMessageReceived代码。如果我的应用程序在前台运行,而不是在后台运行,就会调用这个函数。我怎么能运行这段代码时,应用程序是在后台太?
// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO(developer): Handle FCM messages here.
// 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.
data = remoteMessage.getData();
String title = remoteMessage.getNotification().getTitle();
String message = remoteMessage.getNotification().getBody();
String imageUrl = (String) data.get("image");
String action = (String) data.get("action");
Log.i(TAG, "onMessageReceived: title : "+title);
Log.i(TAG, "onMessageReceived: message : "+message);
Log.i(TAG, "onMessageReceived: imageUrl : "+imageUrl);
Log.i(TAG, "onMessageReceived: action : "+action);
if (imageUrl == null) {
sendNotification(title,message,action);
} else {
new BigPictureNotification(this,title,message,imageUrl,action);
}
}
// [END receive_message]
我觉得所有的响应都是不完整的,但它们都有一些你需要处理的东西,当你的应用程序在后台时,一个有数据的通知。
遵循这些步骤,你将能够在应用程序处于后台时处理通知。
添加一个intent-filter,像这样:
<活动android: name = "。MainActivity”>
<意图过滤器>
<行动android: name = "。MainActivity " / >
<category android:name="android.intent.category. default " />
< /意图过滤器>
到要处理通知数据的活动。
以以下格式发送通知:
{
“通知”:{
"click_action": "。MainActivity”,
"body": "new Symulti update !",
"title": "新的Symulti更新!",
"icon": "ic_notif_symulti"},
"data":{…},
"to": "c9Vaa3ReGdk:APA91bH-AuXgg3lDN2WMcBrNhJZoFtYF9"}
这里的关键是加法
"click_action" : ".MainActivity"
其中. mainactivity是您在步骤1中添加的带有intent-filter的活动。
从.MainActivity的onCreate中的通知中获取数据信息:
onCreate(Bundle savedInstanceState)
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
//获取通知数据信息
Bundle Bundle = getIntent().getExtras();
If (bundle != null) {
//bundle必须包含通知的"data"字段发送的所有信息
}
}
这就是你需要做的。
2023年1月
对于那些实现了最新的Firebase云消息(FCM)的应用程序,您可能不会被限制在后台或完全关闭的情况下分别为应用程序发送数据和通知以处理数据。正如这里的一些回答所解释的那样,简短的版本是:
在你的启动器活动上,监视启动时的额外内容;
测试您的FCM数据中的唯一键是否在列表中;
如果存在,获取必要的数据并调用您的活动来处理您想要做的处理。
//Firebase
// [START handle_data_extras]
if (getIntent().getExtras() != null) {
boolean fcmExtraFlag = false;
for (String key : getIntent().getExtras().keySet()) {
Object value = getIntent().getExtras().get(key);
Log.d(TAG, "Key: " + key + " Value: " + value);
if(key.equalsIgnoreCase("tracerId")){
//test your known key to be sure it is from fcm
//this must have come from notification (system) tray
//this will come whether the app was in the background or completely off
//generally, this could be in the main activity as it has the intent-filter already set
fcmExtraFlag = true;
}
}
//pick fcm values if present and notify and/or process accordingly
//you may add time-lookup to ignore delayed (time-passed) ones; and ignore
if(fcmExtraFlag){
String tracerId = (String) getIntent().getExtras().get("tracerId");
//prepare your data as needed
String tracerData = tracerId+">"+data-one+">"+data-two;
String msgBody = "This is a test notification; data received: "+tracerId;
String fcmMessage = msgBody;
//start your confirmation activity, directly or whichever way
SidUtils.firebaseStartConfirms(msgBody, tracerData, this);
}
}
// [END handle_data_extras]
如前所述,如果可能的话,这应该在你的主活动中,以处理你的应用程序实际上关闭的情况-而不仅仅是在后台。这些将通过点击系统托盘上的应用程序通知来触发。
自2019年以来,谷歌Firebase的api有了很大的变化
我的意思是:
“com.google.firebase: firebase-messaging: 18.0.0”
在18.0.0中,他们删除了MyFirebaseInstanceIDService,你需要在MyFirebaseMessagingService中获取令牌,所以你只需要写:
@Override
public void onNewToken(String token) {
Log.d(TAG, "Refreshed token: " + token);
}
在你的AndroidManifest.xml中,你必须删除:
<service android:name=".service.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
此外,建议您设置默认值以自定义通知的外观。您可以指定自定义默认图标和自定义默认颜色,在通知有效负载中没有设置等效值时应用它们。
在应用程序标记中添加这些行来设置自定义默认图标和自定义颜色:
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_notification" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/push_channel" />
现在要在后台应用程序中处理通知消息,你应该在你的第一个Activity中定义一个Intent,即使它是SplashScreen。当你的应用程序在后台时,Android将通知消息定向到系统托盘。用户点击通知会默认打开应用启动器。
例如,如果你的Json是这样的:
"data": {
"message": "2",
"title": "1",
"pushType" : "banner",
"bannerLink": "http://www.google.com",
"image" : "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"}
你只需要写一个简单的意图来获取这些值:
Bundle extras = intent.getExtras();
String bannerLink = extras.getString("bannerLink");
...
String channelId = extras.getString("channelId");
我在firebase-messaging-sw.js中添加了以下代码,
messaging.onBackgroundmessage((payload)=>{
console.log("background message detected!!");
console.log("message : ", payload);
})
这是触发每次消息接收在后台。但我无法在主线程中使用有效负载,因为SW不支持它。所以我做了很多研究,在一个Android论坛上找到了一个解决方案。
因此,解决方案是必须从请求有效负载中删除通知有效负载。
所以我把有效载荷从
{
"notification": {
"title": "Hey there",
"body": "Subscribe to AMAL MOHAN N youtube channel"
},
"to": "your-browser-token",
"data": {
"value1": "text",
"value2": "",
"value3": "sample3",
"value4": "sample4"
}
}
to
{
"to": "your-browser-token",
"data": {
"value1": "text",
"value2": "",
"value3": "sample3",
"value4": "sample4"
}
}
有效负载的变化会自动在前台消息和后台消息中触发receiveMessage()。
我在一个Android论坛上发现了这个,这对我来说很有用!如果这对你有用,请告诉我。
根据文件
Handle messages in a backgrounded app
When your app is in the background, Android directs notification
messages to the system tray. A user tap on the notification opens the
app launcher by default.
This includes messages that contain both notification and data
payload. In these cases, the notification is delivered to the device's
system tray, and the data payload is delivered in the extras of the
intent of your launcher Activity.
If you want to open your app and perform a specific action, set
click_action in the notification payload and map it to an intent
filter in the Activity you want to launch. For example, set
click_action to OPEN_ACTIVITY_1 to trigger an intent filter like the
following:
<intent-filter> <action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
编辑:
基于这个线程:
不能使用Firebase Console设置click_action有效负载。您可以尝试使用curl命令或自定义http服务器进行测试
curl --header "Authorization: key=<YOUR_KEY_GOES_HERE>"
--header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send
-d "{\"to\":\"/topics/news\",\"notification\":
{\"title\": \"Click Action Message\",\"text\": \"Sample message\",
\"click_action\":\"OPEN_ACTIVITY_1\"}}"