Android端如何检测设备是否处于屏幕casting/镜像状态?
检测Android全局投屏状态(非当前应用发起)
我明白你的痛点——系统自带的CastSession和SessionManager确实只关心当前应用发起的投屏会话,要检测全局的投屏状态(比如其他APP开启的镜像/全屏投屏),得换个思路。这里有两个靠谱的方案:
方法1:用MediaRouter监控媒体路由
系统的MediaRouter可以追踪所有活跃的媒体路由,不管是哪个APP发起的投屏,都能捕捉到状态变化。
一次性检测(应用启动时)
// 获取MediaRouter实例 val mediaRouter = getSystemService(Context.MEDIA_ROUTER_SERVICE) as MediaRouter val selectedRoute = mediaRouter.selectedRoute // 判断当前选中的路由是否为外部投屏设备 val isDeviceCasting = selectedRoute.type != MediaRouter.RouteType.ROUTE_TYPE_LAUNCH && selectedRoute.type != MediaRouter.RouteType.ROUTE_TYPE_DEFAULT
实时监听状态变化
如果需要实时关注投屏状态的切换,可以注册回调:
val mediaRouter = getSystemService(Context.MEDIA_ROUTER_SERVICE) as MediaRouter val routeCallback = object : MediaRouter.Callback() { override fun onRouteSelected(router: MediaRouter, type: Int, info: MediaRouter.RouteInfo) { val isCastingNow = info.type != MediaRouter.RouteType.ROUTE_TYPE_LAUNCH && info.type != MediaRouter.RouteType.ROUTE_TYPE_DEFAULT // 在这里处理投屏状态变更的逻辑,比如隐藏特定内容 } } // 注册回调,监听视频类路由(包含投屏) mediaRouter.addCallback(MediaRouter.ROUTE_TYPE_LIVE_VIDEO, routeCallback) // 记得在页面销毁时移除回调,避免内存泄漏 override fun onDestroy() { super.onDestroy() mediaRouter.removeCallback(routeCallback) }
方法2:用DisplayManager检测外部显示设备
投屏本质是将内容输出到额外的显示设备,DisplayManager可以获取所有已连接的显示设备,通过判断是否存在外部显示来间接检测投屏状态。
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager val allDisplays = displayManager.displays // 方案1:判断是否存在主显示之外的设备(主显示ID通常为0) val hasExternalDisplay = allDisplays.size > 1 // 方案2:精确判断无线投屏类型(API 24+支持) val isWirelessCasting = allDisplays.any { display -> display.type == Display.TYPE_WIFI || display.type == Display.TYPE_EXTERNAL }
注意事项
- 兼容性:
Display.TYPE_WIFI是Android 7.0(API 24)新增的,低版本设备可以用Display.FLAG_PRESENTATION来判断是否为演示用外部显示。 - 特殊情况:有些设备可能会连接HDMI显示器等有线外部显示,如果你只需要检测无线投屏,优先用
TYPE_WIFI判断。 - 权限:这两个方案都不需要额外的权限,直接调用系统服务即可。
你可以在应用启动时(比如onCreate方法里)调用这些检测逻辑,根据结果决定是否展示特定内容。
内容的提问来源于stack exchange,提问作者Mohammadreza Khahani
相关产品推荐
相关产品推荐

