10

I have try all the methods but it doesn't work for me. i want to open or resume app with whatever screen open while click on notification.

I used following method:

NotificationCompat.BigTextStyle notiStyle = new NotificationCompat.BigTextStyle();
        notiStyle.setBigContentTitle(team);
        notiStyle.bigText(message);

        Intent resultIntent = new Intent(this, MainDrawerActivity.class);
        resultIntent.putExtra("fromNotification", "notification");

        resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_SINGLE_TOP);


        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);



        stackBuilder.addNextIntent(resultIntent);


        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
                PendingIntent.FLAG_UPDATE_CURRENT);

        int icon = R.mipmap.ic_launcher;


        return new NotificationCompat.Builder(this).setSmallIcon(icon)
                .setAutoCancel(true)

                .setContentIntent(resultPendingIntent).setContentTitle(team)
                .setContentText(message).setStyle(notiStyle).build(); 
Rajesh Satvara
  • 3,842
  • 2
  • 30
  • 50
sunil
  • 796
  • 1
  • 8
  • 28

7 Answers7

17

To raise your application to the foreground without starting any new activity, fire its launcher intent.

This method is from an old project of mine.

/**
 * Creates a new launcher intent, equivalent to the intent generated by
 * clicking the icon on the home screen.
 *
 * @return the launcher intent
 */
public static Intent newLauncherIntent(final Context context) {
    final Intent intent = new Intent(context, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_LAUNCHER);
    return intent;
}

The intent created by this method does not start a new task if the app is running, even though it has that flag.

This is another way to obtain a launcher intent. However, I found that this intent would always start a new task, which is not what you want if the app is running.

final Intent intent = context.getPackageManager()
        .getLaunchIntentForPackage(BuildConfig.APPLICATION_ID);
Kevin Krumwiede
  • 9,868
  • 4
  • 34
  • 82
  • Thank you so much, you saved my day.it is working fine. – sunil Dec 20 '16 at 05:38
  • While app is in background then only app open and remain on screen . but while app is in foreground then app get relaunch again. but i don't want to relaunch. simply dismiss that notification from status bar. what i need to do? – sunil Dec 20 '16 at 05:59
  • @sunil I didn't encounter that, but I'm also not 100% sure I tested that scenario. I'll look into it. – Kevin Krumwiede Dec 23 '16 at 19:26
  • i am using this, (it is working with running the app through run button) and i thought it is working but somehow when i try to run/install the apk i build from Build > Build Apk menu, i am having a different kind of result. – niczm25 Jun 29 '17 at 06:06
  • Oh, my bad this works. i have a different issue why i am having an impression does not work. it is related with [the app restarts when try to resume the app through launcher icon](https://stackoverflow.com/questions/19545889/app-restarts-rather-than-resumes). but still the intent start na new task, i works fine with the fix on the issue i stated. props to kevin.. +1.. – niczm25 Jun 29 '17 at 07:30
  • BuildConfig.APPLICATION_ID is deprecated. Better use BuildConfig.LIBRARY_PACKAGE_NAME or context.getPackageName() – Emanuel Mar 27 '20 at 11:07
  • That flags working for me – Arbaz.in Apr 21 '22 at 10:50
1

This is working fine for following three conditions:

1.if app already open and click on notification, notification should remove from status bar.

2.if app is open and in background then app should resume with whatever screen open already previously.

3.if app is close and click on notification in status bar then app should open.

private final static int NORMAL = 0x00;
private final static int BIG_TEXT_STYLE = 0x01;
private static NotificationManager mNotificationManager;

in onMessage call

mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
new CreateNotification(BIG_TEXT_STYLE, team, message).execute();

then declare following class in GCMIntentService. public class CreateNotification extends AsyncTask {

    int style = NORMAL;
    String team, message;

    public CreateNotification(int style, String team, String message) {
        this.style = style;
        this.team = team;
        this.message = message;

    }

    @Override
    protected Void doInBackground(Void... params) {
        Notification noti = new Notification();

        switch (style) {
        case BIG_TEXT_STYLE:
            noti = setBigTextStyleNotification(team, message);
            break;

        }

        noti.sound = (null);
        noti.defaults = 0;
        noti.sound = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.beep);
        noti.flags |= Notification.FLAG_AUTO_CANCEL;

        mNotificationManager.notify(0, noti);

        return null;

    }
}

