微信扫码
添加专属顾问
我要投稿
AI Agent接管手机操作带来便利的同时,也带来了数据污染的挑战,本文深入解析如何识别非人操作的技术路径。核心内容: 1. AI Agent操作手机对数据分析的三大影响 2. Android平台识别非人操作的三种技术路径 3. AccessibilityService服务实现自动化的三个阶段
背景介绍
Cloud Native
最近,基于 AI Agent 的各种手机助手在社交媒体上爆火,它能够通过 AI 自动操作手机完成下单、比价、搜索等复杂任务。用户只需说一句“帮我找最便宜的 iPhone”,AI 就能自动打开购物 App、搜索商品、对比价格并完成下单。这种“AI 接管手机”的场景,让很多人看到了未来人机交互的新形态。
然而,当 AI 开始大规模操作手机时,传统的用户行为分析将会面临严重的数据污染问题,如:
转换率虚高:AI 自动下单会对转换率数据造成干扰,导致业务决策误判
用户路径分析失效:AI 操作的路径高度优化且重复,会污染用户行为路径的分析
推荐算法偏差:基于 AI 操作数据训练的推荐模型,会偏离真实用户偏好
如何识别“非人”操作?我们先拆解下 AI 或脚本是如何操作手机的。
技术拆解
Cloud Native
我们先看下 AI Agent 操作手机的原理。
主要分为以下几个层次:
用户入口层:用户通过文字/语音等方式下达操作指令
屏幕捕获层:获取原始屏幕信息
云端通信层:云端推理服务器
操作执行层:点击、滑动、长按、输入等
从移动端监控角度去识别“非人”操作,需要重点关注“操作执行层”。以 Android 平台为例,在“操作执行层”常见的有三种技术路径可以实现“非人”操作:
通过 AccessibilityService(无障碍服务)输入事件
通过 INJECT_EVENTS 注入事件
通过 adb shell input 注入事件
除此之外,定制 ROM、外接硬件等也可以实现“非人”操作,这部分暂时不在本文的讨论范围。
▍通过 AccessibilityService 输入事件
AccessibilityService 是 Android 提供的无障碍服务框架,原本用于辅助残障人士使用手机,但也可以用于自动化操作。是各种辅助功能应用、游戏辅助工具实现自动化操作的主要技术路径。
AccessibilityService 的工作机制可以分为三个阶段:
阶段一:事件监听
阶段二:屏幕读取
阶段三:自动化操作
阶段一:事件监听
当应用界面发生变化时(如新页面打开、按钮状态改变),系统会通过 AccessibilityEvent 通知已注册的无障碍服务。服务可以监听多种事件类型,包括窗口状态变化、内容变化、视图滚动等。
阶段二:屏幕读取
无障碍服务可以获取当前活动窗口的视图层次结构(View Hierarchy),通过 AccessibilityNodeInfo 对象访问屏幕上的所有 UI 元素,包括:
文本内容(按钮文字、输入框内容等)
视图属性(位置、大小、可点击性等)
视图层次关系(父子节点、兄弟节点等)
这使得 AI Agent 能够“看到”屏幕上的内容,理解当前界面状态
阶段三:自动化操作
基于读取的屏幕内容,无障碍服务可以执行两种类型的操作:
节点操作:直接对 UI 节点执行操作(点击、长按、输入文本等)
手势操作:通过 GestureDescription API 执行复杂的触摸手势(滑动、拖拽、多点触控等)
通过无障碍服务输入事件,有以下特点:
需要用户授权:用户需要在系统设置中手动开启无障碍服务
屏幕内容读取:可以完整读取屏幕上的文本、视图层次结构等信息
操作能力灵活:支持点击、滑动、长按、输入文本等复杂操作
▍通过 INJECT_EVENTS 注入事件
INJECT_EVENTS 是 Android 系统级权限,允许应用直接向输入系统注入触摸事件,模拟用户操作。这个是 Android 系统层面提供的底层事件注入机制。
INJECT_EVENTS 的工作机制也可以分为三个阶段:
阶段一:事件构造
阶段二:权限验证
阶段三:系统注入
阶段一:事件构造
应用通过 Instrumentation 或反射调用系统 API,构造 MotionEvent 对象。这个对象包含了触摸的坐标、动作类型(ACTION_DOWN、ACTION_UP 等)等基本信息。
阶段二:权限验证
Android 系统会检查调用者是否具有 INJECT_EVENTS 权限。这个权限是系统级权限,普通应用无法获取,只有以下情况下才能使用:
系统应用(具有系统签名)
Root 权限的应用
阶段三:系统注入
通过权限验证后,事件会被直接注入到 Android 的输入子系统(Input System)。输入子系统负责处理所有输入事件(触摸、按键等),注入的事件会被当作真实的硬件输入事件处理,分发给当前焦点窗口。
通过 INJECT_EVENTS 注入事件有以下特点:
底层注入:事件直接注入到系统,发生在更底层
无需用户授权:不需要用户手动授权(但需要系统签名或 root 权限)
更难检测:注入发生在系统底层,更难被应用层检测
▍通过 adb shell input 注入事件
adb shell input 是 Android Debug Bridge(ADB)提供的命令行工具,用于通过 USB 连接或网络连接向设备注入输入事件。这是开发调试和自动化测试中常用的方式。与 INJECT_EVENTS 在本质上是一样的,在调用主体和权限获取方面存在差异。
通过 adb shell input 注入事件的工作机制主要分为四个阶段:
阶段一:命令发送
阶段二:ADB 协议传输
阶段三:守护进程处理
阶段四:系统注入
阶段一:命令发送
在 pc 端或远程设备上(如 USB 设备等),可以通过 ADB 客户端发送 input 命令,如下:
adb shell input tap 500 1000 # 点击坐标(500, 1000)adb shell input swipe 100 200 300 400 # 从(100, 200)滑动到(300, 400)adb shell input text "hello" # 输入文本 "hello"
阶段二:ADB 协议传输
ADB 客户端通过 USB 或 TCP/IP 网络,将命令发送到 Android 设备端的 ADB 守护进程(adbd)。ADB 协议负责命令的序列化、传输和反序列化。
阶段三:守护进程处理
设备端的 adbd 守护进程接收到命令后,解析命令参数,构造相应的 MotionEvent 或 KeyEvent 对象。adbd 进程以系统权限(通常是 shell 或 root)运行,具有系统级权限。
阶段四:系统注入
adbd 调用系统 API(InputManager.injectInputEvent()),将事件注入到输入子系统。这个过程与应用内 INJECT_EVENTS 的最终注入路径相同。
与 INJECT_EVENTS 对比,adb shell input 方式注入事件有以下特点:
需要经过 ADB 协议传输
权限获取方式:只要建立了 ADB 连接就能获取到权限,不需要修改应用
事件注入的底层实现与 INJECT_EVENTS 一致
如何检测“非人”操作
Cloud Native
不少外挂和脚本,包含可以操作手机的 AI Agent 等都在使用上述方案。但特殊人群(如视障用户)也在使用无障碍服务。简单的通过特征值对事件进行分析,可能会造成误判。下文将主要探讨当操作事件发生时,如何通过采集事件的特征以及外部环境的特征,辅助分析“非人”操作事件。
▍识别 AccessibilityService 输入事件
通过 AccessibilityService 操作手机,需要先在手机系统设置中开启对应的障碍服务。Android 系统提供了可以判断是否有无障碍服务在运行的相关 API,如下:
支持检测是否存在正在运行的无障碍服务
支持读取无障碍服务的 ID
支持检测屏幕内容是否被读取
支持检测是否具备操作应用的能力
// 检测是否存在正在运行的无障碍服务public boolean hasAccessibilityServiceRunning() {AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);return am != null && am.isEnabled();}// 检测无障碍服务的Idpublic void checkServiceId() {List<AccessibilityServiceInfo> enabledServices = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);for (AccessibilityServiceInfo service : enabledServices) {// 获取服务 ID (通常是 "包名/类名")String id = service.getId();}}// 检测是否具备操作应用的能力public boolean hasFullControlAgent() {List<AccessibilityServiceInfo> enabledServices = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);for (AccessibilityServiceInfo service : enabledServices) {int capabilities = service.getCapabilities();// 1. 检查是否有可以读取屏幕boolean canRetrieve = (capabilities & AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT) != 0;// 2. 检查是否可以操作应用boolean canPerform = (capabilities & AccessibilityServiceInfo.CAPABILITY_CAN_PERFORM_GESTURES) != 0;// 具备操作应用的能力if (canRetrieve && canPerform) {return true;}}return false;}
除此之外,还可以通过检查 MotionEvent 的 flags 来判断事件是否通过无障碍服务产生:
// 检测事件是否由无障碍服务产生(有API版本要求)public boolean isAccessibilityEvent(MotionEvent event) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {int flags = event.getFlags();// 使用位运算检查是否包含 0x800return (flags & FLAG_IS_ACCESSIBILITY_EVENT) != 0;}return false;}
通过以上方式,应用虽然可以检测到当前是否存在正在运行的无障碍服务,但也可能对正常的无障碍服务造成误伤。
▍识别 INJECT_EVENTS 注入事件
INJECT_EVENTS 注入的事件一般有以下特征:
事件属性可能缺少压力值、触摸面积等属性
标志位可能是 FLAG_IS_GENERATED_GESTURE
事件来源可能是 SOURCE_UNKNOWN
检测逻辑如下:
public boolean isEventInjected(MotionEvent event) {if (event == null) {return false;}// 方法1:检查事件属性// 注入的事件可能缺少压力值、触摸面积等属性boolean hasPressure = event.getPressure() > 0;boolean hasSize = event.getSize() > 0;boolean hasToolType = event.getToolType(0) != MotionEvent.TOOL_TYPE_UNKNOWN;// 如果事件缺少这些基本属性,可能是注入的(可能会误判)if (!hasPressure && !hasSize && !hasToolType) {return true;}// 方法2:检查事件标志位int flags = event.getFlags();// FLAG_IS_GENERATED_GESTURE 表示是程序生成的手势if ((flags & 0x08000000) != 0) {return true;}// 方法3:检查事件来源int source = event.getSource();if (source == InputDevice.SOURCE_UNKNOWN) {return true;}return false;}
通过 INJECT_EVENTS 注入的事件,目前并没有非常可靠的单一方法,因为注入的事件发生在更底层,可以绕过应用层的检测机制。对于这类事件的注入,往往需要多维度综合检测的方式进行识别(也适用其他类型的注入事件检测)。即便如此,也可以尝试对事件特征进行检测,用于提升识别“非人”操作的成功率。
▍识别 adb shell input 注入事件
通过 adb shell input 注入的事件,本质上与通过 INJECT_EVENTS 注入的事件是一样的。但由于需要连接 ADB,相对 INJECT_EVENTS 的注入,可以通过检测 ADB 连接状态等进行识别。
检测 ADB 是否开启:
public static boolean isAdbEnabled(Context context) {return Settings.Global.getInt(context.getContentResolver(),Settings.Global.ADB_ENABLED, 0) > 0;}
检测 USB 连接状态:
private static boolean isUsbConnected(Context context) {Intent intent = context.registerReceiver(null,new IntentFilter(Intent.ACTION_BATTERY_CHANGED));if (intent == null) return false;int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);// 判断是否通过 USB 供电return plugged == BatteryManager.BATTERY_PLUGGED_USB;}
检测 ADB 端口是否打开:(无线调试和模拟器场景)
private static boolean isAdbPortOpen() {// 常见的 ADB 端口,5555 是默认,部分模拟器可能是 5554-5585int[] ports = {5555, 5554, 5556, 5557, 5558, 5559, 5560};for (int port : ports) {try (Socket socket = new Socket()) {socket.connect(new InetSocketAddress("127.0.0.1", port), 50);Log.w(TAG, "isAdbPortOpen, opened. port: " + port);} catch (Exception e) {// ignorede.printStackTrace();Log.w(TAG, "isAdbPortOpen, closed. port: " + port);}}return false;}
检测调试器状态:
public static boolean isDebuggerAttached() {return android.os.Debug.isDebuggerConnected();}
检测 USB ADB 状态:
private static boolean isUsbAdbActive() {try {Class<?> systemPropertiesClass = Class.forName("android.os.SystemProperties");Method getMethod = systemPropertiesClass.getMethod("get", String.class);String usbState = (String) getMethod.invoke(null, "sys.usb.state");// 判断是否包含 adb// 常见的返回值:// "mtp,adb" -> 开启了 MTP 传输且 ADB 已连接// "adb" -> 仅充电模式且 ADB 已连接// "mtp" -> 仅 MTP,未开启 ADBif (usbState != null && usbState.contains("adb")) {return true;}// 双重校验:有些厂商可能用 persist.sys.usb.configString usbConfig = (String) getMethod.invoke(null, "persist.sys.usb.config");if (usbConfig != null && usbConfig.contains("adb")) {return true;}} catch (Exception e) {// 反射失败或权限不足(部分高版本 Android 可能限制读取)e.printStackTrace();}return false;}
通过以上方式,可以采集到操作时的 ADB 相关环境信息。在分析操作事件发生时,结合 ADB 相关的状态信息,可以协助判断当前应用“非人”操作的可能性。
▍通过 RUM + 自定义 Query 识别异常操作
以上三种方式检测的结果字段将会通过 RUM SDK 上报到用户体验监控产品,通过对结果字段的查询分析可以快速识别可疑的非人操作。以下是几个分析场景。
通过分析无障碍服务的开启状态和服务 ID,快速定位可能存在非人操作的用户。
-- 查询最近1小时内开启无障碍服务的用户及其操作次数* and context.accessibility_enabled: true |SELECT"user.name","context.accessibility_service_id",COUNT(*) as operation_count,COUNT(DISTINCT "session.id") as session_countGROUP BY"user.name", "context.accessibility_service_id"ORDER BYoperation_count DESCLIMIT 100
分析说明:如果某个用户的操作次数异常高,且开启了非系统的无障碍服务,需要重点关注。
重点分析具备读取屏幕和操作应用双重能力的无障碍服务。
-- 查询具备全控能力的无障碍服务及影响的用户数* and context.can_retrieve_window: true and context.can_perform_gestures: true |SELECT"context.accessibility_service_id",COUNT(DISTINCT "user.name") as affected_users,COUNT(DISTINCT "device.id") as affected_devicesFROM logGROUP BY "context.accessibility_service_id"ORDER BY affected_users DESC
分析说明:同时具备屏幕读取和手势操作能力的服务,更有可能被用于自动化操作。
分析在 ADB 连接状态下的用户操作,可能存在脚本或自动化工具。
-- 查询 ADB 开启状态下的用户操作特征* and context.adb_enabled: true or context.usb_adb_active:true or context.adb_port_open: true |SELECT"user.name","device.id",CASEWHEN "context.adb_enabled" = true THEN 'ADB已开启'WHEN "context.usb_adb_active" = true THEN 'USB-ADB已连接'WHEN "context.adb_port_open" = true THEN 'ADB端口已打开'END as adb_status,COUNT(*) as event_countFROM logGROUP BY "user.name", "device.id", adb_statusORDER BY event_count DESCLIMIT 100
分析说明:ADB 连接状态下的操作,可能是自动化脚本。
通过事件标志位和属性缺失情况,识别可能通过 INJECT_EVENTS 注入的事件。
-- 查询具有注入特征的事件* and event_type: "action" and (context.is_generated_gesture: true or context.event_source = 'SOURCE_UNKNOWN' or (context.has_pressure: false and context.has_size: false and context.has_tool_type: false)) |SELECT"user.name","device.id",COUNT(*) as injected_event_count,COUNT(DISTINCT session_id) as session_count,ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (PARTITION BY "user.name"), 2) as inject_ratioFROM logGROUP BY "user.name", "device.id"HAVING injected_event_count > 50ORDER BY inject_ratio DESCLIMIT 100
分析说明:如果某个用户的注入事件占比过高(如超过 50%),很可能存在非人操作。
结语
Cloud Native
以上内容对 AI Agent 或脚本操作手机的技术原理进行了分析,同时也介绍了三种技术路径下如何提取事件的特征信息。AutoGLM、豆包手机等 AI Agent 的兴起,标志着移动端交互即将进入新的阶段。AI 能够自动完成复杂的交互操作,这既是技术的进步,也为如何识别“非人”操作带来新的挑战。移动端监控要做到准确的“非人”识别,需要通过多个维度进行检测和识别。包括但不限于:应用运行环境检测能力的增强,无障碍服务包名特征的检测,设备特征的检测,行为特征的检测,屏幕轨迹特征的检测等。当前,阿里云可观测用户体验监控 SDK 已经采集相关属性,基于这些属性可以自定义分析当前是否可能存在非人操作(功能灰度中,可以加入钉钉交流群联系笔者,群号:67370002064)。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2026-02-11
全新DeepSeek发布!上下文扩展至1M
2026-02-11
刚刚,DeepSeek悄悄测试新模型:百万token上下文、知识库更新,V4要来了?
2026-02-11
DeepSeek V4 悄咪咪上线了?1M 上下文简直爽翻!
2026-02-11
2026 企业级AI(Agentic AI for Enterprise),是新大陆
2026-02-11
深度求索突然出手!1M上下文碾压GPT-4?国内AI迎来全新突破
2026-02-11
从 Clawdbot 到 OpenClaw :揭秘 AI Agent 的三重生态系统供应链风险
2026-02-11
DeepSeek 刚刚发布了新模型!
2026-02-11
DeepSeek新模型来了!官网模型更新为最新版,实测显示非此前的DeepSeek V3.2,最高支持100万tokens输入,以及知识截止日期为2025年5月
2026-01-24
2026-01-10
2025-11-19
2026-01-26
2026-01-01
2025-12-09
2025-12-21
2026-01-09
2025-11-15
2026-01-09
2026-02-11
2026-02-11
2026-02-11
2026-02-11
2026-02-07
2026-02-04
2026-02-03
2026-02-03