更新记录

1.2.0(2024-07-11)

  1. 修复资源ID显示问题。
  2. 修复之前版本不能重复粘贴问题。
  3. 添加通知监听。
  4. 添加长按事件 setPerformLongClick()。
  5. 其它细节问题。

1.1.2(2024-05-27)

  1. 新增方法 pasteToInputByIndex(index, 'contentToPaste') 根据索引粘贴内容
  2. 新增方法 pasteToInput(id, 'contentToPaste') 根据节点ID粘贴内容
  3. 新增方法 scheduleWakeUp() 唤醒屏幕

1.1.1(2024-05-22)

  1. 新增 getAppVersion(packageName) 获取指定应用的版本方法。
  2. 新增 performGestureSlideScreen(gesturePath, totalDuration) 执行一个复杂的滑动屏幕手势,通过一系列的点来描述手势的路径。
查看更多

平台兼容性

Android Android CPU类型 iOS
适用版本区间:5.1 - 14.0 armeabi-v7a:支持,arm64-v8a:支持,x86:支持 ×

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios

注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择


UniApp 原生安卓无障碍插件开发者文档

概述

  1. 该插件提供了丰富的无障碍操作接口,可用于查询、点击页面节点、获取屏幕节点信息、输入文本等功能,适用于实现各种自动化控制手机和执行自动化操作、自动化测试、用户行为模拟和界面操作等。

  2. 悬浮窗内运行的是一个 WebView 界面,使用 HTML、JavaScript、CSS 构建悬浮窗口界面,并且兼容本地网页和远程 HTTP 网址。

  3. 本次升级集成了通知监听插件,一款为 uni-app 框架设计的 Android 原生插件,用于处理 Android 设备上的通知服务。它提供了一系列的方法来管理通知权限、监听短信、监听通知、获取活动通知以及模拟点击通知等功能。

演示程序

扫码下载示例 APP

初始化

导入插件

注意:请先打包自定义基座

// 无障碍插件
const LinAccessibility = uni.requireNativePlugin('Lin-Accessibility');
// 通知监听插件
const LinNotification = uni.requireNativePlugin('Lin-Accessibility-Notification');
// 悬浮窗插件
const LinFloatWeb = uni.requireNativePlugin('Lin-Accessibility-Float');

通知监听插件使用说明文档:https://ext.dcloud.net.cn/plugin?id=19167

无需另外购买,本插件以集成了通知监听插件的功能,通知监听插件的详细使用说明请参考通知监听插件文档。

悬浮窗插件使用说明文档:https://ext.dcloud.net.cn/plugin?id=17858

无需另外购买,本插件以集成了悬浮窗插件的功能,悬浮窗插件的详细使用说明请参考悬浮窗插件文档。

获取无障碍权限

goAliveSetting()

跳转到设置,获取无障碍权限。

LinAccessibility.goAliveSetting(); // 跳转到设置

检查无障碍服务状态

getServiceState()

用于判断无障碍服务是否开启,返回值为布尔型。

console.log(LinAccessibility.getServiceState()); // true 或 false

接收页面变动事件

start(options, callback)

启动无障碍服务,接收页面变动事件。

参数说明

参数名 类型 说明
options object 配置无障碍服务的参数
callback function 无障碍服务的响应回调

options 参数

参数名 类型 说明
packageNames string[] 要监视的应用程序包的名称数组
notificationTimeout number 通知栏状态变化时的监听时间
monitorAllEvent boolean 是否监视所有事件

callback 参数

参数名 类型 说明
class_name string 触发事件的视图类名
package_name string 触发事件的应用程序包名
event_type number 触发的事件类型

示例代码

LinAccessibility.start(
    {
        packageNames: ['com.example.app1', 'com.example.app2'],
        notificationTimeout: 20,
        monitorAllEvent: true,
    },
    response => {
        console.log(response);
    }
);

stop()

停止接收页面变动事件回调。

LinAccessibility.stop();

getState()

接收页面变动事件回调状态。

console.log(LinAccessibility.getState()); // true 或 false

节点操作

getAllNodes(callback)

获取屏幕上的所有节点。

参数说明

参数名 类型 说明
callback function 回调函数,参数为节点数组

示例代码

LinAccessibility.getAllNodes(nodes => {
    console.log('All nodes: ', nodes);
});

forNodes(callback)

遍历屏幕上的所有节点。

参数说明

