【问题标题】:How Do We Leave Picture-In-Picture Mode?我们如何离开画中画模式?
【发布时间】:2017-08-27 17:19:54
【问题描述】:

我们有 enterPictureInPictureMode() 将活动从其当前形式移动到画中画表示。

除了销毁 Activity 之外,我们通过什么方式恢复它,将 Activity 恢复到其正常状态? Activity 上没有 exitPictureInPictureMode()leavePictureInPictureMode()janeGetMeOffThisCrazyPictureInPictureModeThing() 方法,并且文档似乎没有涵盖替代方法。

我对适用于 Android O 的解决方案感兴趣,该解决方案适用于移动设备上的画中画模式,不过如果它也适用于 Android TV,那就太好了!

更新 2017-04-08:如果您想要在用户单击 X 按钮退出画中画模式时返回正常模式,您可以执行以下操作:

  @Override
  public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
    super.onPictureInPictureModeChanged(isInPictureInPictureMode);

    if (!isInPictureInPictureMode) {
      getApplication().startActivity(new Intent(this, getClass())
        .addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT));
    }
  }

关键位是调用startActivity() 以使用FLAG_ACTIVITY_REORDER_TO_FRONT 再次启动当前活动。对于singleTask 活动,您需要在一些非Activity 上下文中调用它,例如Application 单例。这似乎不会触发onStop()onStart(),但它会触发onNewIntent()(无论您传递给Intent 的任何startActivity())。

【问题讨论】:

  • 您是否遵循Using a Single Playback Activity for PIP 的建议?
  • @ianhanniballake:是的。不过,这并不能解决我的担忧。我不想切换内容。我只想将内容扩展回其原始大小,而不会中断正在发生的事情。例如,用户决定进入画中画模式,发现视频太小,想再次展开。
  • 是的,没有像你提到的那样的方法。我在画中画中工作不多,但您可以使用onPictureInPictureModeChanged 来追踪正常和画中画模式切换事件。
  • 好问题,让我参观了 -- Multiwindow support 提到了电视上的画中画和手持设备的分屏,同义词.. 另外,我只是想知道,简不会发疯如果 tom、dick 和 harry 开发的应用程序相互压制对方强迫/滥用 janeEscapeLoopPiP,那么.. 可能将这部分留给用户输入/操作会更好。当用户在会议中时,这听起来像是向电话 api 提供“disconnectCall”方法
  • @CommonsWare 祝您问题得到解决。

标签: android android-8.0-oreo android-picture-in-picture


【解决方案1】:

Official documentation 表示 PIP 窗口带有菜单,可让您切换到全屏。

PIP 窗口为 240x135 dp,显示在最顶层 屏幕的四个角,由系统选择。用户可以 调出 PIP 菜单,让他们将 PIP 窗口 切换到 全屏,或关闭 PIP 窗口,方法是按住 Home 按钮 在遥控器上。如果另一个视频开始在主屏幕上播放,则 PIP 窗口会自动关闭。

并且您可以在用户切换 PIP 模式时覆盖 PIP 更改事件以处理 UI 元素。

link to onPictureInPictureModeChanged

@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
    if (isInPictureInPictureMode) {
        // Hide the controls in picture-in-picture mode.
        ...
    } else {
        // Restore the playback UI based on the playback status.
        ...
    }
}

【讨论】:

  • 这似乎是电视的说明。在 Android O 手机 (Nexus 5X) 上,有一个关闭按钮,它会破坏活动。没有遥控器。长按窗口可以移动它。似乎没有用户可访问的方法将活动恢复到正常模式。这些都没有表明我如何以编程方式离开 PiP 模式,这是这个问题的核心。不过谢谢!
【解决方案2】:

我认为 Activity 无法决定退出画中画模式。

来自Android O API preview doc

进入 PIP 模式的活动进入暂停状态,但仍处于启动状态。如果用户点击 PIP 活动,系统会显示一个菜单供用户交互;处于 PIP 状态时,没有触摸事件到达 Activity。

活动将通过onPictureInPictureModeChanged()通知。