and finally

private Notification setBigTextStyleNotification(String team, String message) {

    // Create the style object with BigTextStyle subclass.
    NotificationCompat.BigTextStyle notiStyle = new NotificationCompat.BigTextStyle();
    notiStyle.setBigContentTitle(team);
    notiStyle.bigText(message);


    Intent      resultIntent = getPackageManager()
            .getLaunchIntentForPackage(getPackageName());

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);

        // Adds the Intent that starts the Activity to the top of the stack.
    stackBuilder.addNextIntent(resultIntent);


    PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
            PendingIntent.FLAG_UPDATE_CURRENT);
    int icon = R.mipmap.ic_launcher;


    return new NotificationCompat.Builder(this).setSmallIcon(icon)
            .setAutoCancel(true)

            .setContentIntent(resultPendingIntent).setContentTitle(team)
            .setContentText(message).setStyle(notiStyle).build();
}
sunil
  • 796
  • 1
  • 8
  • 28
  • Is @Kevin Krumwiede method works the same way with your code, if "yes" which would you prefer, your method or his method? – niczm25 Jun 28 '17 at 15:23
  • I am using my method, Intent intent = new Intent(this, MainDrawerActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); – sunil Jun 29 '17 at 04:58
  • this flag i am using – sunil Jun 29 '17 at 04:58
  • PendingIntent pendingIntent = PendingIntent.getActivity(this, (int)System.currentTimeMillis(), intent, PendingIntent.FLAG_UPDATE_CURRENT); – sunil Jun 29 '17 at 04:59
  • i also tried the solution above with Intent resultIntent = getPackageManager() .getLaunchIntentForPackage(getPackageName());, (it is working with running the app through run button) and i thought it is working but somehow when i try to run/install the apk i build from Build > Build Apk menu, i am having a different kind of result. – niczm25 Jun 29 '17 at 06:08
1

You should have something like this in Application class to store the current activity.

private BaseActivity mCurrentActivity = null;

public BaseActivity getCurrentActivity() {
    return mCurrentActivity;
}

public void setCurrentActivity(BaseActivity currentActivity) {
    this.mCurrentActivity = currentActivity;
}

Then, inside your handle notification Service class.

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

    BaseActivity currentActivity = ((App) this.getApplicationContext())
                               .getCurrentActivity();
        Intent intent;
        if (currentActivity instanceof ActivityA) {
            intent = new Intent(this, ActivityA.class);
        } else if (currentActivity instanceof ActivityB) {
            intent = new Intent(this, ActivityB.class);
        } else {
            intent = new Intent(this, MainActivity.class);
        }

        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);

    // your code...
}

If your app is killed, default activity will be called, such as MainActivity.

Else, when you receive & click push notification message when app is on foreground or background. Current activity will stay there as default activity, such as ActivityA & ActivityB. Then you can navigate to wherever another activities or fragments.

My suggestion, better we should use Fragment, it's easier in navigate to specially screen from push notification.

Tri Ngo Minh
  • 145
  • 1
  • 9
0
//I am using write now this can possible    
  NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notification = new Notification(icon, message, when);

        Intent notificationIntent = new Intent(context, HomeActivity.class);

        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_SINGLE_TOP);

        PendingIntent intent = PendingIntent.getActivity(context, 0,
                notificationIntent, 0);

        notification.setLatestEventInfo(context, title, message, intent);
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(0, notification);
vasupujy
  • 442
  • 2
  • 11
0

make new activity

