Android 12 画中画问题

Android 画中画
在Android 12 系统的手机(oppo 小米),home进入画中画,然后在恢复全屏模式,然后点击界面上其他按钮打开新界面,会出现 startActivity新的界面会延迟好久 或者 打不开新界面的情况。
按照官方文档使用安卓12的.setAutoEnterEnabled(true)依然不管用;
跳转不了、或者延迟、好像新页面在当前界面下面,因为home或者旋转屏幕后就打开了。
奇怪的是非home,手动调用enterPictureInPictureMode,就没有这个问题。貌似和home有关系。

大概代码如下


 Button btn_floating_open2 = findViewById(R.id.btn_floating_open2);
        btn_floating_open2.setOnClickListener(v -> {
            Intent intent = new Intent(FloatingActivity.this, TestActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
            FloatingActivity.this.startActivity(intent);
        });

  @Override
    protected void onUserLeaveHint() {
        super.onUserLeaveHint();
        enterPiPMode();
    }

 private void enterPiPMode() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//            videoPlayer.setIsInPictureInPictureMode(true);
            if (mPictureInPictureParamsBuilder == null) {
                mPictureInPictureParamsBuilder = new PictureInPictureParams.Builder();
            }
            // Calculate the aspect ratio of the PiP screen. 计算video的纵横比
            int mVideoWith = videoPlayer.getWidth();
            int mVideoHeight = videoPlayer.getHeight();
            if (mVideoWith != 0 && mVideoHeight != 0) {
                //设置param宽高比,根据宽高比例调整初始参数
                Rational aspectRatio = new Rational(mVideoWith, mVideoHeight);
                mPictureInPictureParamsBuilder.setAspectRatio(aspectRatio);
            }
            //进入pip模式
            enterPictureInPictureMode(mPictureInPictureParamsBuilder.build());
        }
    }

1、可以试试在恢复全屏模式之前退出画中画模式。可以在应用程序的主活动中重写onStop()方法,并使用isInPictureInPictureMode()方法来检查下当前是否处于画中画模式,如果是,就退出画中画模式。

2、也可以试试其他解决方案,比如使用其他方法来启动新界面,例如使用FragmentTransaction来替换当前的Fragment,或者使用Intent.FLAG_ACTIVITY_NEW_TASK标志来启动新的任务栈。

3、还可以试试使用setAutoEnterEnabled(true)方法来自动进入画中画模式,这样在用户将应用程序置于后台时,它就会自动进入画中画模式。但是需要确保应用程序满足所有画中画模式的要求,例如提供可见且有意义的内容,并且没有较高的 CPU 使用率。

4、另外如果发现非 home 状态下手动调用enterPictureInPictureMode没有出现问题,那么这可能是因为在 home 状态下调用enterPictureInPictureMode时可能会有其他应用程序在后台运行,导致应用程序受到较低的 CPU 优先级的限制。可以试试在 home 状态下停止其他应用程序的运行,然后再调用enterPictureInPictureMode,看看是否会有所改善。
望采纳。

看下这个实例讲解:https://developer.android.google.cn/guide/topics/ui/picture-in-picture?hl=zh-cn

在 Android 12 系统中,当你从画中画模式进入新界面时,如果新界面未立即显示或无法打开,可能是因为新界面的显示被暂时延迟。这是因为在 Android 12 中,画中画模式的行为发生了变化。

为了解决这个问题,你可以尝试使用 setAutoEnterEnabled(true) 方法来启用自动进入画中画模式。这个方法会自动在你的应用程序进入画中画模式时启动新界面。你可以在启动新界面之前使用这个方法,例如:

Intent intent = new Intent(FloatingActivity.this, TestActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    intent.setAutoEnterPictureInPicture(true);
}
FloatingActivity.this.startActivity(intent);


另外,你也可以使用 setPictureInPictureParams(params) 方法来设置新界面的画中画参数。这个方法可以让你自定义新界面在画中画模式下的显示方式,例如设置画中画窗口的大小和位置。你可以在启动新界面之前使用这个方法,例如:

Intent intent = new Intent(FloatingActivity.this, TestActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    PictureInPictureParams params = new PictureInPictureParams.Builder().build();
    intent.setPictureInPictureParams(params);
}
FloatingActivity.this.startActivity(intent);


谢谢大家的回复,昨天在外网搜到解决方式,不过不理解为啥这么处理。
应该是Android12谷歌的bug;
地址:https://issuetracker.google.com/issues/207397151
解决方式地址:https://github.com/limdale/PipTest/commit/ed49df5f8730946da472d85da76468687606692c
解决思路

class MainActivity : AppCompatActivity(), ServiceConnection {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        binding.buttonVideo.setOnClickListener {
            startActivity(Intent(this, VideoActivity::class.java))
        }
        Intent(this, TestService::class.java).also { intent ->
            startService(intent)
            bindService(intent, this, Context.BIND_AUTO_CREATE)
        }
    }

    override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
        // do nothing
    }

    override fun onServiceDisconnected(name: ComponentName?) {
        // do nothing
    }
}
import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder

class TestService : Service() {
    override fun onBind(intent: Intent?): IBinder {
        return TestServiceBinder()
    }

    inner class TestServiceBinder : Binder() {
        fun getService() = this@TestService
    }
}

        <service android:name=".TestService" />