当应用程序处于后台或手机锁定或处于睡眠模式时,不会调用gcmlistenerservice,但会触发通知。怎么称呼这个
当应用程序在前台时,它的工作状态是理想的。
gcmlistenerservice的代码如下
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
LocalDataBaseManager mDbManager;
String message;
Random randomNumber;
long ID;
/**
* Called when message is received.
*
* @param from SenderID of the sender.
* @param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
// [START receive_message]
@Override
public void onMessageReceived(String from, Bundle data) {
String message ;
String title;
// ID = Utils.getIDForPush("pushId",this);
// if(ID == 0){
// ID = 1;
// }else {
// ID += 1;
// }
// Utils.saveIDForPush("pushId",ID,this);
Bundle bundle = data.getBundle("notification");
if(bundle!= null){
message = bundle.getString("body");
title = bundle.getString("title");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);}
else {
message ="";
title = "NCMS";
}
mDbManager = LocalDataBaseManager.getInstance(this);
if (from.startsWith("/topics/")) {
Calendar c = Calendar.getInstance();
SimpleDateFormat s = new SimpleDateFormat("ddMMyyyyhhmmss");
String format = s.format(new Date());
ID = Long.parseLong(format);
String date = new SimpleDateFormat("dd-MM-yyyy HH:mm", Locale.ENGLISH).format(new Date());
Warnings warnings = new Warnings();
warnings.setWARNING_ID(ID);
warnings.setWARNING_EN(message);
warnings.setWARNING_AR(message);
warnings.setSTART_DATE_TIME(date);
warnings.setNotification_type(String.valueOf(Constant.NotificationType.PUSH));
warnings.setSEVERITY("");
warnings.setEND_DATE_TIME("");
warnings.setUPDATE_NO("");
mDbManager.insertNotificationInfo(warnings);
// message received from some topic.
} else {
// normal downstream message.
}
// [START_EXCLUDE]
/**
* Production applications would usually process the message here.
* Eg: - Syncing with server.
* - Store message in local database.
* - Update UI.
*/
/**
* In some cases it may be useful to show a notification indicating to the user
* that a message was received.
*/
// KeyguardManager km = (KeyguardManager) this.getSystemService(Context.KEYGUARD_SERVICE);
// boolean locked = km.inKeyguardRestrictedInputMode();
//
// String release = android.os.Build.VERSION.RELEASE;
//
//
// if (Integer.parseInt(String.valueOf(release.charAt(0))) < 5 && locked) {
//
// this.stopService(new Intent(this, NotificationService.class));
// Intent serviceIntent = new Intent(this, NotificationService.class);
// this.startService(serviceIntent);
//
// }
sendNotification(title,message);
// [END_EXCLUDE]
}
// [END receive_message]
/**
* Create and show a simple notification containing the received GCM message.
*
* @param message GCM message received.
*/
private void sendNotification(String title,String message) {
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("message",message);
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);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ncms_launcher)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
此服务的清单信息如下
<service
android:name=".gcm.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
我在这里失去了什么。
最佳答案
看起来这个问题的核心实际上是服务器端的问题。如果服务器正在发送通知消息,则如果应用程序在后台,则不会调用onMessageReceived
。服务器实际上应该发送数据消息。
GCM Docs讨论区别。
基本上,消息的有效负载应该有一个data
键,比如
{
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data" : {
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
},
}
而不是通知密钥,如
{
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification" : {
"body" : "great match!",
"title" : "Portugal vs. Denmark",
"icon" : "myicon"
}
}
更具体地说,gcm文档声明,根据应用程序是在前台还是后台,发送的消息(包括数据和通知有效负载)将被区别对待:
当接收到包含通知和数据有效负载的消息时,应用程序的行为取决于应用程序是在后台还是前台-本质上,是在接收时它是否处于活动状态。
在后台,应用程序在通知托盘中接收通知负载,并且仅在用户点击通知时处理数据负载。
在前台时,你的应用程序会收到一个捆绑包,其中包含两个可用的有效负载。
This github thread还有一个很好的解释:
所以有两种GCM消息:
通知消息-这些消息旨在生成通知,而应用程序不进行中间处理。只有在应用程序正在运行时,它们才会点击onMessageReceived。
数据消息-这些消息旨在无声地将数据传递到应用程序的消息服务。即使应用程序在后台,他们也会点击收到的消息。然后,服务可以选择使用常规系统通知api生成通知,也可以选择以静默方式处理消息。