Android画中画(PIP)进阶---Action按钮的使用

学更好的别人,

做更好的自己。

——《微卡智享》

c84014fcfeff352537241d1560ef7353.jpeg

本文长度为1839,预计阅读5分钟

前言

上一篇《Android画中画(PIP)模式使用》介绍了画中画的使用,今天这篇来讲讲Action按钮的使用,主要是广播方式更新UI及Android 12后的兼容性问题。

9423ed60ccd577c689047c38842617d4.png

实现效果

a03c6bca79dd714d03efbb1c6275b34b.gif

ee79571ae68fa3bf8a1f3e401657e8f6.gif

054924d470725e65b80bc1e317a46c9c.jpeg

eca1f9471b1860c108748be5a9540d47.png

代码实现

19b3fed727637eec142a90d3dbffad1b.png

微卡智享

还是接着上一篇的程序代码,我们在这里进行处理,文章的最后会把Demo的源码地址发送上来。

定义广播和常量

5f10bef468942d772c7fc53c20494b10.png

ACTION_TEXTVIEW和ACTION_TOAST定义的是更新TextView的显示和使用Toast的两个常量,然后再定义一个BroadcastReceiver中写代码的实现,区分不同的action来实现更新TextView还是使用Toast弹窗。

private val ACTION_TEXTVIEW = "textview"
    private val ACTION_TOAST = "toast"
    private val ACTION_VALUE = "value"
    //定义广播接收
    private var mBroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            intent?.let {
                val str = it.getStringExtra(ACTION_VALUE)
                when (it.action) {
                    ACTION_TEXTVIEW -> {
                        binding.textView.text = str
                    }
                    ACTION_TOAST -> {
                        context?.let { mContext ->
                            Toast.makeText(mContext, str, Toast.LENGTH_SHORT)
                                .show()
                        }
                    }
                    else -> {
                        return@let
                    }
                }
            }
        }


    }

实现RemoteAction的发送广播

这个主要是由PendingIntent来实现的,当第一个按钮点击返回应用程序全屏时,用到的PendingIntent.getActivity,而第二和第三个按钮通过发送广播的方式就会用到了PendingIntent.getBroadcast,所以这里我们写了一个函数,通过函数的参数来生成对应的PendingIntent。

private fun getPendingIntent(intent: Intent, requestcode: Int, flag: Int = 1): PendingIntent {
        when (flag) {
            1 -> return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                PendingIntent.getActivity(
                    this, requestcode,
                    intent,
                    PendingIntent.FLAG_IMMUTABLE
                )
            } else {
                PendingIntent.getActivity(
                    this, requestcode,
                    intent,
                    PendingIntent.FLAG_UPDATE_CURRENT
                )
            }
            else -> return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                PendingIntent.getBroadcast(
                    this, requestcode,
                    intent,
                    PendingIntent.FLAG_IMMUTABLE
                )
            } else {
                PendingIntent.getBroadcast(
                    this, requestcode,
                    intent,
                    PendingIntent.FLAG_UPDATE_CURRENT
                )
            }
        }
    }

重点:

353b353a3438f012233832d3f70e4e6f.png

函数里面加入了判断Android的SDK版本,是因为上一篇中没加入这个,8.0的模拟器中运行正常,但是真机Android 12就会直接崩溃了,原因是Android 12 声明特定 PendingIntent 对象是否可变,请分别使用 PendingIntent.FLAG_MUTABLE 或 PendingIntent.FLAG_IMMUTABLE 标志。如果您的应用试图在不设置任何可变标志的情况下创建 PendingIntent 对象,系统会抛出 IllegalArgumentException。

重新再修改enterPipModel函数,加入创建三个按钮的代码。

private fun enterPipModel() {
        val builder = PictureInPictureParams.Builder()


        //设置Actions
        val actions = arrayListOf<RemoteAction>()
        //1.返回全屏窗口
        val pIntent1 = getPendingIntent(intent, 1)
        val remoteAction1 = RemoteAction(
            Icon.createWithResource(
                this,
                R.mipmap.ic_phone_round
            ), "画中画", "Vaccae", pIntent1
        )
        actions.add(remoteAction1)


        //2.修改Text显示
        val intent2 = Intent(ACTION_TEXTVIEW).putExtra(ACTION_VALUE, "Vaccae点击了Text Action")
        val pIntent2 = getPendingIntent(intent2, 2, 2)
        actions.add(
            RemoteAction(
                Icon.createWithResource(
                    this,
                    R.mipmap.ic_launcher
                ), "TextView", "Vaccae", pIntent2
            )
        )


        //3.实现Toast控制
        val intent3 = Intent(ACTION_TOAST).putExtra(ACTION_VALUE, "关注微卡智享")
        val pIntent3 = getPendingIntent(intent3, 3, 2)
        actions.add(
            RemoteAction(
                Icon.createWithResource(
                    this,
                    R.mipmap.ic_launcher
                ), "Toast", "Vaccae", pIntent3
            )
        )


        builder.setActions(actions)
        //设置宽高比例,第一个是分子,第二个是分母,指定宽高比,必须在 2.39:1或1:2.39 之间,否则会抛出IllegalArgumentException异常。
        val rational = Rational(5, 11)
        builder.setAspectRatio(rational)


        //Android12下加入的画中画配置,对于非视频内容停用无缝大小调整
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            builder.setSeamlessResizeEnabled(false)
            builder.setAutoEnterEnabled(true)
        }


        enterPictureInPictureMode(builder.build())
    }

判断画中画模式进入和退出时的广播监听

上一篇中使用onPictureInPictureModeChanged函数来判断时入画中画模式后将button按钮隐藏,回到全屏模式后再显示出来,现在在这个函数中再加入进入画中画时注册广播接收,关闭画中画时就释放广播接收,代码如下:

override fun onPictureInPictureModeChanged(
        isInPictureInPictureMode: Boolean,
        newConfig: Configuration?
    ) {
        super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
        if (isInPictureInPictureMode) {
            binding.textView.text = "画中画模式"
            binding.btnpip.visibility = View.GONE


            //进入画中画时注册广播接收
            val intentFilter = IntentFilter()
            intentFilter.addAction(ACTION_TEXTVIEW)
            intentFilter.addAction(ACTION_TOAST)
            registerReceiver(mBroadcastReceiver, intentFilter)


        } else {
            binding.textView.text = "正常模式"
            binding.btnpip.visibility = View.VISIBLE


            //退出画中画时停止广播接收
            unregisterReceiver(mBroadcastReceiver)
        }
    }

有时候当用户主动按主屏幕键或是最近的应用按钮,还是可以切换到画中画模式,这里就用到了onUserLeaveHint方法了。

1cf3c3f5348ca4315c9284c5244a7017.png

完成上面的步骤,画中画的按钮功能实现的Demo就完成了。

微卡智享

源码地址

https://github.com/Vaccae/AndroidPipDemo.git

点击阅读原文可以看到“码云”的代码地址

0c0833171287d50db1583a36a13eb70e.png

61a42e03f176382a281ed9e98897d41d.png

往期精彩回顾

bb369a3b0200fbbc93ed2e221f68727a.jpeg

Android画中画(PIP)模式使用


8c0fa77277f2cdb716843dd9560ba0b7.jpeg

C++ OpenCV手动截取图像做透视变换


2ebf61eb9f9c3f52b5c3ab672514ea3f.jpeg

使用OpenCV做个简单的颜色提取器


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vaccae

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值