当前位置: 首页 > java >正文

Flutter PIP 插件 ---- 新增PipActivity,Android 11以下支持自动进入PIP Mode

接上文 Flutter PIP 插件 ---- Android

项目地址 PIP, pub.dev也已经同步发布 pip 0.0.3,你的加星和点赞,将是我继续改进最大的动力

开发文档 Add videos using picture-in-picture (PiP)介绍PIP功能从 Android 8.0 (API level 26) 引入,但是autoEnter功能从 Android 12 才开始支持,那么不支持的版本呢就需要通过监听 onUserLeaveHint 主动调用 enterPictureInPictureMode 才能进入 PIP Mode,在之前的版本中因为 FlutterActivity 没有转发 onUserLeaveHint,导致我们只能在 dart 中通过 flutterdidChangeAppLifecycleState 事件,在应用进入后台是主动调用的方式进入PIP Mode,但实际测下来,似乎无法区分通知栏下滑的通知,这导致即使应用在前台,当用户下滑通知栏的时候依然会自动进入PIP Mode, 这显然不是我们想要的,优化后的效果如下:

请添加图片描述

修改PIP插件

  • 新增PipActivity

    package org.opentraa.pip;import android.app.PictureInPictureUiState;
    import android.content.res.Configuration;
    import android.os.Build;
    import androidx.annotation.NonNull;
    import androidx.annotation.RequiresApi;
    import io.flutter.embedding.android.FlutterActivity;@RequiresApi(Build.VERSION_CODES.O)
    public class PipActivity extends FlutterActivity {public interface PipActivityListener {void onPictureInPictureModeChanged(boolean isInPictureInPictureMode,Configuration newConfig);void onPictureInPictureUiStateChanged(PictureInPictureUiState state);boolean onPictureInPictureRequested();void onUserLeaveHint();}private PipActivityListener mListener;public void setPipActivityListener(PipActivityListener listener) {mListener = listener;}// only available in API level 26 and above@RequiresApi(26)@Overridepublic void onPictureInPictureModeChanged(boolean isInPictureInPictureMode,Configuration newConfig) {super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);if (mListener != null) {mListener.onPictureInPictureModeChanged(isInPictureInPictureMode,newConfig);}}// only available in API level 30 and above@RequiresApi(30)@Overridepublic boolean onPictureInPictureRequested() {if (mListener != null) {return mListener.onPictureInPictureRequested();}return super.onPictureInPictureRequested();}// only available in API level 31 and above@RequiresApi(31)@Overridepublic voidonPictureInPictureUiStateChanged(@NonNull PictureInPictureUiState state) {super.onPictureInPictureUiStateChanged(state);if (mListener != null) {mListener.onPictureInPictureUiStateChanged(state);}}@Overridepublic void onUserLeaveHint() {super.onUserLeaveHint();if (mListener != null) {mListener.onUserLeaveHint();}}
    }
    

    主要思路就是如果PIP 插件的用户想要在 Android 12 以下支持应用进入后台自动进入 PIP Mode 的话,可以将自己 MainActivity 的父类修改为 PipActivity ,这样在 PIP 插件被注册时,可以通过判断传入的 Activity 是否是 PipActivity 来决定是否启用相关的功能。

  • 绑定 ActivityPipController
    PipPluginonAttachedToActivityonReattachedToActivityForConfigChanges 的时候去初始化 PipController

    private void initPipController(@NonNull ActivityPluginBinding binding) {if (pipController == null) {pipController = new PipController(binding.getActivity(), new PipController.PipStateChangedListener() {@Overridepublic void onPipStateChangedListener(PipController.PipState state) {// put state into a json objectchannel.invokeMethod("stateChanged",new HashMap<String, Object>() {{ put("state", state.getValue()); }});}});} else {pipController.attachToActivity(binding.getActivity());}
    }@Override
    public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {initPipController(binding);
    }@Override
    public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {initPipController(binding);
    }
    
  • PipController 构造函数和 attachToActivity 方法中去综合当前的系统版本和绑定的 Activity 进行检查是否支持 autoEnter

    public PipController(@NonNull Activity activity,@Nullable PipStateChangedListener listener) {setActivity(activity);//  ... Other code ...
    }private boolean checkAutoEnterSupport() {// Android 12 and above support to set auto enter enabled directlyif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {return true;}// For android 11 and below, we need to check if the activity is kind of// PipActivity since we can enter pip mode when the onUserLeaveHint is// called to enter pip mode as a workaroundActivity activity = mActivity.get();return activity instanceof PipActivity;
    }private void setActivity(Activity activity) {mActivity = new WeakReference<>(activity);if (activity instanceof PipActivity) {((PipActivity)activity).setPipActivityListener(this);}mIsSupported = checkPipSupport();mIsAutoEnterSupported = checkAutoEnterSupport();
    }public void attachToActivity(@NonNull Activity activity) {setActivity(activity);
    }
    

修改Example项目中的MainActivity

  • 孤伶伶的MainActivity
    package org.opentraa.pip_example;import io.flutter.embedding.android.FlutterActivity;
    import org.opentraa.pip.PipActivity;public class MainActivity extends PipActivity {
    }
    

如上,至此我们已经支持了全部版本的 PIP Mode autoEnter 功能。

http://www.xdnf.cn/news/3372.html

相关文章:

  • ARM ASM
  • 【云原生】基于Centos7 搭建Redis 6.2 操作实战详解
  • 【五一培训】Day1
  • Redis 挂掉后高并发系统的应对策略:使用 Sentinel 实现限流降级与 SkyWalking 监控优化
  • PostgreSQL 数据库下载和安装
  • Stm32 烧录 Micropython
  • 基于机器学习的舆情分析算法研究
  • 连接linux虚拟机并运行C++【从0开始】
  • 机器学习实战,天猫双十一销量与中国人寿保费预测,使用多项式回归,梯度下降,EDA数据探索,弹性网络等技术
  • vue中$set原理
  • Meta公司于2025年4月29日正式推出了全新Meta AI应用程序的首个版本
  • 正则表达式:精准匹配,高效处理文本
  • 《软件设计师》复习笔记(11.1)——生命周期、CMM、开发模型
  • 结构模式识别理论与方法
  • JWT Access Token 被窃取的风险与解决方案
  • spring-boot-maven-plugin 将spring打包成单个jar的工作原理
  • 企业经营系统分类及功能详解
  • 华为eNSP:IS-IS认证
  • 机器人--主机--控制系统
  • Python 常用内置函数详解(九):type()函数——获取对象类型或获取一个新的类型对象
  • RAG工程-基于LangChain 实现 Advanced RAG(预检索-查询优化)(上)
  • 2025华东杯数学建模B题完整分析论文(共36页)(含模型、代码、数据)
  • 分享5款开源、美观的 WinForm UI 控件库
  • 【Linux网络】I/O多路转接技术 - poll
  • DAY01:Vue零基础入门:环境搭建与核心语法深度解析
  • 数据库Mysql_约束
  • 第二章 日志分析-apache日志分析(玄机系列)
  • 【论文阅读26】贝叶斯-滑坡预测-不确定性
  • 图解 Git 工作流:理解 Rebase、Merge 与 Pull Request 的区别
  • 基于Redis实现-用户签到