【讨论】:

  • 注意:我在 Google 工作(虽然不是在 Android 中),也找不到任何关于 janeGetMeOffThisCrazyPictureInPictureModeThing() 或类似方法的电话。
  • 活动应该能够离开画中画模式:只需finish()活动并创建一个新实例。即使有转换,这也可能导致 UI 打嗝,我希望我们有一个 API 可以避免这种情况。不过谢谢!
  • 我真的不认为销毁/重新创建实例与更改模式相同。
  • @GustavoForeroCarvajal:Google 拒绝了这个功能请求,而且我已经有几年没有玩过画中画了,所以我不知道有没有出现。对不起!
【解决方案3】:
  1. 将活动移到后面

    activity.moveTaskToBack(false /* nonRoot */);
    
  2. 将活动恢复到最前面

    Intent startIntent = new Intent(PipActivity.this, PipActivity.class);
    startIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    activity.startActivity(startIntent);
    

【讨论】:

  • 这种模式似乎是用于多窗口的。希望这有帮助,我无法尝试自己,因为我所有的模拟器图像都失败了“IllegalStateException:enterPictureInPictureMode:设备不支持画中画模式”......
  • 这太狡猾了!不幸的是,我很难让moveTaskToBack() 工作。 PiP 活动是singleTask(根据文档)。 moveTaskToBack() 似乎影响了应用程序的原始任务,而不是画中画活动的任务。我也可能需要do this hack。我会继续戳这个,因为你的方法似乎很有希望。谢谢!
  • 我刚刚尝试了这个解决方案,并调用了onDestroy(),因此它没有回答你的问题。实际上它被调用了两次:一次在 enterPictureInPicture 中,一次在启动意图时,尽管 singleTask 和 FLAG_ACTIVITY_REORDER_TO_FRONT。
  • 我给予这个答案赏金,因为它最接近有一个解决方案。我不接受它,因为它不是真正的解决方案。 :-) 再次感谢!
【解决方案4】:

我找到了一种 100% 可靠的方法。

  1. 将清单中 PIP 活动的 taskAffinity 属性设置为类似于“com.package.pip”的内容。没关系,它只需要与您的包名称不同,这是默认的任务关联。这将导致它在一个完全独立的堆栈中启动,就好像它完全是另一个应用程序一样。
  2. 只要您想退出 PIP,请在另一个活动中使用 startActivity(new Intent(this, PipActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)) 启动它。

我只是查看了当应用程序的主要活动当前处于 PIP 模式时会发生什么,并且您从启动器启动它并认为我可以复制这一点,我确实可以。

【讨论】:

    【解决方案5】:

    我遇到了同样的问题:

    • MainActivity 打开已启用 PIP 模式的 VideoPlayerActivity
    • 按返回按钮进入 PIP 模式。
    • 再次按返回按钮,直到我退出 MainActivity
    • 按 PIP 窗口上的关闭 (X) 按钮。
    • 打开应用程序,它将打开VideoPlayerActivity

    虽然上述解决方案都不适合我,但我发现收听X 按钮的唯一方法是覆盖onStop

    当活动从 PIP 恢复时,onResumeonPictureInPictureModeChanged 被调用,当X 按钮被点击时,onStoponPictureInPictureModeChanged 被调用。

    所以当onStop 已经被调用时,我尝试在onPictureInPictureModeChanged 中调用finish()

    override fun onStop() {
        super.onStop()
        onStopCalled = true
    }
    
    override fun onResume() {
        super.onResume()
        onStopCalled = false
    }
    
    override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration) {
            if (isInPictureInPictureMode) {
                // ...
            } else {
                if (onStopCalled) {
                    finish()
                }
            }
        }
    

    【讨论】:

    • 是否保证onStop方法会在onPictureInPictureModeChanged 之前被调用?不知何故,在某些设备(使用 android 8 和 9)中,onPictureInPictureModeChangedonStop 之前被调用,从而阻止我们完成活动。这几天我一直在为此苦苦挣扎。
    猜你喜欢
    • 2022-12-16
    • 2020-03-17
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    • 2020-07-07
    • 2015-07-10
    • 1970-01-01
    • 2019-06-24
    相关资源
    最近更新 更多