参数名 类型 说明
callback function 回调函数,参数为当前遍历到的节点对象

示例代码

LinAccessibility.forNodes(node => {
    console.log('Node: ', node);
});

clickByIndex(index)

点击节点(根据forNodes/getAllNodes方法遍历获得的index索引)。

参数说明

参数名 类型 说明
index number 节点索引

示例代码

LinAccessibility.getAllNodes(nodes => {
    console.log('All nodes: ', nodes);
    let index = 8;
    LinAccessibility.clickByIndex(index);
});

editByIndex(index, text)

输入文本(根据forNodes/getAllNodes方法遍历获得的index索引)。

参数说明

参数名 类型 说明
index number 节点索引
text string 要输入的文本内容

示例代码

LinAccessibility.getAllNodes(nodes => {
    console.log('All nodes: ', node);
    let index = 1;
    LinAccessibility.editByIndex(index, 'ExampleText');
});

getTagState(texts, callback)

查询多个文字判断是否存在。

参数说明

参数名 类型 说明
texts array 要查询的文字数组
callback function 回调函数,参数为每个文字的存在状态数组

示例代码

LinAccessibility.getTagState(['text1', 'text2'], status => {
    console.log('Does the text exist', status);
});

node(params, callback)

在当前界面上查找第一个满足条件的节点,并执行点击或编辑操作。

参数说明

参数名 类型 说明
params object 配置条件参数
callback function 执行结果回调

params 参数

参数名 类型 必填 说明
text string 否 节点的 text 属性
textMatch string 否 节点的 text 符合 textMatch 正则
id string 否 节点的 id
className string 否 节点的类名
packageName string 否 节点的包名
contentDesc string 否 节点的 contentDesc 属性
contentDescMatch string 否 节点的 contentDesc 符合 contentDescMatch 正则
edit string 否 需要编辑的内容
click boolean 否 是否点击节点

callback 参数

参数名 类型 说明
accNode boolean 是否找到满足条件的节点
click boolean 是否成功点击节点
edit boolean 是否成功编辑节点

示例代码

LinAccessibility.node(
    {
        click: true,
        textMatch: '.*匹配文字.*',
        edit: true,
        edit: '输入文本内容',
    },
    result => {
        const { accNode, click, edit } = result;
        if (accNode) {
            if (click) console.error('点击成功');
            if (edit) console.error('编辑成功');
        } else {
            console.error('没找见满足条件的节点');
        }
    }
);

findFirstNodeByText(text)

查询是否存在文字符合的节点。

参数说明

参数名 类型 说明
text string 要匹配的文字

示例代码

let isTextFound = LinAccessibility.findFirstNodeByText('ExampleText');
console.log('Text found: ', isTextFound);

clickFirstNodeByText(text)

点击第一个文字符合的节点。

参数说明

参数名 类型 说明
text string 要匹配的文字

示例代码

let isClicked = LinAccessibility.clickFirstNodeByText('ExampleText');
console.log('Clicked: ', isClicked);

getNodeSizeById(id)

获取符合 id 的节点数量。

参数说明

参数名 类型 说明
id string 要匹配的节点 id

示例代码

let nodeCount = LinAccessibility.getNodeSizeById('exampleId');
console.log('Node count: ', nodeCount);

clickById(id, index)

点击符合 id 的节点。

参数说明

参数名 类型 说明
id string 要匹配的节点 id
index number 节点索引

示例代码

let isNodeClicked = LinAccessibility.clickById('exampleId', 0);
console.log('Node clicked: ', isNodeClicked);

findFirstNodeByNotFullText(text)

查询是否存在文字符合包含的节点。

参数说明

参数名 类型 说明
text string 要匹配的文字片段

示例代码

let isTextPartiallyFound = LinAccessibility.findFirstNodeByNotFullText('ExampleText');
console.log('Text partially found: ', isTextPartiallyFound);

clickFirstNodeByNotFullText(text)

点击第一个文字符合包含的节点。

参数说明

参数名 类型 说明
text string 要匹配的文字片段

示例代码

let isPartialTextClicked = LinAccessibility.clickFirstNodeByNotFullText('ExampleText');
console.log('Partial text clicked: ', isPartialTextClicked);

findFirstNodeByContentDesc(text)

查询是否存在文字描述符合的节点。

参数说明

参数名 类型 说明
text string 要匹配的 contentDesc 文字

示例代码

