前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android画中画(PIP)进阶---Action按钮的使用

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

作者头像
Vaccae
发布2022-12-29 14:06:47
9620
发布2022-12-29 14:06:47
举报
文章被收录于专栏:微卡智享微卡智享

学更好的别人,

做更好的自己。

——《微卡智享》

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

前言

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

实现效果

代码实现

微卡智享

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

定义广播和常量

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

代码语言:javascript
复制
    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。

代码语言:javascript
复制
    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
                )
            }
        }
    }

重点:

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

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

代码语言:javascript
复制
    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按钮隐藏,回到全屏模式后再显示出来,现在在这个函数中再加入进入画中画时注册广播接收,关闭画中画时就释放广播接收,代码如下:

代码语言:javascript
复制
    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方法了。

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

微卡智享

源码地址

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微卡智享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定义广播和常量
  • 实现RemoteAction的发送广播
  • 判断画中画模式进入和退出时的广播监听
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档