Android N:如何在分屏时单击通知时在当前活动窗口而不是第二个窗口中启动活动?

Nik*_*hil 19 android android-intent android-notifications split-screen android-7.0-nougat

在Android N使用分屏时,我希望activity在用户点击通知时在当前活动窗口中启动,但如果通过单击通知启动,则Android N始终activity在第二个窗口中启动.

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);
Run Code Online (Sandbox Code Playgroud)

什么时候intent比发射activity.

 Intent in = new Intent(MainActivity.this, SecondActivity.class);
 startActivity(in);
Run Code Online (Sandbox Code Playgroud)

前 - 我在前台有两个应用程序,如第一个窗口中的Chrome浏览器和第二个窗口中的Facebook,现在我在Chrome浏览器中搜索某些内容,此时我收到了通知Gmail.现在当我点击Gmail通知而不是通过替换Facebook在第二个窗口中打开Gmail应用程序但我希望我的应用程序通知在第一个窗口中替换Chrome(与用户交互的用户).

Noh*_*hus 5

你不能

指定在Intent您的应用程序不属于的任务中启动活动,其中包括其他应用程序的多窗口窗口。

有几种可能的情况:

  1. 您从另一个 Activity 启动一个 Activity,它将在前一个 Activity 的任务(和窗口)中启动。
  2. Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT您可以在意图中包含该标志,并使用该Intent.FLAG_ACTIVITY_NEW_TASK标志在另一个窗口中启动活动。仅当系统已处于多窗口模式时这才有效,并且不能保证。如果系统处于自由格式模式(而不是分屏模式),则此请求在另一个自由浮动窗口中启动 Activity,那么您还可以使用.setLaunchBounds()指定其大小。
  3. 你从一个Service启动一个Activity,由于Service不能在一个task中,所以你必须指定flag Intent.FLAG_ACTIVITY_NEW_TASK,系统会为这个Activity启动一个新的task。
  4. 您可以从通知(PendingIntent)启动一个活动,就像您所做的那样:
    • 您可以转到Intent已启动的活动并在其中执行您想要的任何操作。例如,使用 启动另一个窗口中的活动Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT。
    • 如果您的活动没有任务/窗口,系统将选择从哪里启动它,您无法控制它。您可以使用 来控制在自由形式模式下启动 Activity 的位置.setLaunchBounds(),但您无法像您想要的那样劫持另一个应用程序的窗口。

简而言之:您可以创建新窗口,或更改现有窗口,您不能从其他应用程序获取窗口。

但如果你坚持

控制您的新 Activity 将在分屏多窗口中占据屏幕的哪一侧,然后创建一个新的虚拟 Activity。而不是开始启动SecondActivity虚拟活动。在其中,检查它是在屏幕的哪一侧启动的。我现在能想到的一种方法是在a上调​​用.getGlobalVisibleRect()View并查看这些值与整个屏幕尺寸的比较情况。您可以通过以下方式获取屏幕尺寸:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Run Code Online (Sandbox Code Playgroud)

您还可以采用这种检测键盘尺寸的解决方案来检测窗口的位置。但它更hacky。

现在,如果您位于所需的屏幕一侧,请启动SecondActivity正常屏幕和finish()虚拟屏幕。如果您走错了,也可以使用该Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT标志,您的活动将在您想要的一侧启动,而虚拟活动将消失。

这是一个肮脏的黑客行为。我建议让系统选择从哪里开始您的活动。

如果您总是想更换打开的浏览器

然后让浏览器打开您的应用程序,它将占用它的任务(和窗口)。您可以通过打开带有 的链接来实现此目的Intent,浏览器将处理该链接,然后从那里重定向到打开您的应用程序的链接,请参阅处理应用程序链接和启用深层链接以获取有关如何执行此操作的更多信息。它应该有效。