let isDescFound = LinAccessibility.findFirstNodeByContentDesc('ExampleDesc');
console.log('Desc found: ', isDescFound);

clickFirstNodeByDesc(text)

点击第一个文字描述符合的节点。

参数说明

参数名 类型 说明
text string 要匹配的 contentDesc 文字

示例代码

let isDescClicked = LinAccessibility.clickFirstNodeByDesc('ExampleDesc');
console.log('Desc clicked: ', isDescClicked);

findFirstNodeByNotFullDesc(text)

查询是否存在文字描述符合包含的节点。

参数说明

参数名 类型 说明
text string 要匹配的 contentDesc 文字片段

示例代码

let isPartialDescFound = LinAccessibility.findFirstNodeByNotFullDesc('ExampleDesc');
console.log('Partial desc found: ', isPartialDescFound);

clickFirstNodeByNotFullDesc(text)

点击第一个文字描述符合包含的节点。

参数说明

参数名 类型 说明
text string 要匹配的 contentDesc 文字片段

示例代码

let isPartialDescClicked = LinAccessibility.clickFirstNodeByNotFullDesc('ExampleDesc');
console.log('Partial desc clicked: ', isPartialDescClicked);

setPerformLongClick()

设置长按操作。如果需要模拟长按屏幕操作,可以在所有点击方法(clickLocation(x, y)除外)执行之前调用此方法,执行一次长按事件后恢复正常点击。

示例代码

LinAccessibility.setPerformLongClick();
// 执行模拟长按屏幕操作
let isNodeClicked = LinAccessibility.clickById('exampleId', 0);
console.log('Node clicked: ', isNodeClicked);

edit(id, text)

输入文本。

参数说明

参数名 类型 说明
id string 要编辑的输入框节点 id
text string 要输入的文本内容

示例代码

let isTextEntered = LinAccessibility.edit('exampleId', 'ExampleText');
console.log('Text entered: ', isTextEntered);

getFirstNodeInformByText(text, fields, callback)

获取第一个符合文字的节点信息。

参数说明

参数名 类型 说明
text string 要匹配的文字
fields array 要获取的字段数组,如['className', 'text']
callback function 回调函数,参数为节点信息对象

fields 包含字段如下:

['className', 'text', 'packageName', 'contentDesc', 'checkable', 'checked', 'clickable', 'enable', 'focusable', 'focused', 'scrollable', 'longClickable', 'password', 'selected', 'bounds', 'childCount'];

示例代码

LinAccessibility.getFirstNodeInformByText('ExampleText', ['className', 'text'], nodeInfo => {
    console.log('Node information: ', nodeInfo);
});

getNodeInformById(id, index, fields, callback)

获取第 index 个符合 id 的节点信息。

参数说明

参数名 类型 说明
id string 要匹配的节点 id
index number 节点索引
fields array 要获取的字段数组
callback function 回调函数,参数为节点信息对象

示例代码

LinAccessibility.getNodeInformById('exampleId', 0, ['className', 'text'], nodeInfo => {
    console.log('Node information: ', nodeInfo);
});

getFirstNodeInformById(id, fields, callback)

获取第一个符合 id 的节点信息。

参数说明

参数名 类型 说明
id string 要匹配的节点 id
fields array 要获取的字段数组
callback function 回调函数,参数为节点信息对象

示例代码

LinAccessibility.getFirstNodeInformById('exampleId', ['className', 'text'], nodeInfo => {
    console.log('Node information: ', nodeInfo);
});

getChildNodeInform(id, nodeIndex, childIndex, fields, callback)

获取第 nodeIndex 个 id 符合的节点的第 childIndex 个节点信息。

参数说明

参数名 类型 说明
id string 要匹配的节点 id
nodeIndex number 节点索引
childIndex number 子节点索引
fields array 要获取的字段数组
callback function 回调函数,参数为节点信息对象

示例代码

LinAccessibility.getChildNodeInform('exampleId', 0, 0, ['className', 'text'], nodeInfo => {
    console.log('Node information: ', nodeInfo);
});

clickLocation(x, y)

点击坐标。

参数说明

参数名 类型 说明
x number x 坐标
y number y 坐标

示例代码

LinAccessibility.clickLocation(100, 200);

slideScreen(start_x, start_y, end_x, end_y, duration)

滑动屏幕。

参数说明

