androidgoogle-cloud-messaginggcmlistenerservice

GcmListenerService is not called When Application is in Background


GcmListenerService is not called when application is in background or when phone is locked or in sleep mode but notification is fired. How this will be called When App is in foreground its working ideally. Code for GcmListenerService is following

  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());
    }
}

Manifest info for this service is following

 <service
        android:name=".gcm.MyGcmListenerService"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>

What I am missing here.


Solution

  • The Issue I was facing was when Application is in background or force closed then notification is fired but not through GcmListenService but through GCMReceiver So I extended GCMReceiver and made it something like this with this when application is in foreground or in background or force killed. it will be called GCMListenerService after modification is as following

     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());
        }
    } 
    

    and GCM Receiver is as following

       public class GcmBroadcastReceiver extends GcmReceiver {
    
        LocalDataBaseManager mDbManager;
        @Override
        public void onReceive(Context context, Intent intent) {
            mDbManager = LocalDataBaseManager.getInstance(context);
            Bundle bundle = intent.getExtras();
            bundle.keySet();
            Set<String> keySet = bundle.keySet();
            if(keySet != null && keySet.isEmpty() == false) {
                Iterator<String> it = keySet.iterator();
               int i = 0;
                while(it.hasNext()){
                   String  key = it.next();
                   String  desc = bundle.getString(key);
                   Log.d("BroadCast Values",key +"  "+desc);
                }
            }
            Log.d("", "In Receive Method of Broadcast Receiver");
    
            if (bundle != null && bundle.containsKey("gcm.notification.body")) {
                String message = bundle.getString("gcm.notification.body","");
                Long ID = new Date().getTime();
                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.
            }
    
            super.onReceive(context, intent);
    //        ComponentName cn = new ComponentName(context.getPackageName(), RegistrationIntentService.class.getName());
    //        startWakefulService(context, intent.setComponent(cn));
    //        setResultCode(Activity.RESULT_OK);
        }
    }
    

    Manifest changes for GCMReceiver is following

       <receiver
                android:name=".gcm.GcmBroadcastReceiver"
                android:exported="true"
                android:permission="com.google.android.c2dm.permission.SEND" >
                <intent-filter>
                    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                    <category android:name="com.uae.ncms" />
                </intent-filter>
            </receiver>
    <service
            android:name=".gcm.MyGcmListenerService"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>