Android 双屏异显(Presentation) 开发,将第二个页面投屏到副屏上

news2024/11/18 9:39:08

1. 背景

最近开发的一个项目,有两个屏幕,需要将第二个页面投屏到副屏上,这就需要用到Android的双屏异显(Presentation)技术了,研究了一下,这里做下笔记。
我们那个副屏是一块汽车的后视镜(流媒体后视镜),是一块长条块的屏幕,分辨率是400 * 1920 px,如何将需要显示的内容正确摆放地显示到这块屏幕上,也是我们开发中的一个重点。
并且,我们是使用平板横屏进行开发的,对于横屏情况下双屏异显的处理,也是我们开发中的一个重点。

2. 创建主屏布局

主屏就用MainActivity就好

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //...
    }
}

3. 创建副屏布局

这里,继承了MyPresentation接口

class MyPresentation(outerContext: Context, display: Display) :
    Presentation(outerContext, display) {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.dialog_normal)//绑定副屏显示的布局
    }

	//显示时调用
    override fun onStart() {
        super.onStart()
    }


    //消失时调用
    override fun onStop() {
        super.onStop()
    }
}

4. 将页面投屏到副屏上

投屏到副屏上有多中方式,我们只需要在MainActivity中去调用这些代码就可以了。

4.1 方式一 : MediaRouter

MediaRouter mediaRouter = (MediaRouter) getSystemService(Context.MEDIA_ROUTER_SERVICE);
MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_AUDIO);
if (route != null) {
    Display presentationDisplay = route.getPresentationDisplay();
    if (presentationDisplay != null) {
        MyPresentation myPresentation = new MyPresentation(MainActivity.this, presentationDisplay);
        myPresentation.show();
    }
}

4.2 方式二 : DisplayManager

DisplayManager mDisplayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
Display[] displays = mDisplayManager.getDisplays();
if (displays.length > 1) {
   //displays[0] 主屏,displays[1] 副屏
   MyPresentation myPresentation = new MyPresentation(MainActivity.this, displays[1]);
   myPresentation.show();
}

5. 横屏状态下双屏异显的处理

在我们那个副屏上,副屏的显示逻辑是,主屏是竖屏,副屏就以副屏显示,主屏是横屏,副屏就以横屏显示。
如下图所示
在这里插入图片描述

而我们想要达到的效果是,主屏是横屏,而主屏是竖屏。
后来,我们想到了一个办法,就是搞两个ActivityActivity1负责显示主屏的页面,而Activity2负责副屏的显示。
首先启动Activity2,然后迅速启动Activity1,当Activity1关闭的时候,也去关闭Activity1,这样就可以实现主屏和副屏方向显示不一样的情况了。

6. 将需要显示的内容正确摆放到副屏上

由于我们的副屏是一块长条块的屏幕,分辨率是400 * 1920 px,我们现在主屏上是横屏显示,而副屏通过上述的操作,显示的是竖屏。
在这里插入图片描述
而我们真正期望显示的内容是蓝色这部分
在这里插入图片描述

所以,我们需要对View做一下旋转并位移

val rotation: ObjectAnimator = 
	ObjectAnimator.ofFloat(binding.textureView, "rotation", 0f, 90f)
val translationX: ObjectAnimator =
    ObjectAnimator.ofFloat(binding.textureView, "translationX", 0f, -720F)
val translationY: ObjectAnimator =
    ObjectAnimator.ofFloat(binding.textureView, "translationY", 0f, 420F)
val animatorSet = AnimatorSet()
animatorSet.playSequentially(rotation, translationX, translationY)
animatorSet.duration = 0
animatorSet.start()

最终显示为这样
在这里插入图片描述

7. 其他

7.1 没有副屏的情况下,如何调试 ?

如果手头上没有副屏,可以在开发者选项中,打开模拟辅助显示设备
在这里插入图片描述

这里我们可以选择1080P

在这里插入图片描述

显示出来的虚拟副屏如下所示

在这里插入图片描述
这样,我们就可以通过虚拟的副屏进行调试了。

7.2 参考

感谢
Android 双屏异显实现的三种方式
Android Presentation实现双屏异显
Presentation 官方文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/184026.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

超详细:KNN与K-means从入门到实战

作者:王同学 来源:投稿 编辑:学姐 1. 基本概念 1.1 KNN k近邻法(k-nearest neighbor,k-NN)是一种基本分类与回归方法。 k近邻法的输入为实例的特征向量对应于特征空间的点;输出为实例的类别&…

CnOpenData食品安全抽检数据

一、数据简介 食品安全是关乎人体生命健康的公共卫生问题。近年来,频繁发生的食品安全事件给人民的生命健康带来了巨大威胁,并成为人们关注的热点问题。   民以食为天,食以安为先。由于消费者和生产者之间存在信息不对称,完善…

【Linux】---进程程序替换

进程替换出现的背景我们可以用fork函数来创建子进程,使父子进程同时出现。正所谓子承父业,子进程在刚被创建时和父进程共享数据和代码,但是操作者想让子进程执行一个全新的程序,这个使子进程执行全新程序的操作叫做进程程序替换。…

