20

In Android N while using split screen I want to launch activity in current active window when user clicks on notification, but Android N always launches activity in second window if launch by clicking on notification.

NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(this)
                        .setSmallIcon(R.drawable.notification)
                        .setAutoCancel(false)
                        .setContentTitle("Demo Title")
                        .setContentText("Demo");

Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("myIntent", "test");

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pendingIntent);

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

Notification notification = mBuilder.build();

notification.flags = Notification.FLAG_NO_CLEAR;

mNotificationManager.notify(156, notification);

When get intent than launch activity.

 Intent in = new Intent(MainActivity.this, SecondActivity.class);
 startActivity(in);

ex - I have two apps in foreground like Chrome browser in first window & Facebook in second window now I am searching something in Chrome browser, at this moment I receive notification of Gmail. Now when I click on Gmail notification than Gmail app open in second window by replacing Facebook but I want that my app notification replace Chrome(whom with user interact) in first window.

Pravin Divraniya
  • 4,223
  • 2
  • 32
  • 49
Nikhil
  • 1,023
  • 17
  • 35
  • It shouldn't happen, as far as this code goes. Are you sure you are not setting anything in `AndroidManifest.xml`? Android does not start Activities in separate tasks (and a separate window is a separate task) unless specifically told to do so with flags like `FLAG_ACTIVITY_NEW_TASK` and `FLAG_ACTIVITY_LAUNCH_ADJACENT` or `AndroidManifest.xml` equivalents in the `` definition. – Nohus Sep 22 '16 at 01:06
  • @Nohus Yes i am sure i am not setting anything in AndroidManifest.xml that effect this. Its not happen only with my app any app like Gmail, Whatsapp etc whenever i click on notification on these apps than these apps also open in second window in split screen in Android N instead of current active window(While i am interacting with first window that is active window). – Nikhil Sep 22 '16 at 05:49
  • Strange, I just checked two apps and both open activities from notifications in the same window they are already open in. Maybe this is something specific to your device, did you see if that happens on another device or the emulator? – Nohus Sep 22 '16 at 12:23
  • @Nohus- Ohh i think i miss it to define here that my app in background and two different apps running in foreground in split view. ex - i have two apps in foreground like Chrome browser in first window & Facebook in second window now i am searching something in chrome browser, at this moment i receive notification of gmail. Now when i click on gmail notification that gmail open in second window by replacing Facebook but i want that my app notification replace Chrome(whom with user interact) in first window. – Nikhil Sep 22 '16 at 12:42
  • Both in horizontal and vertical multi-window my notifications open in the active window, the one I interacted with most recently. If you scroll around in Chrome and then tap the notification, it still opens in the other window? – Nohus Sep 22 '16 at 12:53
  • Yes, i am checking it on Nexus 7 & Nexus 6P. It always open in second window. No matter i am working on first window or second window. – Nikhil Sep 22 '16 at 13:06
  • Where is the notification sent, since you say it is sent in the background, is there a `Service` that sends it? – Nohus Sep 22 '16 at 13:34
  • Yes notification send by service. – Nikhil Sep 22 '16 at 13:36
  • Are you using android:gravity="top" in attribute of tag? – Pravin Divraniya Sep 27 '16 at 09:13
  • @PravinDivraniya I am talking about Split screen in Andorid N. Do you think its work here? – Nikhil Sep 27 '16 at 09:55
  • Yes I know that you are talking about Split screen in Android N and I am also talking in same context. Refer this link for more info about what am I asking and check 'Layout attributes' section. https://developer.android.com/guide/topics/ui/multi-window.html#configuring – Pravin Divraniya Sep 27 '16 at 10:04
  • @PravinDivraniya I appreciate your help, i tried this but its not work for me. – Nikhil Sep 27 '16 at 10:29
  • You must be one of the 0.x% of users who'd like the app they're currently interacting with replaced by an app opened from notification. What's the reasoning behind this? – Eugen Pechanec Sep 27 '16 at 11:15
  • @EugenPechanec : my point is that why activity always open in second window? Why not developer choose in which window he want to open his activity? Also if i am currently interacting with app opened in second window that will replaced, why not similar behaviour with first window? – Nikhil Sep 27 '16 at 11:28
  • I have a same problem with your post. I send notification from service, when i tap on notification on notification panel, new activity is opened on 2nd window. Did you find any solution to fix it ? – Zappy.Mans Nov 14 '17 at 08:17

3 Answers3

5

You cannot

specify in an Intent to start an Activity in a task your app is not a part of, which includes multi-window windows of other apps.

