首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

  • 24-12-05 21:06
  • 3719
  • 12107
juejin.cn

Android 窗口镜像(mirror)常规的应用场景有投影、录屏等,本文介绍窗口镜像的使用方法和实现机制

mirror相关的方法有些是hide的,所以使用前需要评估当前app是否有权限

1. 投屏使用方法

官方文档:developer.android.google.cn/media/grow/…

投影接口:MediaProjection

标准用法:

  1. 通过用户授权获取一个一次性的MediaProjection
kotlin
代码解读
复制代码
val mediaProjectionManager = getSystemService(MediaProjectionManager::class.java) var mediaProjection : MediaProjection val startMediaProjection = registerForActivityResult( StartActivityForResult() ) { result -> if (result.resultCode == RESULT_OK) { mediaProjection = mediaProjectionManager .getMediaProjection(result.resultCode, result.data!!) } } startMediaProjection.launch(mediaProjectionManager.createScreenCaptureIntent())
  1. 启动一个前台服务
xml
代码解读
复制代码
<manifest ...> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" /> <application ...> <service android:name=".MyMediaProjectionService" android:foregroundServiceType="mediaProjection" android:exported="false"> service> application> manifest>
  1. 创建一个VirtualDisplay接收投影数据
kotlin
代码解读
复制代码
virtualDisplay = mediaProjection.createVirtualDisplay( "ScreenCapture", width, height, screenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, surface, null, null)

其中的Surface可以来自SurfaceView(实时显示)、ImageReader(截图)、MediaRecorder(录屏)或SurfaceTexture(实时显示、编辑),根据具体使用场景决定

2. 核心实现

核心实现涉及到一个类SurfaceControl,SurfaceControl 代表一个绘制图层,是 SurfaceFlinger 中 Layer 在Java层的一种封装,其中也包含了 Layer 的各种属性和操作接口。

一般的窗口,如Activity、Dialog以及通过WindowManager.addView()添加的窗口至少包含一个SurfaceControl,这样窗口才能被绘制出来。

核心方法

java
代码解读
复制代码
// android.view.SurfaceControl public static SurfaceControl mirrorSurface(SurfaceControl mirrorOf)

投屏或者镜像的核心实现是:通过SurfaceControl中的hide方法mirrorSurface(),把数据源SurfaceControl“复制”(mirror)一份,放(reparent)到目标SurfaceControl中。

两个操作对应到SurfaceFlinger中:

  • mirror操作是建一个新的Layer,并记录mirror源 Layer 的信息,到合成时直接使用源Layer的内容
  • reparent操作是将两个Layer设置从属关系,比如位置、透明度等属性从属Layer会受到主Layer的影响和限制

3. 扩展应用

使用mirror功能,需要源/从属SurfaceControl,也需要目标/主SurfaceControl,所以需要知道怎么获取SurfaceControl。

3.1 获取SurfaceControl

对于Window来说,可以通过View中的方法AttachedSurfaceControl getRootSurfaceControl()获取到接口AttachedSurfaceControl,通过其中方法buildReparentTransaction(SurfaceControl child)绑定mirror内容。这个接口中使用的是Window的根SurfaceControl。

另外也可以通过在布局中添加SurfaceView,然后使用SurfaceControl getSurfaceControl()获取SurfaceView对应的SurfaceControl。这也侧面说明SurfaceView与窗口中其他部分使用了不同的Layer进行合成。

获取到SurfaceControl就可以进行后续的操作。比如可以把一个SurfaceView的内容投影到另一个SurfaceView里,投影时可以添加各种常规的转换,比如缩放、旋转、位移和透明度等。

这些转换和reparent都属于SurfaceControl.Transaction的方法,对SurfaceControl的操作都需要通过SurfaceControl.Transaction进行,系统的窗口动画很多都是通过这个类实现的。

3.2 壁纸预览

AOSP里mirror的一个使用场景是壁纸预览,有两个方式可以获取壁纸:

  • 任意壁纸:SurfaceControl IWallpaperEngine.mirrorSurfaceControl(),使用示例可以参考packages/apps/WallpaperPicker2/src/com/android/wallpaper/util/WallpaperConnection.java,简单来说是需要绑定一个WallpaperService,然后通过回调中的IWallpaperEngine获取壁纸内容的SurfaceControl
  • 当前壁纸: 通过SurfaceControl WindowManagerGlobal.getInstance().mirrorWallpaperSurface(0 /*display id*/)获取某个显示屏上的系统壁纸SurfaceControl

获取到壁纸内容SurfaceControl后,可以通过3.1中的方式把壁纸经过转换显示到窗口或者SurfaceView中。

如果只是希望用壁纸来做窗口背景,可以给窗口加上FLAG_SHOW_WALLPAPER,或者主题里添加showWallpaper。上面列出的方式适合更复杂的使用场景。

3.3 放大镜

AOSP里另一个使用场景是无障碍中的放大镜功能,其中涉及到对SurfaceControl进行转换

image.png

  • 文档参考:source.android.google.cn/docs/core/d…
  • 代码参考:frameworks/base/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
注:本文转载自juejin.cn的OkieLe的文章"https://juejin.cn/post/7443812376846155830"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

140
Android
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top