Android检测并停止屏幕共享:Google Meet有效MS Teams无效的问题
解决MS Teams屏幕共享检测失效问题
你的代码依赖DisplayManager.DISPLAY_CATEGORY_PRESENTATION检测屏幕共享,但MS Teams的屏幕共享实现逻辑和Google Meet不同——它没有创建Presentation类型的Display,而是采用虚拟显示(Virtual Display)或直接基于系统MediaProjection API实现共享,因此原检测方法完全失效。
以下是针对MS Teams的替代解决方案:
一、检测屏幕共享状态
方案1:通过AccessibilityService监听窗口变化
MS Teams启动屏幕共享时会创建特定的窗口组件,可通过AccessibilityService捕获窗口状态变化来检测:
- 配置AccessibilityService
在AndroidManifest.xml中声明服务:
<service android:name=".TeamsScreenShareDetector" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_config" /> </service>
创建res/xml/accessibility_config.xml配置文件:
<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeWindowStateChanged" android:accessibilityFeedbackType="feedbackGeneric" android:canRetrieveWindowContent="true" android:description="@string/accessibility_desc" />
- 实现检测逻辑
class TeamsScreenShareDetector : AccessibilityService() { override fun onAccessibilityEvent(event: AccessibilityEvent) { if (event.eventType != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) return val packageName = event.packageName?.toString() val windowClass = event.className?.toString() // 匹配Teams包名及共享窗口特征(类名包含ScreenShare关键词) if (packageName == "com.microsoft.teams" && windowClass?.contains("ScreenShare") == true) { Log.i("ScreenShare", "MS Teams屏幕共享已开启") // 这里触发停止共享操作 stopTeamsShare() } } private fun stopTeamsShare() { rootInActiveWindow?.run { // 查找"停止共享"按钮并模拟点击 findAccessibilityNodeInfosByText("停止共享").firstOrNull()?.apply { performAction(AccessibilityNodeInfo.ACTION_CLICK) } } } override fun onInterrupt() {} }
方案2:通过NotificationListenerService监听共享通知
MS Teams屏幕共享时会显示系统通知,可通过监听通知检测状态并触发停止操作:
- 声明NotificationListenerService
<service android:name=".ShareNotificationListener" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> <intent-filter> <action android:name="android.service.notification.NotificationListenerService" /> </intent-filter> </service>
- 实现监听逻辑
class ShareNotificationListener : NotificationListenerService() { override fun onNotificationPosted(sbn: StatusBarNotification) { super.onNotificationPosted(sbn) if (sbn.packageName != "com.microsoft.teams") return val title = sbn.notification.extras.getString(Notification.EXTRA_TITLE) if (title?.contains("正在共享屏幕") == true) { // 遍历通知操作按钮,触发停止共享 sbn.notification.actions?.forEach { action -> if (action.title == "停止共享") { action.actionIntent.send() } } } } }
二、停止屏幕共享的补充说明
- 若需强制停止(不推荐),可通过
ActivityManager结束Teams进程,但会导致应用完全关闭:
val am = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager am.killBackgroundProcesses("com.microsoft.teams")
- 优先使用AccessibilityService或NotificationListener的模拟点击方式,更符合用户操作逻辑。
内容的提问来源于stack exchange,提问作者Sagar Jadhav
相关产品推荐
相关产品推荐

