如何检测系统对话框是否显示在活动之上?

问题描述 投票:0回答:1

我正在开发一个显示视频内容的应用程序,当用户按下主页按钮时,我们支持 PiP(画中画)模式。正如文档所建议的,我们在 onUserLeaveHint() 方法中触发 pip 模式。

 protected void onUserLeaveHint() {
     super.onUserLeaveHint();
     enterPipMode();
}

我们目前遇到的问题是,出现在视频内容 Activity 顶部的任何系统对话框(例如将手机连接到计算机时的权限对话框、允许 USB 调试)都会调用 onUserLeaveHint()。我知道当您切换到另一个活动时会调用此方法,并且系统对话框在大多数情况下是不同的活动。

所以问题是:我们如何检测当前正在显示系统对话框?

我环顾四周,但没有找到任何适合我的解决方案。

到目前为止,我尝试了不同的方法来获取可用于防止在存在对话框的情况下调用 EnterPipMode() 的标志,但目前我没有找到涵盖所有系统的可靠解决方案对话框和用例。

我尝试过的事情:

  • 使用 ActivityManager
       .getSystemService(Activity.ACTIVITY_SERVICE);
    String className = activityManager.getRunningTasks(1).get(0).topActivity.getClassName();
  • 检测活动焦点
override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        if (!hasFocus) {
            //todo your logic
        }
    }
  • BroadCastReceiver 监听手机被插入的事件
    private BroadcastReceiver mPowerConnectionReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
                if (action.equals(Intent.ACTION_POWER_CONNECTED)) {
                    booleanFlag = true;
                } else if (action.equals(Intent.ACTION_POWER_DISCONNECTED)) {
                    booleanFlag = false;
                }
            }
        }
    };

或者类似的东西

    public boolean isConnected() {
        Intent intent = this.registerReceiver(
                null,
                new IntentFilter("android.hardware.usb.action.USB_STATE")
        );
        if (intent != null && intent.getExtras() != null) {
            return intent.getExtras().getBoolean("adb") ||
                    intent.getExtras().getBoolean("connected");
        } else {
            return false;
        }
    }

还尝试通过反射来获取它。

只有 BroadCastReceiver 的方法给出了一些结果,但没有好的方法来知道何时清除标志,并且在设备连接时没有画中画模式,并且我们没有涵盖所有可能的系统对话框。

我可以看到 Google 地图有画中画,并且运行良好:)

如果需要任何其他信息,请告诉我。 谢谢!

android
1个回答
0
投票

因此,经过几天尝试不同的方法,我成功地获得了我需要的行为 - 仅当用户点击主页按钮时才看到 Pip。这与问题中的原始方法有点不同,但希望它可以帮助某人。

我添加了一个接收器来侦听主页按钮事件,如此处所述,以及一个检查用户是否仍在同一活动中的函数。

    private final BroadcastReceiver homeButtonClickReceiver = new BroadcastReceiver() {
    final String SYSTEM_DIALOG_REASON_KEY = "reason";
    final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
            String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
            if (reason != null) {
                if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
                    shouldEnterPip = isInVideoScreenActivity();
                }
            }
        }
    }
};

private boolean isInVideoScreenActivity() {
    ActivityManager manager = (ActivityManager) this.getSystemService(Activity.ACTIVITY_SERVICE);
    final List<ActivityManager.AppTask> appTasks = manager.getAppTasks();
    final ComponentName componentName = appTasks.get(0).getTaskInfo().topActivity;
    final String className;
    if (componentName != null) {
        className = componentName.getClassName();
        Toast.makeText(this, "onReceive(): " + className, Toast.LENGTH_SHORT).show();
        return className.equals(VideoScreenActivity.class.getName());
    } else {
        return false;
    }
}

我使用shouldEnterPip标志来确定是否应该打开PiP,每次进入PiP模式时,我们都会清除该标志以避免一些不需要的行为。

 @Override
 protected void onUserLeaveHint() {
    super.onUserLeaveHint();
    if (shouldEnterPip) {
        enterPipMode();
        shouldEnterPip = false;
   }
 }

就是这样。让我知道这个解决方案有哪些缺陷以及是否有更好的方法来解决这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.