9

In my application I have push notification integrated with GCM. Its working fine whenever notification comes its appearing. But push notification come even when user is inside the app. I want notifications to appear only when user is outside the app.

Here is my code for push notification:

GcmBroadcastReceiver

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    ComponentName comp = new ComponentName(GCMNotificationIntentService.class.getPackage().getName(), 
            GCMNotificationIntentService.class.getName());
    startWakefulService(context, (intent.setComponent(comp)));
    setResultCode(Activity.RESULT_OK);
}
}

GCMnotificationIntentService.Class

public class GCMNotificationIntentService extends IntentService {

public static int notificationId = 10;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
private boolean login_status = false;


public GCMNotificationIntentService() {
    super("GcmIntentService");
}

public static final String TAG = GCMNotificationIntentService.class.getSimpleName();

@Override
protected void onHandleIntent(Intent intent) {
    Bundle extras = intent.getExtras();
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
    // The getMessageType() intent parameter must be the intent you received
    // in your BroadcastReceiver.
    String messageType = gcm.getMessageType(intent);

    if ( !extras.isEmpty() ) { // has effect of unparcelling Bundle
        /*
         * Filter messages based on message type. Since it is likely that
         * GCM will be extended in the future with new message types, just
         * ignore any message types you're not interested in, or that you
         * don't recognize.
         */
        if ( GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType) ) {
            sendNotification("Send error: " + extras.toString());
        } else if ( GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType) ) {
            sendNotification("Deleted messages on server: " + extras.toString());
            // If it's a regular GCM message, do some work.
        } else if ( GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType) ) {
            sendNotification(extras.getString("message"));
            Log.i(TAG, "Received: " + extras.toString());
        }
    }
    // Release the wake lock provided by the WakefulBroadcastReceiver.
    GcmBroadcastReceiver.completeWakefulIntent(intent);
}

private void sendNotification(String msg) {

    mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this).setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle(getString(R.string.notification_title))
            .setStyle(new NotificationCompat.BigTextStyle().bigText(msg)).setContentText(msg);
    Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    mBuilder.setSound(uri);
    mBuilder.setContentIntent(contentIntent);
    mBuilder.setAutoCancel(true);
    mNotificationManager.notify(notificationId++, mBuilder.build());
}
}

In ManifestFile

 <receiver
        android:name=".GcmBroadcastReceiver"
        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.medlife.deliveryagent" />
        </intent-filter>
    </receiver>
  <service android:name=".GCMNotificationIntentService" />

Any suggestions would be highly appreciated!!!

Naman
  • 2,205
  • 2
  • 19
  • 32
John
  • 1,407
  • 7
  • 26
  • 51
  • Have you added permission for ? – Amit Jun 19 '15 at 11:31
  • You have control what to show, or show not to show in notifications. Just you have to find app is in foreground I think. This link of SO discusses about that. Just check it out. http://stackoverflow.com/questions/5504632/how-can-i-tell-if-android-app-is-running-in-the-foreground – Alok Rao Jun 19 '15 at 11:33
  • @Amit I have added all the permission in manifest file. then only its working – John Jun 19 '15 at 11:33
  • Have a look at http://stackoverflow.com/questions/30544165/starting-app-only-if-its-not-currently-running/30703555#30703555 – Haris Qurashi Jun 19 '15 at 11:34
  • You mean if you have exited your app then you want to show notification?? – Pankaj Jun 19 '15 at 11:34
  • @Clairvoyant : Yes exactly . – John Jun 19 '15 at 11:35

2 Answers2

4

Do something like this to check whether you app is in foreground or not by calling below method and depending on returning value true or false do your rest of work

public boolean checkApp(){
       ActivityManager am = (ActivityManager) this
                .getSystemService(ACTIVITY_SERVICE);

        // get the info from the currently running task
        List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);

        ComponentName componentInfo = taskInfo.get(0).topActivity;
        if (componentInfo.getPackageName().equalsIgnoreCase("YourPackage")) {
            return true;
        } else {
           return false;
        }
  } 
Pankaj
  • 7,908
  • 6
  • 42
  • 65
  • For packageName can i give particular classname , – John Jun 22 '15 at 07:23
  • Yeah you can use class name also format would be: `pacakgename + classname` – Pankaj Jun 22 '15 at 09:31
  • I have one more doubt. i have home screen with navigation drawer . suppose i am in second fragement i am getting notification. if i tap that notificaition it should redirect to The FirstFragement . how to do that any idea?? – John Jun 23 '15 at 11:47
  • 3
    As of API v21 `ActivityManager.getRunningTasks` is deprecated, so this solution should not be used anymore. – wvdz Dec 10 '15 at 12:08
  • This is depcreated. – cesards Nov 25 '16 at 10:47
2

Kotlin

 fun isAppRunning(context: Context, packageName: String): Boolean {
    val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    val procInfos = activityManager.runningAppProcesses
    if (procInfos != null) {
        for (processInfo in procInfos) {
            if (processInfo.processName == packageName) {
                return true
            }
        }
    }
    return false
}
murgupluoglu
  • 6,524
  • 4
  • 33
  • 43
  • Really nice solution, it works perfectly and it's better than the accepted answer, because the as of API v21 ActivityManager.getRunningTasks is deprecated, as mentioned by @wvdz. – Alexander Cavalheiro Becker Jun 19 '19 at 19:04