参数名 类型 说明
start_x number 开始位置的 x 坐标
start_y number 开始位置的 y 坐标
end_x number 结束位置的 x 坐标
end_y number 结束位置的 y 坐标
duration number 滑动持续时间(毫秒)

示例代码

LinAccessibility.slideScreen(100, 200, 300, 400, 500);

performGestureSlideScreen(points, totalDuration)

执行复杂的滑动手势,可以连续滑动多个点。

参数说明

参数名 类型 说明
points array 包含多个点的起始和结束坐标,以及每个点的滑动持续时间。格式为 [ [startX, startY, endX, endY, duration], ... ] 或者 [ [startX, startY], [endX, endY], ...]
totalDuration number 整个滑动过程的总持续时间(毫秒)。如果不设置,则默认为各个点持续时间之和。

示例代码

// [ [startX, startY, endX, endY, duration], ... ]
LinAccessibility.performGestureSlideScreen([
    [100, 200, 200, 200, 500], // 第一个点的起始坐标、结束坐标和滑动持续时间
    [200, 200, 200, 300, 500], // 第二个点的起始坐标、结束坐标和滑动持续时间
]);
// [ [startX, startY], [endX, endY], ...]
LinAccessibility.performGestureSlideScreen(
    [
        [100, 0], // 第一个点的起始坐标
        [100, 2000], // 第一个点的结束坐标
        [400, 2000], // 第二个点的起始坐标
        [400, 0], // 第二个点的结束坐标
        [600, 1500], // 第三个点的起始坐标
        [400, 1000], // 第三个点的结束坐标
        [800, 1500], // 第四个点的起始坐标
        [900, 1000], // 第四个点的结束坐标
    ],
    3000
); // 总的滑动持续时间为3000毫秒

pasteToInputByIndex(index, text)

根据节点的索引将文本粘贴到输入框中。

参数说明

参数名 类型 说明
index number 节点索引
text string 要粘贴到输入字段的文本。

返回值

  • true:粘贴成功。
  • false:粘贴失败。

示例代码

LinAccessibility.getAllNodes(nodes => {
    console.log('All nodes: ', node);
    let index = 1;
    const success = LinAccessibility.pasteToInputByIndex(index, '要粘贴的数据内容');
    console.log(success ? '粘贴成功' : '粘贴失败');
});

pasteToInput(id, num, text)

根据输入的节点的 ID 将文本粘贴到输入框中。

参数说明

参数名 类型 说明
id string 节点的 ID。
num number 第一个节点的 ID。
text string 要粘贴到输入字段的文本。

返回值

  • true:粘贴成功。
  • false:粘贴失败。

示例代码

// 粘贴数据到指定节点
const success = LinAccessibility.pasteToInput('nodeId', 2, '要粘贴的数据内容');
console.log(success ? '粘贴成功' : '粘贴失败');

其他无障碍操作 API

goBack()

返回。

示例代码

let isBack = LinAccessibility.goBack();
console.log('Back: ', isBack);

goHome()

回到桌面。

示例代码

let isHome = LinAccessibility.goHome();
console.log('Home: ', isHome);

goRecentTasks()

打开最近任务。

示例代码

let recentTasksOpened = LinAccessibility.goRecentTasks();
console.log('Recent tasks opened: ', recentTasksOpened);

moveAppToFront()

后台唤起应用程序。需要后台弹出窗口权限。

示例代码

LinAccessibility.moveAppToFront();

getPackageName()

获取应用程序包名称。

示例代码

let packageName = LinAccessibility.getPackageName();
console.log('Package name: ', packageName);

getAppVersion(packageName)

获取指定应用的版本。

参数说明

参数名 类型 说明
packageName string 应用的包名

示例代码

LinAccessibility.getAppVersion('com.tencent.mm', res => {
    console.log('微信:' + JSON.stringify(res));
});

scheduleWakeUp([delay])

安排设备在指定的时间后唤醒。

参数说明

参数名 类型 说明
delay number 延迟唤醒的时间(毫秒),可选参数。

示例代码

// 安排设备立即唤醒
LinAccessibility.scheduleWakeUp();
// 安排设备在10秒后唤醒
LinAccessibility.scheduleWakeUp(10000);

以上接口足以让你完成大部分的需求了,如果有什么疑问,请在下方留言哦。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

android.permission.REORDER_TASKS android.permission.BIND_ACCESSIBILITY_SERVICE android.permission.SYSTEM_ALERT_WINDOW

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

无

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无