这是我的舱单:
<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]
我想出了各种方案
当app在前台时,
onMessageReceived()方法从FirebaseService调用。因此,服务类中定义的pendingIntent将被调用。
当app在后台时,第一个activity被调用。
现在,如果你使用了一个splashactivity,那么必须记住splashactivity会被调用,否则如果没有splashactivity,那么无论第一个activity是什么,都会被调用。
然后你需要检查firstActivity的getIntent(),看看它是否有任何bundle。如果一切正常,你会看到bundle在那里,值被填充。如果从服务器发送的数据标签中的值是这样的,
"data": {
"user_name": "arefin sajib",
"value": "user name notification"
}
然后在第一个活动中,你会看到,
有一个有效的意图(getIntent()不是null),有效的捆绑包和在捆绑包内,会有上面提到的以数据为键的整个JSON。
在这种情况下,提取值的代码是这样的,
if(getIntent()!=null){
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
try {
JSONObject object = new JSONObject(bundle.getStringExtra("data"));
String user_name = object.optString("user_name");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
要使firebase库在以下情况下调用onmessagerecreceived ()
应用程序在前台
后台应用程序
应用程序已被杀死
你不能把JSON键通知在你的请求到Firebase API,而是使用数据,见下文。
当你的应用程序处于后台或被杀死时,下面的消息将不会调用你的onmessagerreceived(),并且你不能自定义你的通知。
{
"to": "/topics/journal",
"notification": {
"title" : "title",
"text": "data!",
"icon": "ic_notification"
}
}
但是用这个方法就可以了
{
"to": "/topics/dev_journal",
"data": {
"text":"text",
"title":"",
"line1":"Journal",
"line2":"刊物"
}
}
基本上,消息是在参数RemoteMessage中与数据对象一起发送的,如Map<String, String>,然后您可以在这里的代码片段中管理onmessagerreceived中的通知
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
//you can get your text message here.
String text= data.get("text");
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
// optional, this is to make beautiful icon
.setLargeIcon(BitmapFactory.decodeResource(
getResources(), R.mipmap.ic_launcher))
.setSmallIcon(smallIcon) //mandatory
.......
/*You can read more on notification here:
https://developer.android.com/training/notify-user/build-notification.html
https://www.youtube.com/watch?v=-iog_fmm6mE
*/
}
此情况仅用于firebase管理通知
如果应用程序在后台,则不会触发FirebaseMessagingService
要处理这种情况,请转到launcher activity,检查附加的intent bundle,并使用以下代码打印出所有数据:
intent?.extras?.let {it->
for (key in bundle.keySet()) {
val value = bundle[key]
Log.d("NotificationData", String.format("%s %s (%s)", key, value.toString(), value!!.javaClass.name))
}
}
显示所有数据类型的签入日志;
例子:
我想从通知中获得周和标题将使用这段代码
intent?.extras?.let {it->
if (it.containsKey("week")){
}
if (it.containsKey("title")){
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
}
不是每次调用它时,只有当应用程序是在前景
有一个覆盖方法,这个方法每次都会被调用,不管什么应用程序在前台,在后台或被杀死,但是这个方法在这个firebase API版本中可用
这是你必须从gradle导入的版本
compile 'com.google.firebase:firebase-messaging:10.2.1'
这就是方法
@Override
public void handleIntent(Intent intent) {
super.handleIntent(intent);
// you can get ur data here
//intent.getExtras().get("your_data_key")
}
在之前的firebase API中,这个方法是不存在的
当应用程序在后台....时,Fire base句柄本身现在你有了这个方法
无论你想做什么…你可以在这里用这个方法.....
如果您使用的是以前的版本,那么默认活动将启动
在这种情况下,你可以用同样的方法得到数据
if(getIntent().getExtras() != null && getIntent().getExtras().get("your_data_key") != null) {
String strNotificaiton = getIntent().getExtras().get("your_data_key").toString();
//做你想做的事....
}
通常这是我们在通知中从服务器获得的结构
{
"notification": {
"body": "Cool offers. Get them before expiring!",
"title": "Flat 80% discount",
"icon": "appicon",
"click_action": "activity name" //optional if required.....
},
"data": {
"product_id": 11,
"product_details": "details.....",
"other_info": "......."
}
}
这是由你决定的,你想给数据键或者你想给任何你可以给.......的通知
无论你在这里给出什么,用相同的键,你都会得到数据.........
有少数情况下,如果你没有发送点击动作在这种情况下,当你将点击通知默认活动将打开,但如果你想打开你的特定活动时,应用程序是在后台,你可以从这个handleIntent方法调用你的活动,因为这是每次调用
像这样简单的总结
如果你的应用正在运行;
onMessageReceived ()
是触发器。
如果你的应用程序没有运行(通过滑动杀死);
onMessageReceived ()
不是直接触发和传递的。如果你有特殊的键值对。它们不工作,因为onmessagerecreceived()不工作。
我找到了这条路;
在你的启动器活动中,放入这样的逻辑,
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState, R.layout.activity_splash);
if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("PACKAGE_NAME")) {
// do what you want
// and this for killing app if we dont want to start
android.os.Process.killProcess(android.os.Process.myPid());
} else {
//continue to app
}
}
在这个if块中,根据firebase UI搜索你的密钥。
在这个例子中,我的键和值就像上面那样;(对不起,语言=))
当我的代码工作时,我得到“com.rda.note”。
android.os.Process.killProcess(android.os.Process.myPid());
有了这行代码,我关闭了我的应用程序,打开谷歌播放市场
快乐编码=)