更新记录

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. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问