There are a few possible scenarios:

  1. You start an Activity from another Activity, it will be started in the previous Activity's task (and window).
  2. You can include the Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT flag in the intent, with the Intent.FLAG_ACTIVITY_NEW_TASK flag to start the Activity in another window. This will only work if the system is already in multi-window mode and is not guaranteed. If the system is in freeform mode (as opposed to split-screen) this requests to start the Activity in another free floating window, then you can also specify it's size with .setLaunchBounds().
  3. You start an Activity from a Service, since a Service cannot be in a task, you must specify the Intent.FLAG_ACTIVITY_NEW_TASK flag, and the system starts a new task for the Activity.
  4. You start an Activity from a Notification (PendingIntent), like you do:
    • You can make the Intent go to an Activity that is already started and do whatever you want in it. For example start the Activity in another window with Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT.
    • If there are no tasks/windows with your Activities, the system will choose where to start it, and you cannot control that. You can control where to start you Activity in freeform mode with .setLaunchBounds(), but you cannot hijack the window of another app like you want to do.

In short: You can either create new windows, or change existing windows you have, you cannot take windows from other apps.

But if you insist

on controlling which side of the screen your new Activity will occupy in split-screen multi-window, then create a new dummy Activity. Instead of starting your SecondActivity start the dummy Activity. In it, check which side of the screen it was started on. One way I can think of now is to call .getGlobalVisibleRect() on a View and see how the values compare to the entire screen size. You can get the screen size this way:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

You can also adapt this solution of detecting the keyboard size to detect the location of your window. It's even more hacky though.

Now if you are on the desired screen side, start your SecondActivity normally, and finish() the dummy one. If you are on the wrong one, the also use the Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT flag and your Activity will start on the side you want, while the dummy Activity disappears.

This is a dirty hack. I would recommend just letting the system choose where to start your activity.

If you always want to replace an opened browser

then make the browser open your app and it will occupy it's task (and window). You can do that by opening a link with an Intent, which the browser will handle, and from there redirect to a link that opens your app, see Handling App Links and Enabling Deep Links for more information on how to do that. It should work.

Community
  • 1
  • 1
Nohus
  • 739
  • 8
  • 16
  • 1
    I find an app that do what i want, https://play.google.com/store/apps/details?id=com.safeincloud&hl=en app shows notification on chrome browser when Auto-fill ON & replace Chrome browser always either Chrome in first window or second window. I also want to do that but don't know how?? – Nikhil Sep 22 '16 at 15:17
  • -As per you say "Now if you are on the desired screen side" but unable to understand how to know which one is current active window because my desire screen is current active screen. – Nikhil Sep 23 '16 at 09:37
  • When you check the global coordinates of a View and they are smaller than half of the screen size then your Activity is on the left, otherwise it's on the right. That's for landscape, when that works same thing goes with up and down for portrait. – Nohus Sep 24 '16 at 10:33
  • I don't think you can detect the current active window, maybe with some accessibility API's, like I said the system already starts new windows on the active side of the screen. This is unusual if that doesn't happen for you. – Nohus Sep 24 '16 at 10:41
  • User should have full control whether he wants to open an activity in first window or second. It depends on their logic. User decides the scenario. There should be no need for hacks. – M. Usman Khan Nov 27 '19 at 16:47
2

Could you check below code :

private void Notify(String notificationMessage, String pushFullMessage) {

    Intent intent = new Intent(this, GCMNotificationActivity.class);
    intent.putExtra("pushNotification", pushFullMessage);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    final int not_nu = generateRandom();
    PendingIntent pendingIntent = PendingIntent.getActivity(this,
            not_nu, intent, PendingIntent.FLAG_ONE_SHOT);


    android.support.v4.app.NotificationCompat.Builder notificationBuilder = new android.support.v4.app.NotificationCompat.Builder(
            this)
            .setSmallIcon(R.drawable.app_logo) //Small Icon from drawable
            .setContentTitle(this.getString(R.string.app_name))
            .setContentText(notificationMessage)
            .setAutoCancel(true)
            .setLocalOnly(true)
            .setColor(this.getResources().getColor(R.color.green))
            .setStyle(
                    new android.support.v4.app.NotificationCompat.BigTextStyle().bigText(notificationMessage))
//       .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.drawable.ic_launcher)) //Big Icon from drawable
            .setContentIntent(pendingIntent);


    notificationBuilder.setPriority(Notification.PRIORITY_HIGH);
    notificationBuilder.setDefaults(Notification.DEFAULT_SOUND);
    notificationBuilder.setVibrate(new long[]{0, 100, 200, 300});

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

    notificationManager.notify(not_nu, notificationBuilder.build());
}

public static int generateRandom() {
    Random random = new Random();
    return random.nextInt(9999 - 1000) + 1000;
}
Shaishav Jogani
  • 2,111
  • 3
  • 23
  • 33
Prithiv Dharmaraj
  • 357
  • 2
  • 4
  • 17
1

You cannot use Activities for this functionality...

Solution is Use Fragments instead of activities...

just replace the fragments whenever you want

Rajappa R
  • 31
  • 2
  • 14