public class FinishImmediateActivity extends AppCompatActivity {
  @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    finish();
  }
}

add to manifest.xml

<activity android:name=".FinishImmediateActivity"/>

check app is running

public static boolean isMainActivityRunning() {
  ActivityManager activityManager = (ActivityManager) MyApp.getContext().getSystemService(Context.ACTIVITY_SERVICE);
  List<ActivityManager.RunningTaskInfo> tasksInfo = activityManager.getRunningTasks(Integer.MAX_VALUE);

  for (int i = 0; i < tasksInfo.size(); i++) {
    if (tasksInfo.get(i).baseActivity.getPackageName().equals(MyApp.getContext().getPackageName())) {
      return true;
    }
  }
  return false;
}

then call that activity in notification intent.

Intent resultIntent = new Intent(this, isMainActivityRunning() ? FinishImmediateActivity.class : HomeActivity.class);
Hun
  • 3,652
  • 35
  • 72
  • in which class i have to use this in main Drawer or in GCM Intent notification. – sunil Dec 20 '16 at 05:22
  • Intent resultIntent = new Intent(this, FinishImmediateActivity.class); – Hun Dec 20 '16 at 05:24
  • Grate, now app is remain on same page but while click on notification its not open. but when i click on on app icon and open then app open with previous screen. – sunil Dec 20 '16 at 05:30
  • what i need to do if i want to open app? – sunil Dec 20 '16 at 05:30
  • Please help me out. your method is working fine while app is open and click on notification, notification dismiss. only one thing i need while app is in background and click on notification, app should resume. – sunil Dec 20 '16 at 06:13
0

If you want to just resume the app state then instead of multiple activity I will suggest you just keep single activity and use Fragments for different screen.

On Notification click you need to define entry point of app in notification payload and the entry point decide what will be the next navigation.

If you are having only single activity then you can define that activity as a entry point and on the activity you can decide do you have to push new fragment or not.

Or second option if you are using firebase then push all notification as background notification and onMessageReceive method you can get top activity from activity stack and set that activity as entry point for the notification. But there is still problem as user may be click on notification after navigate from set entry point activity which again problem. So I prefer to go with first one approach.

VikasGoyal
  • 3,308
  • 1
  • 22
  • 42
  • yes, i have done same...use one activity and all other screens are fragment. – sunil Dec 20 '16 at 06:10
  • If you have single activity you should define activity as singleTask in manifest so on click of notification if your activity is in background it will call onNewIntent with new data. – VikasGoyal Dec 20 '16 at 10:36
  • Thanx, by this way it has solved Intent intent = new Intent(this, MainDrawerActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, (int)System.currentTimeMillis(), intent, PendingIntent.FLAG_UPDATE_CURRENT); – sunil Dec 21 '16 at 12:58
  • Hope you like the answer as well . – VikasGoyal Dec 22 '16 at 05:25
0

By this way also we can achieve the above result:

            try {
            int icon;

                icon = R.mipmap.ic_launcher;


        int mNotificationId = 001;


            Intent intent = new Intent(this, MainDrawerActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

            //FLAG_UPDATE_CURRENT is important
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 
 (int)System.currentTimeMillis(), intent, 
PendingIntent.FLAG_UPDATE_CURRENT);


            NotificationCompat.Builder mBuilder = new 
 NotificationCompat.Builder(
                this);
        Notification notification = 
  mBuilder.setSmallIcon(icon).setTicker(json.getString("team")).setWhen(0)
                .setAutoCancel(true)
                .setContentTitle(json.getString("team"))
                .setStyle(new 
 NotificationCompat.BigTextStyle().bigText(json.getString("message")))
                .setContentIntent(pendingIntent)
                .setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.beep))


        NotificationManager notificationManager = (NotificationManager) 
  this.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(mNotificationId, notification);




        } catch (Exception e) {
            e.printStackTrace();
        }
sunil
  • 796
  • 1
  • 8
  • 28