0

I'm new to android. In my app, I didn't receive notification when the app is closed. If it is running it received. I tried all the way but still I didn't get the solution. Please find what I make wrong

Here my code:

Manifest.xml:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.google.android.c2dm.permission.REGISTER" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<permission android:name="com.h2o.permission.C2D_MESSAGE"
 android:protectionLevel="signature" />
 <uses-permission android:name="com.h2o.permission.C2D_MESSAGE" />
 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<receiver
     android:name="com.h2o.ExternalReceiver"
 android:permission="com.google.android.c2dm.permission.SEND" >
 <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
    <action android:name="com.google.android.c2dm.intent.REGISTER" />
    <category android:name="com.google.android.gcm.demo.app" />
  </intent-filter>
</receiver>


<service
android:name="com.h2o.MessageReceivingService"
android:label="com.h2o.MessageReceivingService" >
<intent-filter>
   <action android:name="com.h2o.ExternalReceiver" />
   <category android:name="com.h2o"/>
</intent-filter>
</service>

Receiver:

public class ExternalReceiver extends WakefulBroadcastReceiver { 
  public void onReceive(Context context, Intent intent) {
    // Explicitly specify that GcmIntentService will handle the intent.
       ComponentName comp = new ComponentName(context.getPackageName(),MessageReceivingService.class.getName());
       startWakefulService(context,(intent.setComponent(comp)));
       setResultCode(Activity.RESULT_OK);
  }
}

Service:

public class MessageReceivingService extends Service{
private GoogleCloudMessaging gcm;
public static SharedPreferences savedValues;

public static void sendToApp(Bundle extras, Context context){
    Intent newIntent = new Intent();
    newIntent.setClass(context, AndroidMobilePushApp.class);
    newIntent.putExtras(extras);
    newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(newIntent);
}

public void onCreate(){
    super.onCreate();
    final String preferences = getString(R.string.preferences);
    savedValues = getSharedPreferences(preferences, Context.MODE_PRIVATE);

    gcm = GoogleCloudMessaging.getInstance(getBaseContext());
    SharedPreferences savedValues = PreferenceManager.getDefaultSharedPreferences(this);
    if(savedValues.getBoolean(getString(R.string.first_launch), true)){
        register();
        SharedPreferences.Editor editor = savedValues.edit();
        editor.putBoolean(getString(R.string.first_launch), false);
        editor.commit();
    }
    if(savedValuess.getBoolean(getString(R.string.first_launch), true)){
        // Let AndroidMobilePushApp know we have just initialized and there may be stored messages
        sendToApp(new Bundle(), this);
    }
}

protected static void saveToLog(Bundle extras, Context context){
    SharedPreferences.Editor editor=savedValues.edit();
    String numOfMissedMessages = context.getString(R.string.num_of_missed_messages);
    int linesOfMessageCount = 0;
    for(String key : extras.keySet()){
        String line = String.format("%s=%s", key, extras.getString(key));
        editor.putString("MessageLine" + linesOfMessageCount, line);
        linesOfMessageCount++;
    }
    editor.putInt(context.getString(R.string.lines_of_message_count), linesOfMessageCount);
    editor.putInt(context.getString(R.string.lines_of_message_count), linesOfMessageCount);
    editor.putInt(numOfMissedMessages, savedValues.getInt(numOfMissedMessages, 0) + 1);
    editor.commit();
    postNotification(new Intent(context, AndroidMobilePushApp.class), context);
}

protected static void postNotification(Intent intentAction, Context context){
    final NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

    final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intentAction, Notification.DEFAULT_LIGHTS | Notification.FLAG_AUTO_CANCEL);
    final Notification notification = new NotificationCompat.Builder(context).setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle("Message Received!")
            .setContentText("")
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .getNotification();

    mNotificationManager.notify(R.string.notification_number, notification);
}

private void register() {
    new AsyncTask(){
        protected Object doInBackground(final Object... params) {
            String token;
            try {
                token = gcm.register(getString(R.string.project_number));
                Log.i("registrationId", token);
            } 
            catch (IOException e) {
                Log.i("Registration Error", e.getMessage());
            }
            return true;
        }
    }.execute(null, null, null);
}

public IBinder onBind(Intent arg0) {
    return null;
}

}

Thanks in advance!

Abu
  • 39
  • 3
  • 9

2 Answers2

1

To be able to receive notifications when your application is closed, you have to register a service listener with the following permission

android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"

See the documentation for more details

https://developer.android.com/reference/android/service/notification/NotificationListenerService.html

Francisco Hernandez
  • 2,378
  • 14
  • 18
1

you need to define your broadcast receiver in manifest like this:

<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>

and in the broadcast receiver class add the following codes:

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

there is some problem with wakeful broadcast receiver, read this Confusion about WakefulBroadcastReceiver

For best practice it is recommended that you should use Firebase cloud messaging (FCM) instead of GCM.

Community
  • 1
  • 1
rafsanahmad007
  • 23,683
  • 6
  • 47
  • 62