前端播放大视频卡顿的解决(m3u8视频流)

前言 最近在一个大屏看板项目中有一个需求是:要求视频和看板要进行来回切换。 最开始的做法是将MP4视频放在项目里,在本地运行时是没什么问题的,但是在往仓库里提交代码时出现了问题。当单个文件超过100MB时会导致代码提交失败; …

【闲聊杂谈】直击重灾区 - 多线程与高并发

在开始学习多线程与高并发的知识之前,我想先问一个问题:你平时在写代码的时候,有没有刻意的去思考如何压榨CPU性能?其实纵观整个编程的发展历史,其实就是一部对于CPU性能压榨的血泪史。 单进程人工切换 最早的编程…

@Reference、@Autowired、@Resource的区别

目录 1. Autowired 和 Resource 的区别相同点:不同点:Resource 装配顺序2. Reference 和 Autowired 的区别理解1理解2理解31. Autowired 和 Resource 的区别 相同点: Resource 的作用相当于Autowired ,均可标注在字段或属性的se…

4、因果法

因果图中的图形符号 恒等。若原因出现,则结果出现;若原因不出现,则结果不出现。非。若原因出现,则结果不出现;若原因不出现,则结果出现。或。若几个原因中有一个出现,则结果出现;若几…

章节8 文本编辑器

8-Linux文本编辑器 文本编辑器 Windows:Notepad(记事本)、Sublime、UltraEdit等 Linux:VI/VIM (最常用)、nano、Emacs、Sed、gedit、Kate等 01 VI和VIM的区别 VI和VIM的区别 VI:Visual In…

C 语言零基础入门教程(十六)

C 位域 如果程序的结构中包含多个开关量,只有 TRUE/FALSE 变量,如下: struct {unsigned int widthValidated;unsigned int heightValidated; } status;这种结构需要 8 字节的内存空间,但在实际上,在每个变量中&#…

云计算|OpenStack发展简史

前言: 一般以open开始的软件都非常的牛逼,例如,OpenCV(人工智能学习库),OpenStack(云计算基础操作系统),openwrt(软路由),openEuler&…

表单设计器

表单设计器目录概述需求:设计思路实现思路分析参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,challenge Survive. happy for h…

vue2.x 富文本编辑器Tinymce的使用

VUE项目版本是2.x,切记: vue2中不能使用tinymce/tinymce-vue为4以上版本; 如果有安装高版本,卸载:npm uninstall tinymce/tinymce-vue 第一步:安装 npm install tinymce5.1.0 -S npm install tinymce/tiny…

费曼学习法——孩子弱点方向的提升和沟通技巧

这一篇虽然是兔年第一篇,但是,先不拜年了,主要是成文时间较短,后面会有一个详细的长篇文字,讨论一些观点和看法。每一个孩子都有弱点的方向,我们是否都要给孩子提升,首先表达一个观点&#xff1…

图论算法基础

图论算法基础有向图有向图的实现方式无向图无向图的实现方式连通图连通分量的定义强连通图和强连通分量的定义弱连通图和单向连通图的定义判断图是否是强连通图,弱连通图还是单项连通图一个很典型的错误代码JAVA实现C实现生成树最小生成树拓扑排序邻接表的实现方式数…

【ShaderGraph】道路引导,小溪流水等UV动画效果

目录 一:创建ShaderGraph文件 二:设置UV动画速度变量 ​三:设置UV动画方向和Tiling变量 ​四:设置贴图属性 五:设置主色MainColor属性 六:最终效果 一:创建ShaderGraph文件 1.在assets下…

css之BFC是什么

在讲BFC之前先来了解一下FC FC-Formatting Context FC全称Formatting Context(格式化上下文),元素在标准流里面都属于一个FC的 官网解释: Boxes in the normal flow belong to a formatting context,which may be block or inline, but not both sim…

指针(基础)

目录 一、内存和地址 二、指针是什么? 三、指针变量的内容 四、指针类型 五、间接访问操作符 (一)易混淆 六、野指针 (一)野指针成因 1. 指针未初始化 2. 指针越界访问 3. 指针指向的空间释放 &…

php xss攻击

文章目录一、什么是xss攻击二、攻击类型三、php相关处理函数1、htmlspecialchars 函数2、htmlentities 函数3、strip_tags 函数一、什么是xss攻击 xss攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执…

make menuconfig分析

在uboot源码顶层目录下,进入scripts/kconfig目录,打开Makefile文件 mconf作为可执行参数,uboot源码顶层目录下的配置文件传递给conf

39_tp6的rce漏洞

tp6的rce漏洞 一、环境搭建 使用docker本地搭建tp6环境 1. 下载镜像 docker pull vulfocus/thinkphp:6.0.122. 端口映射 启动镜像,并将80端口映射到8081端口,防止80端口冲突,运行容器 docker run -it -d -p 8081:80 1fc5d159922e3. 打开网站 默认的网页目录是在public目…