找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3102

积分

0

好友

424

主题
发表于 2026-2-12 16:17:04 | 查看: 38| 回复: 0

一张AI Agent操作手机的流程图

最近,各类基于AI Agent的手机助手在社交平台上火爆出圈。它们展现出的能力令人惊叹:用户只需语音或文字下达指令,如“帮我找最便宜的iPhone”,AI就能自动打开购物App、精准搜索商品、比价并完成下单。这种“AI接管手机”的场景,无疑勾勒出了未来人机交互的新蓝图。

然而,当海量的AI操作开始涌现时,传统的移动端用户行为分析将面临严峻挑战。这些自动化的“非人”操作会严重污染业务数据,可能导致以下问题:

  • 转换率虚高:AI的自动下单行为会推高转换率数据,干扰业务方对真实用户购买力的判断。
  • 用户路径分析失效:AI执行的任务路径通常高度优化且重复,会污染真实的用户行为路径分析模型。
  • 推荐算法偏差:基于被AI操作数据“污染”过的数据集进行训练的推荐模型,其推荐结果将逐渐偏离真实用户的兴趣偏好。

那么,我们该如何有效识别这些“非人”操作呢?首先,我们需要从技术层面拆解AI或脚本是如何操作手机的。

AI Agent操作手机的技术原理

上图清晰地展示了AI Agent操作手机的典型流程,主要可分为四个层次:

  1. 用户入口层:用户通过文字或语音下达操作指令。
  2. 屏幕捕获层:Agent获取当前手机的屏幕信息(图像或视图结构)。
  3. 云端通信层:屏幕信息被上传至云端推理服务器,服务器分析后生成下一步操作指令并返回。
  4. 操作执行层:在手机端执行具体的操作指令,如点击、滑动、输入等。

从移动端监控的角度出发,要识别“非人”操作,我们需要重点关注操作执行层。以Android平台为例,在操作执行层实现自动化操作主要有三种技术路径:

  1. 通过 AccessibilityService(无障碍服务)输入事件
  2. 通过 INJECT_EVENTS 权限注入事件
  3. 通过 adb shell input 命令注入事件

此外,通过定制ROM、外接硬件等方式也能实现自动化,但不在本文讨论范围内。

通过 AccessibilityService 输入事件

AccessibilityService 是Android系统为辅助残障人士使用设备而提供的框架,但它也被广泛用于实现自动化操作,是各类辅助功能App和游戏脚本工具的主要技术手段。

其工作机制可分为三个阶段:

  • 阶段一:事件监听
    当应用界面状态发生变化(例如新页面打开、按钮状态改变)时,系统会通过 AccessibilityEvent 通知所有已注册并启用的无障碍服务。服务可以监听多种事件类型,包括窗口状态变化、内容变化、视图滚动等。

  • 阶段二:屏幕读取
    无障碍服务能够获取当前活动窗口的完整视图层次结构,通过 AccessibilityNodeInfo 对象访问屏幕上所有的UI元素,包括:

    • 文本内容(按钮文字、输入框内容等)
    • 视图属性(位置、大小、是否可点击等)
    • 视图的层次关系(父子节点、兄弟节点等)
      这使得AI Agent能够“看见”并理解当前屏幕的内容和状态。
  • 阶段三:自动化操作
    基于读取的屏幕信息,服务可以执行两种操作:

    1. 节点操作:直接对特定的UI节点执行点击、长按、输入文本等操作。
    2. 手势操作:通过 GestureDescription API执行复杂的滑动、拖拽等多点触控手势。

通过无障碍服务注入事件的特点:

  • 需要用户显式授权:用户必须在系统设置中手动开启对应的无障碍服务。
  • 能完整读取屏幕内容:可以获取文本、视图结构等丰富信息。
  • 操作能力灵活全面:支持点击、滑动、输入等复杂交互。

通过 INJECT_EVENTS 注入事件

INJECT_EVENTS 是一个系统级权限,允许应用直接向Android输入子系统注入触摸或按键事件,从而模拟真实用户操作。这是一种更底层的注入机制。

其工作机制也分为三个阶段:

  • 阶段一:事件构造
    应用通过 Instrumentation 或反射调用系统API,构造包含坐标、动作类型等信息的 MotionEvent 对象。

  • 阶段二:权限验证
    Android系统会检查调用者是否持有 INJECT_EVENTS 权限。该权限是系统级,普通应用无法获取,通常只有以下情况可以使用:

    • 具有系统签名的系统应用
    • 已获取Root权限的应用
  • 阶段三:系统注入
    通过权限验证后,事件被直接注入到Android的输入子系统。该系统负责处理所有硬件输入事件,因此注入的事件会被当作真实的触摸事件处理,并分发给当前获得焦点的窗口。

通过 INJECT_EVENTS 注入事件的特点:

  • 底层注入:事件绕过应用层,直接在系统底层产生。
  • 无需用户手动授权:但需要系统签名或Root权限。
  • 更难被检测:由于发生在更底层,应用层常规检测手段可能失效。

通过 adb shell input 注入事件

adb shell input 是Android调试桥提供的命令行工具,用于通过USB或网络连接向设备注入输入事件,常见于开发调试和自动化测试。其本质与 INJECT_EVENTS 相同,主要区别在于调用主体和权限获取方式。

其工作机制主要分为四个阶段:

  • 阶段一:命令发送
    在PC或远程设备上,通过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将命令发送至设备端的ADB守护进程。
  • 阶段三:守护进程处理
    设备端的 adbd 进程解析命令,构造相应的 MotionEventKeyEvent 对象。adbd 通常以 shellroot 权限运行。
  • 阶段四:系统注入
    adbd 调用系统API将事件注入输入子系统,此后的路径与 INJECT_EVENTS 方式完全一致。

