当应用程序在后台时,android – GcmListenerService不被调用

当应用程序在后台或手机被锁定或处于睡眠模式,但通知被触发时,GcmListenerService不被调用.怎么会这样叫
当App在前台时,它的工作理想.
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讨论区别.

基本上,消息的有效载荷应该具有数据密钥,例如

{
   "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文档指出,包含数据和通知有效内容的消息发送将被视为不同的,具体取决于应用程序是在前台还是后台

App behavior when receiving messages that include both notification and data payloads depends on whether the app is in the background,or the foreground —essentially,whether or not it is active at the time of receipt.

  • When in the background,apps receive the notification payload in the notification tray,and only handle the data payload when the user taps on the notification.
  • When in the foreground,your app receives a bundle with both payloads available.

This github thread也有很好的解释:

So there are two kinds of GCM messages:

  • Notification Messages – these are intended to generate a notification with no intermediate processing by the application. They only hit onMessageReceived if the app is running.

  • Data Messages – these are intended to silently pass data to the app’s messaging service. They hit onMessageReceived even if the app is in the background. The service may then choose to generate a notification using the normal system notification APIs,or it may choose to handle the message silently.

相关文章

Android 通过adb shell命令查看内存,CPU,启动时间,电量等...
Monkey Android app稳定性测试工具之Monkey使用教程 by:授客...
Android 常见adb命令 by:授客 QQ:1033553122 1、 查看所有已...
这篇“android轻量级无侵入式管理数据库自动升级组件怎么实现...
今天小编给大家分享一下Android实现自定义圆形进度条的常用方...
这篇文章主要讲解了“Android如何解决字符对齐问题”,文中的...