isActivityStartAllowedOnDisplay()方法

时间:2019-06-06 16:32:24

标签: android android-activitymanager

我正在尝试在辅助显示器上启动第二个活动。在模拟器上可以正常工作,但是我需要辅助显示器来处理触摸事件。

使用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很有帮助,但是,有什么解决方法吗?也许我误解了文档,但似乎如果该设备不支持它,那将无法解决。是否有人知道不会抛出此安全异常的任何显示?

1 个答案:

答案 0 :(得分:0)

为了获取触摸事件以在辅助显示器(GeChic触摸显示器)上注册,我在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(),并且对point.y和point.x值进行了修改,其像素宽度或高度与Android手机/平板电脑的像素宽度或高度不匹配。 displayId()并非始终是一个一致的值,在Android Q中“应该”是稳定的。这是应用程序崩溃且第二个活动因安全权限错误而失败的地方。因此,我使用Android Q Beta测试了新的isActivityStartAllowedOnDisplay()API。我通过Android Studio在手机(运行Android Q Beta OS的手机)上运行它来运行它,并且毫不奇怪,辅助显示返回了false。参见下面的代码:

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命令,我能够在辅助显示器上获得辅助活动!它似乎正在工作!但是,不是,不是...触摸事件仍然继续起作用,就像正在镜像设备一样,因此这仍然是一个问题,无法正常工作。

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

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

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

将来,将会有具有多显示器的仿真器来更好地测试多显示器应用程序,但目前尚不可用。