INJECT_EVENTS 对比,adb shell input 方式的特点:

  • 需要建立ADB连接:事件通过ADB协议传输。
  • 权限来自ADB连接:只要建立了ADB调试连接即可,无需修改应用本身。
  • 底层实现一致:最终的事件注入路径相同。

如何检测“非人”操作

不少脚本工具,包括能操作手机的AI Agent,都在使用上述方案。但需注意,视障用户等群体也合法依赖无障碍服务。因此,简单粗暴的特征匹配容易造成误判。下文将探讨如何在操作发生时,采集事件特征及环境信息,来辅助识别“非人”操作。

识别 AccessibilityService 输入事件

通过无障碍服务操作手机,前提是用户在系统设置中开启它。Android系统提供了API来检测无障碍服务的状态:

// 1. 检测是否存在正在运行的无障碍服务
public boolean hasAccessibilityServiceRunning() {
      AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
      return am != null && am.isEnabled();
}

// 2. 检测无障碍服务的ID
public void checkServiceId() {
    List<AccessibilityServiceInfo> enabledServices = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
    for (AccessibilityServiceInfo service : enabledServices) {
        // 获取服务 ID (通常是 "包名/类名")
        String id = service.getId();
    }
}

// 3. 检测是否具备操作应用的能力(全控能力)
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;
        // 同时具备读取和操作能力,则认为是全控Agent
        if (canRetrieve && canPerform) {
            return true;
        }
    }
    return false;
}

此外,在Android S(API 31)及以上版本,还可以检查 MotionEvent 的标志位来判断事件是否源自无障碍服务:

// 检测事件是否由无障碍服务产生(API 31+)
public boolean isAccessibilityEvent(MotionEvent event) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        int flags = event.getFlags();
        // 使用位运算检查是否包含 FLAG_IS_ACCESSIBILITY_EVENT (0x800)
        return (flags & 0x0800) != 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();
    if ((flags & 0x08000000) != 0) { // FLAG_IS_GENERATED_GESTURE
        return true;
    }

    // 方法3:检查事件来源
    int source = event.getSource();
    if (source == InputDevice.SOURCE_UNKNOWN) {
        return true;
    }
    return false;
}

由于注入发生在底层,没有单一可靠的方法能100%准确识别。因此,对于这类事件,往往需要结合多维特征进行综合判断。

识别 adb shell input 注入事件

adb shell input 注入的事件本质与 INJECT_EVENTS 相同,但由于需要ADB连接,可以通过检测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);
    return plugged == BatteryManager.BATTERY_PLUGGED_USB;
}

检测ADB调试端口是否开放(适用于无线调试或模拟器场景):

  private static boolean isAdbPortOpen() {
      // 常见的 ADB 端口
      int[] 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);
              return true;
          } catch (Exception e) {
              // ignored
              e.printStackTrace();
          }
      }
      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");
        if (usbState != null && usbState.contains("adb")) {
            return true;
        }
        // 双重校验
        String usbConfig = (String) getMethod.invoke(null, "persist.sys.usb.config");
        if (usbConfig != null && usbConfig.contains("adb")) {
            return true;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

通过以上方法,可以在操作发生时采集ADB环境信息,结合事件本身特征,提高识别自动化操作的准确性。

通过RUM数据分析识别异常操作

将上述检测结果通过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_count
FROM log
GROUP BY
  “user.name“, “context.accessibility_service_id“
ORDER BY
  operation_count DESC
LIMIT 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_devices
FROM log
GROUP BY “context.accessibility_service_id“
ORDER BY affected_users DESC

分析说明:同时具备屏幕读取和手势操作能力的服务,被用于自动化操作的风险更高。

场景三:识别ADB连接环境下的操作

分析在ADB连接状态下的用户操作,这些操作很可能来自脚本。

-- 查询 ADB 开启状态下的用户操作特征
* and (context.adb_enabled: true or context.usb_adb_active:true or context.adb_port_open: true) |
SELECT
  “user.name“,
  “device.id“,
  CASE
    WHEN “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_count
FROM log
GROUP BY “user.name“, “device.id“, adb_status
ORDER BY event_count DESC
LIMIT 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_ratio
FROM log
GROUP BY “user.name“, “device.id“
HAVING injected_event_count > 50
ORDER BY inject_ratio DESC
LIMIT 100

分析说明:如果某个用户的事件中,被标记为“疑似注入”的事件比例过高(例如超过50%),则存在非人操作的可能性极大。

结语

本文对AI Agent或脚本自动化操作Android手机的主流技术原理进行了拆解,并详细介绍了针对三种技术路径的检测思路与代码实践。AutoGLM、豆包手机助手等AI Agent的兴起,标志着移动端交互正迈向新阶段。AI能自动完成复杂任务无疑是技术进步,但也为数据分析和业务风控带来了识别“非人”操作的新挑战。

实现精准的“非人”操作识别,绝非依赖单一维度即可完成。它需要一个立体的检测体系,涵盖应用运行环境、无障碍服务特征、设备指纹、用户行为序列、屏幕操作轨迹等多维度信息的交叉分析与建模。当前,一些可观测性平台的体验监控SDK已经开始采集相关属性,基于这些属性,开发者可以自定义分析规则,更有效地甄别潜在的非人操作,守护业务数据的纯净与可靠。




上一篇:计算机存储存取方式详解:从磁带、磁盘到RAM与CAM
下一篇:百度AI全栈布局:从搜索入口到“O计划”的领先战略
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-23 14:20 , Processed in 0.481798 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表