Dani Andújar
Dani Andújar

Reputation: 1176

Push Notifications when app is closed

Do you know if is it possible to receive notifications from google cloud message when the application is fully closed?

I know if it's open or in background yes, but can it be programmed any way in order to receive them?

EDIT:

I continue without receiving notifications when the app is closed.

I attached the code in case I have an error and I am not watching it.

MANIFEST

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.frab"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.frab.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<permission
android:name="com.frab.permission.C2D_MESSAGE"
android:protectionLevel="signature" />

<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.frab.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<receiver
android:name=".GGMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.something" />
</intent-filter>
</receiver>

<service android:name=".GCMIntentService" />
</application>

</manifest>

BROADCAST RECEIVER

package com.something;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.activities.SignIn;
import com.google.android.gcm.GCMBaseIntentService;
import com.objects.Globals;

public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "GGM <-----> FRAB";
private Bundle extras;

public GCMIntentService() {
super(Globals.SENDER_ID);
}

@Override
public void onDestroy() {
Log.d(TAG, "terminando servicio");
}

@Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "onRegistered: registrationId=" + registrationId);
}

@Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "onUnregistered: registrationId = " + registrationId);
}
@Override
protected void onMessage(Context context, Intent data) {
extras = data.getExtras();
String message = extras.getString("msg");
Log.d("******", message);
sendNotification(message);
}

@Override
protected void onError(Context arg0, String errorId) {
Log.e(TAG, "onError: errorId = " + errorId);
}    
}

package com.something;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;

public class GGMBroadcastReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(), GCMIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}

When the app is open : OK

When the app is in background : Ok

When the app is closed forcefully by the user : notifications don't arrive

What is the problem?

Thank you very much.

Upvotes: 44

Views: 114475

Answers (8)

Paresh
Paresh

Reputation: 993

I was having the same issue on Oneplus phone. As mentioned by many people above, the issue was forceful app termination. In my case, it was done due to "Recent App management" setting as shown below. Once I changed it to "Normal clear" setting everything started working fine.

enter image description here

Upvotes: 0

Dhaval Jivani
Dhaval Jivani

Reputation: 9697

Firebase API has two types of messages, they call them:

  • notification
  • data

find more information from here

IMPORTANT : You can't send data payload messages from Firebase Console, Console only delivers notification message. So I have mentioned how to send push notification using postman please follow below steps for that.

You must send push messages with data payload because of data payload - Doesn't matter whether your application is in the foreground or background or killed, these messages will always be delivered to onMessageReceived() method.

In Android 8.0 Oreo if the application is closed, then notification is not received It is because of DOZE mode and battery optimization,you just have to turn off battery optimization for all apps or particular app.

Turn off battery optimization for your app by below step:

Settings>> Battery >> battery Optimization >> find your app >> select >> if optimized click on don't optimize >> try pushing notification

Send push notification using postman

Step 1: https://fcm.googleapis.com/fcm/send

Step 2: Set this two into Header

Authorization : key=AIzaSyBuRl1Ikz3VXFvU7xW9mmg51lJ3uDSH

Content-Type : application/json

Step 3: Send this json

{
 "to" : "eb9HgFulyzU:APA91bFMLReWWwilNFfJ1fnXZ0A2PhJAYsabg-UcK_dHgHQcstTzcxLs4_mqgOmZtUiyLMne4JaOG7f8KH7pWxB7JugOGCCYgjd4fUynRBKZvNUgjaj2UdJB2Ux8VocszuUydCX",
 "data" : {
     "message" : "First Notification",
     "title": "Push Notification",
     "key_1" : "Key 1 value",
     "key_2" : "Hello"
 }
}

Hope this helps..

Enjoy :) :)

Upvotes: 8

Zez3
Zez3

Reputation: 269

After some testing I did on this issue, I found out that it behaves differently on how the app is closed. If you close the app while the cable is connected to the device, it then blocks every notification when the app is closed. However, if you take the cable off the device and close the app, when you send the notification, everything works again, as it should!

In case you get a "Waiting for the Debugger" popup message, just restart the device and then send a test notification!

Upvotes: 11

Sahil Bajaj
Sahil Bajaj

Reputation: 925

Yes, it is possible 'to receive notifications from google cloud message when the application is fully closed'.

Infact, A broadcast receiver is the mechanism GCM uses to deliver messages. You need to have implement a BroadcastReceiver and declare it in the AndroidManifest.xml.

Please refer to the following code snippet.

AndroidManifest.xml

<receiver
    android:name=".GcmBroadcastReceiver"
    android:permission="com.google.android.c2dm.permission.SEND" >
    <intent-filter>
        <!-- Receives the actual messages. -->
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <category android:name="com.google.android.gcm.demo.app" />
    </intent-filter>
</receiver>
<service android:name=".GcmIntentService" />

Java code

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // Explicitly specify that GcmIntentService will handle the intent.
        ComponentName comp = new ComponentName(context.getPackageName(),
                GcmIntentService.class.getName());
        // Start the service, keeping the device awake while it is launching.
        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
    }
}

When GCM delivers a message to your device, BroadcastReceiver will receive the message and call the onReceive() function, wherein you may start a service to actually perform the intended task for you.

The above Code example uses a specialized BroadcastReceiver called WakefulBroadcastReceiver, which makes sure that the device doesn't go to sleep, while the service is doing its work.

Refer to the Official Android Page for the same: https://developer.android.com/google/gcm/client.html

Upvotes: 23

SandyQi
SandyQi

Reputation: 21

I just finished a GCM app. It still works well if you close the app. The thing is you should have already opened the app for once. create two class to achieve this goal: GcmBroadcastReceiver and GcnIntentService. Find more information http://developer.android.com/google/gcm/index.html

Here is the trick

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    // Explicitly specify that GcmIntentService will handle the intent.
    ComponentName comp = new ComponentName(context.getPackageName(),
            GcmIntentService.class.getName());
    // Start the service, keeping the device awake while it is launching.
    startWakefulService(context, (intent.setComponent(comp)));
    setResultCode(Activity.RESULT_OK);

}
}

the class being extended is WakeFulBroadcastReceiver. There is a WAKE_LOCK permission in your Manifest.xml. This allows using PowerManager WakeLocks to keep processor from sleeping or screen from dimming. However, if you extend BroadcastReceiver, it will not work after the app is closed.

<uses-permission android:name="android.permission.WAKE_LOCK" />

Upvotes: 2

laalto
laalto

Reputation: 152807

When the app is closed forcelly by the user : notifications don't arrive

It's a feature of the Android platform. Force stopping an application by the user puts the application in a stopped state and none of its code is run, including any broadcast receivers declared in manifest. Only when the user explicitly launches the app it is put in a state where the receivers get fired.

For further reading: http://www.doubleencore.com/2014/06/effects-android-application-termination/

Upvotes: 18

Dani And&#250;jar
Dani And&#250;jar

Reputation: 1176

I've been trying another phone and the second worked perfectly, even when the phone was off. The first had a room that did not allow to be notified when the app was closed ... Thanks to all

Upvotes: 0

berserk
berserk

Reputation: 2728

It will not work on killing the app from task manager, but work if you just slide it away from recent. I tried doing on whatsapp by killing it and ask someone to send a msg to me, and I haven't got any notification. Then I started the app, and I got notification.

Upvotes: 6

Related Questions