0

我正在尝试在辅助显示器上启动第二个活动。这在模拟器上运行良好,但我需要辅助显示器来处理触摸事件。

使用 Android Pie,在第二个显示器上启动活动会引发安全异常。Google 最近推出了适用于 Android Q 的新 API - isActivityStartAllowedOnDisplay() ( https://developer.android.com/reference/android/app/ActivityManager.html#isActivityStartAllowedOnDisplay(android.content.Context,%2520int,%2520android.content .Intent) ) - 能够判断第二个显示器是否有此安全异常。

这个新的 API 很有帮助,但是,有什么办法可以解决吗?也许我误解了文档,但似乎如果设备不支持它,那么就没有办法解决它。有谁知道任何不会引发此安全异常的显示器?

4

1 回答 1

1

为了让触摸事件在辅助显示器(GeChic Touch Monitor)上注册,我在 Android 设备和触摸显示器之间连接了一个 DisplayLink 设备。此时,它正在镜像手机/平板电脑上的视图,但会处理触摸事件。因此,我编写了一个应用程序,该应用程序将尝试在 Android Pie OS 上使用以下代码在第二个显示器上启动第二个活动:

DisplayManager mgr = (DisplayManager) this.getBaseContext().getSystemService(Context.DISPLAY_SERVICE);

if (mgr != null) {
    Display[] displays = mgr.getDisplays();

    for (int i = 0; i < displays.length; i++) {
        Display display = displays[i];
        Point point = new Point();
        display.getSize(point);

        if (point.y == PX_HEIGHT_OF_SECONDARY_DISPLAY || point.x == PX_HEIGHT_OF_SECONDARY_DISPLAY) {
            Context displayContext = createDisplayContext(display);
            Intent newIntent = new Intent(displayContext, ActivityCID.class);

            ActivityOptions options = ActivityOptions.makeBasic();
            options.setLaunchDisplayId(display.getDisplayId());
            newIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(newIntent, options.toBundle());
            return;
        }
    }
}

请注意,我没有使用 display.getDisplayId() 并且对像素宽度或高度与 Android 手机/平板电脑的像素宽度或高度不匹配的 point.y 和 point.x 值做了一个hacky方式。displayId() 并不总是一个一致的值,“应该”在 Android Q 中是稳定的。这是应用程序崩溃的地方,第二个活动将失败并出现安全权限错误。因此,我使用 Android Q Beta 来测试新的 isActivityStartAllowedOnDisplay() API。我通过 Android Studio 将它运行到手机(在 Android Q Beta OS 上)运行它,毫不奇怪,辅助显示返回错误。请参见下面的代码:

public void launchOnSecondaryDisplay(Display display) {

    Context displayContext = createDisplayContext(display);
    Intent newIntent = new Intent(displayContext, ActivityTest.class);

    ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Activity.ACTIVITY_SERVICE);
        if (activityManager != null) {
            boolean allowsDisplay = activityManager.isActivityStartAllowedOnDisplay(displayContext, display.getDisplayId(), newIntent);

            if (allowsDisplay) {
                ActivityOptions options = ActivityOptions.makeBasic();
                options.setLaunchDisplayId(display.getDisplayId());
                newIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(newIntent, options.toBundle());
            } else {
                Toast.makeText(this, "Cannot start activity on that display as it is not supported.", Toast.LENGTH_LONG).show();
            }

        }
    }

我决定通过命令行尝试一下。在将物理设备联网以匹配我的 Mac 连接的网络后,我能够无线连接到手机并能够在 adb 中进行更改。使用 adb 命令,我能够在辅助显示器上获得辅助活动!它似乎工作了!但是不,它不是......触摸事件仍然继续像设备被镜像一样,所以这仍然是一个问题并且无法正常工作。

我也与 Google 员工讨论过这个问题,并解释说 adb root 可以覆盖这些权限。但是,仍然没有办法让触摸事件映射到辅助显示器上的第二个活动。

在撰写本文时,测试多点触控显示器的唯一受支持方法是使用运行 Android Q Beta 的物理设备并按照以下步骤操作:

  1. 启用开发者选项,
  2. 在开发人员选项中,启用这 4 个选项:强制所有活动可调整大小、自由格式 Windows、强制桌面和模拟辅助显示(无论选择哪个选项来模拟辅助显示),
  3. 重启设备,
  4. 将鼠标连接到设备。鼠标将出现并卡在“模拟辅助显示器”的覆盖窗口内。这将处理触摸事件。

将来会有多显示器的模拟器来更好地测试多显示器应用程序,但目前还没有。

于 2019-06-26T19:00:14.213 回答