You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 7+ 检测并禁用上层绘制应用的可行方案问询

Android 7+ 合规检测上层覆盖窗口方案

Hey there! Great question—detecting overlay windows (even transparent ones) is a critical security measure to block tapjacking attacks, so it’s smart you’re moving past the outdated /proc hacks that no longer work on modern Android versions. Let’s break down the official, compliant ways to handle this:

1. Accessibility Service(最可靠的实时检测方案)

Android’s Accessibility Service is the go-to official tool for monitoring window state changes. It lets you listen when windows are created, destroyed, or modified—perfect for spotting overlays on top of your app.

步骤实现:

  • 创建Accessibility Service类
    重写onAccessibilityEvent来捕获窗口状态变化,检查是否有外部窗口覆盖在你的应用之上:

    public class OverlayDetectAccessibilityService extends AccessibilityService {
        private static final String MY_APP_PACKAGE = "com.your.secure.app";
    
        @Override
        public void onAccessibilityEvent(AccessibilityEvent event) {
            if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
                AccessibilityNodeInfo rootNode = getRootInActiveWindow();
                if (rootNode == null) return;
    
                String overlayPackage = rootNode.getPackageName().toString();
                // 先确认当前前台应用是我们的App,再判断是否有外部覆盖层
                ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
                List<ActivityManager.RunningAppProcessInfo> foregroundProcesses = am.getRunningAppProcesses();
                if (foregroundProcesses != null) {
                    for (ActivityManager.RunningAppProcessInfo process : foregroundProcesses) {
                        if (process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND 
                            && process.processName.equals(MY_APP_PACKAGE)) {
                            if (!overlayPackage.equals(MY_APP_PACKAGE)) {
                                // 检测到外部覆盖层!
                                Log.w("OverlayAlert", "Potential tapjacking risk from: " + overlayPackage);
                                // 这里可以触发你的安全告警逻辑
                            }
                        }
                    }
                }
                rootNode.recycle(); // 记得回收节点,避免内存泄漏
            }
        }
    
        @Override
        public void onInterrupt() {
            // 服务中断时的处理逻辑
        }
    }
    
  • 配置服务权限
    在res/xml目录下创建accessibility_service_config.xml:

    <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
        android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
        android:accessibilityFeedbackType="feedbackGeneric"
        android:canRetrieveWindowContent="true"
        android:description="@string/accessibility_service_desc"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"/>
    
  • 在Manifest注册服务

    <service
        android:name=".OverlayDetectAccessibilityService"
        android:exported="false"
        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_service_config"/>
    </service>
    

    注意:用户必须手动在系统设置中启用你的辅助服务——这是Android的安全要求,无法静默获取权限。

2. Overlay Manager(API 26+, Android 8.0+)

对于Android 8.0及以上设备,OverlayManager API可以查询已获得SYSTEM_ALERT_WINDOW权限的应用(这类应用才有能力显示覆盖层)。它适合预先排查哪些应用存在潜在的覆盖风险。

示例代码:

OverlayManager overlayManager = (OverlayManager) getSystemService(Context.OVERLAY_SERVICE);
// 获取所有能覆盖我们App的应用列表
List<OverlayInfo> overlayInfos = overlayManager.getOverlayInfosForTarget(MY_APP_PACKAGE, OverlayManager.TYPE_ALL);
for (OverlayInfo info : overlayInfos) {
    Log.d("OverlayApps", "App with overlay permission: " + info.packageName);
}

它无法提供实时覆盖检测,但可以和Accessibility Service配合,形成分层的安全防护体系。

3. 补充防护:FLAG_SECURE

虽然这不是检测方法,但给应用窗口添加FLAG_SECURE可以阻止截屏和录屏——即使有覆盖层绕过检测,也能避免界面内容被窃取:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
    setContentView(R.layout.activity_main);
}

关键注意事项

  • 权限限制: 从Android 10(API 29)开始,如果你需要获取其他应用的包名,可能需要申请QUERY_ALL_PACKAGES权限(除非你只针对特定已知恶意包检测)。记得在Google Play listing中说明该权限的用途。
  • 无静默权限: 所有检测方案都需要用户明确授权(要么启用辅助服务,要么授予SYSTEM_ALERT_WINDOW权限),这是符合Android安全模型的必要条件。

内容的提问来源于stack exchange,提问作者kkazakov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:29:05