欢迎使用CH34x系列usb串口-autojs支持库
- 支持类型 串口为控制端,蓝牙为被控端的CH34x串口
目录
- 欢迎使用CH34x系列usb串口-autojs支持库
- 一、流程图
- 二、UsbModel.js帮助文档
- 1.引入串口模块
- 2.实例化模块
- 3.判断设备是否支持外接串口操作
- 4.加载usb串口,并进行动态申请权限
- 5.对指定设备进行尝试连接、动态申请权限和串口设备初始化操作
- 6.动态申请权限
- 7.初始化设备
- 8.发送二进制数据给usb串口设备
- 9.断开连接
- 10.判断设备是否是可支持的usb设备
- 11.注册屏幕旋转
- 12.实例化TouchEvent并获取该对象的引用
- 13.获取一个未被占用的触摸id
- 14.判断触摸id是否被占用
- 15.按下坐标,但不释放
- 16.按下坐标并指定按下时长
- 17.点击坐标
- 18.长按坐标
- 19.两点间滑动
- 20.模拟手势操作
- 21.同时模拟多个手势,多点触控
- 22.抬起手指
- 23.校验是否是ui线程,是则抛出异常
- 24.将16进制命令转为字节数组
- 25.获取KeyBoardEvent(键盘指令事件处理器)
- 26.按下键盘的键码- 但不释放(只按下不抬起)
- 27.抬起指定的键位
- 三、DataCreater.jar帮助文档
一、流程图
二、UsbModel.js帮助文档
1.引入串口模块
- 使用Autojs常用的加载自定义模块的方式加载即可,尽量模块的加载使用单实例原则,否则多次连接串口可能会抛出未知的异常。
参数
- {String} 路径,在项目的/model下的UsbModel.js文件
返回值
- {*} usb串口模块的声明,但为被实例化
//加载usb串口模块
var UsbModel = require("./model/UsbModel");
2.实例化模块
参数
- {android.content.Context} context 上下文
返回值
- {UsbModel} UsbModel 实例化的串口模块对象
//实例化串口模块
this.UsbModel = new UsbModel(context);
3.判断设备是否支持外接串口操作
参数
- 无
返回值
- {Boolean} : true 支持;false 不支持
//判断设备是否支持外接串口操作
this.UsbModel.isSupportOtg();
4.加载usb串口,并进行动态申请权限
参数
- {Function} fun_NoDevice 未插入任何设备的回调方法
- {Function} fun_NoneSupportDevice 在有连接usb设备而无可支持的设备时执行的回调方法
- {Function} fun_onDeviceConnect 在设备连接时的回调方法,参数为android.hardware.usb.UsbDevice(用5中的connect进行设备连接)
- {Function} fun_AfterAgree 在点击同意后执行的回调方法
- {Function} fun_Aftercancle 在点击拒绝后执行的回调方法
返回值
- 无
//加载usb设备并进行connect操作
this.UsbModel.loadUsb(fun_NoDevice, fun_NoneSupportDevice, fun_onDeviceConnect, fun_AfterAgree, fun_Aftercancle);
5.对指定设备进行尝试连接、动态申请权限和串口设备初始化操作
注意:
- 连接失败会抛出异常,需要进行捕获并处理
- 在4中的fun_onDeviceConnect回调中使用该方法
参数
- {android.hardware.usb.UsbDevice} device 需要连接的设备
返回值
- 无
//连接设备,并进行数据对接
this.UsbModel.connect(device);
6.动态申请权限
注意:
- 此方法不需要进行使用,在5中的connect方法内部已经进行了调用。如需进行二次开发,请使用此方法来动态申请权限
参数
- {android.hardware.usb.UsbDevice} device 需要连接的设备
- {Function} fun_onDeviceConnect 在设备连接时的回调方法
- {Function} fun_AfterAgree 在点击同意后执行的回调方法
- {Function} fun_Aftercancle 在点击拒绝后执行的回调方法
返回值
- 无
//动态申请权限,并在按下同意/拒绝、设备连接时进行回调的执行
this.UsbModel.accessPermission(device, fun_onDeviceConnect, fun_AfterAgree, fun_Aftercancle);
7.初始化设备
注意:
- 此方法不需要进行使用,在5中的connect中已经进行了调用。如需进行二次开发,请使用此方法来动态申请权限
参数
- 无
返回值
- {Boolean}: true 初始化成功;false 初始化失败
//初始化设备
this.UsbModel.UartInit();
8.发送二进制数据给usb串口设备
注意:
- 此方法不需要进行使用,在后续的各种指令操纵中已经进行了调用。如需进行二次开发,请使用此方法并结合DataCreater.jar包内方法来动态申请权限。详见DataCreater.jar包帮助文档
参数
- {Array} data 字节数组的数据
- {Number} dataLength 字节数组的长度
- {Number} timeout 超时时间
返回值
- {Boolean} :执行结果 true 成功;false 失败
//创建字节数组
var data = util.java.array('byte', 1024);
//发送数据给usb设备
this.UsbModel.WriteData(data, data.length,10000);
9.断开连接
注意:
- app退出前必须调用此方法,否则,再次打开app,串口会被占用,而导致触摸指令、键盘指令等执行失败
//进行连接的断开操作
this.UsbModel.disConnect();
10.判断设备是否是可支持的usb设备
- 本模块已预设可支持的usb设备列表,如需进行扩展,可在模块内进行补充
- 无需调用本方法,本方法已在4中方法内进行了调用,如需二次开发,请用本方法进行设备过滤
参数
- {android.hardware.usb.UsbDevice} device 需要连接的设备
返回值
- {Boolean} :是否支持 true 支持;false 不支持
//判断该设备是否是可支持的设备
this.UsbModel.isCheckUsb(device);
11.注册屏幕旋转
- 串口模块的坐标无论屏幕如何旋转都是以手机正放的左上角为原点,而android的标准是当前屏幕位置的左上角。
- DataCreater.jar包内进行了坐标的转换,但是需要在屏幕旋转时,设备屏幕朝向,所以需要对屏幕旋转进行监听,以动态化设备屏幕朝向,完美解决该冲突
- 但是需要先进行TouchEvent对象的实例化,否则无法进行DataCreater.jar包内屏幕坐标转换器的屏幕朝向的注入
- 此方法不需要进行调用,已在12中实例化TouchEvent时,进行了调用,如需二次开发,请使用本方法进行监听
//注册屏幕旋转,并动态化设置屏幕朝向,完成坐标转化
this.UsbModel.onScreenRotationListener();
12.实例化TouchEvent并获取该对象的引用
- 在调用点击类操作时,务必使用本方法,对该对象实例化,否则会抛出异常
- 本方法不仅可以实例化对象,还可以返回该对象的引用,在第二次调用该方法时,只返回引用而不再次实例化
参数
- {Function} fun_log(point, eventType, command) 输出日志的回调方法,为null则不进行日志的处理(坐标,事件类型,命令报文)
返回值
- {com.msyq.touch.TouchEvent} TouchEvent对象(详见DataCreater.jar包开发文档)
// 实例化TouchEvent对象,并返回该对象引用
this.UsbModel.getTouchEvent((point, type, command) => {
log("触摸了:" + point +";事件类型:"+ type + ";命令:" + command);
});
13.获取一个未被占用的触摸id
返回值
- {Number} touchId 触摸id
//获取一个未被占用的触摸id
this.UsbModel.getFreeTouchId();
14.判断触摸id是否被占用
参数
- {Number} touchId 触摸id
返回值
- {Boolean} :是否被占用 true 被占用;false未被占用
//判断触摸id是否被占用
this.UsbModel.isFreeTouchId(touchId);
15.按下坐标,但不释放
- 按下坐标,但不释放。需要调用unTouch(touchId)进行释放。
- 当多次调用本方法而不释放的效果为滑动
- 触摸id如果为null或大于255,或小于0 ,则会调用13中的方法getFreeTouchId(),申请一个未被占用的触摸id
- 多次调用本方法,并传入不同的触摸id,效果为多点触控
- 据android规定,最多只能同时按下是个坐标,如果超过10个坐标且未被释放,会抛出异常
参数
- {Number} x 坐标x
- {Number} y 坐标y
- {Number} id 触摸id
返回值
- {Boolean} 执行结果 true 执行成功;false 执行失败
//方法一
//滑动展示
this.UsbModel.touch(200, 300, 0);
this.UsbModel.touch(300, 300, 0);
//仅释放触摸id 0
this.UsbModel.unTouch(0);
//方法二
//点击坐标展示
//按下(200,300),并自动分配触摸id
this.UsbModel.touch(200, 300);
//抬起所有的触摸id
this.UsbModel.unTouch(0);
16.按下坐标并指定按下时长
参数
- @param {Number} x 坐标的x
- @param {Number} y 坐标的y
- @param {Number} duration 等待时长
返回值
- 无
//按下坐标并指定按下时长
//按下(200,300)的坐标3s(3s = 3000ms)
this.UsbModel.press(200, 300, 3000);
17.点击坐标
参数
- {Number} x 坐标的x
- {Number} y 坐标的y
返回值
- 无
//点击指定的坐标
//点击(200,300)的坐标
this.UsbModel.click(200, 300);
18.长按坐标
参数
- {Number} x 坐标的x
- {Number} y 坐标的y
返回值
- 无
//长按特定的坐标
//长按(200,300)的坐标
this.UsbModel.longClick(200, 300);
19.两点间滑动
参数
- {Number} x1 坐标1的x
- {Number} y1 坐标1的y
- {Number} x2 坐标2的x
- {Number} y2 坐标2的y
- {Number} duration 执行时长
- {Boolean} isUnTouch 执行完后是否松手(可选参数,默认为true)
- {Number} touchId 触摸id(可选参数,默认为0)
返回值
- 无
//方法一
//从(200,300)滑动到(400,500)
this.UsbModel.slide(200, 300, 400, 500, 1000, true, 0);
//方法二
//从(200,300)滑动到(400,500)
this.UsbModel.slide(200, 300, 400, 500, 1000);
20.模拟手势操作
- 例如gesture(1000, [0, 0], [500, 500], [500, 1000])为模拟一个从(0, 0)到(500, 500)到(500, 100)的手势操作,时长为2秒。
- 使用slide()函数也可以模拟手势,但是无法进行两点之间的点位补全。也就是说,slide()只能进行预设点位的滑动,gesture()滑动的更真实。
参数
- {number} duration {number} 手势的时长
- {[x , y],[x , y]…} [x , y]手势滑动路径的一系列坐标
返回值
- 无
//从(500,500)经过(400,300)滑动到(800,800)
this.UsbModel.gesture(800, [500, 500], [400, 300], [800, 800]);
21.同时模拟多个手势,多点触控
参数
- gestures([delay1, duration1, [x1, y1], [x2, y2], …], [delay2, duration2, [x3, y3], [x4, y4], …], …)
返回值
- 无
// 手指捏合
obj.UsbModel.gestures([3000, [800, 300], [500, 1000]],[5000, [300, 1500], [500, 1000]]);
22.抬起手指
参数
- {Number} id 需要抬起的触摸id(可选参数)为空则抬起所有的触摸点位
返回值
- {Boolean} : 执行结果 true执行成功;false 执行失败
//抬起触摸id为0的触摸
this.UsbModel.unTouch(0);
//抬起所有的触摸
this.UsbModel.unTouch();
23.校验是否是ui线程,是则抛出异常
- 本方法用于检验当前线程是否是UI线程,以进行坐标的阻塞操作
- 本方法无返回值,但是如果是UI线程,则会抛出异常
- 本方法无需调用,且已在需要进行阻塞的坐标操控方法中进行了调用。
参数
- {String} 抛出的异常信息
返回值
- 无
// An highlighted block
this.UsbModel.checkNotUiThread("当前是UI线程,无法进行阻塞操作,请在多线程内尝试!");
24.将16进制命令转为字节数组
参数
- {String} command 需要转换成二进制指令的16进制字符串
返回值
- {byte[] } 字节数组形式的报文命令
//得到按下键盘A的指令
var data = this.UsbModel.getBtyeCommandFromHash("2c 08 45 41 00 00 04 00 00 00 00 00");
//执行指令
this.UsbModel.WriteData(data, data.length,10000);
25.获取KeyBoardEvent(键盘指令事件处理器)
- 实例化KeyBoardEvent,以使UsbModel具有操作键盘的能力
- 键码可通过com.msyq.keyboard.KeyBoard的静态字段来获取
- 在使用键盘的操作命令前,请务必调用该方法来实例化对象,否则会抛出异常
- 在第二次调用该方法时,如果对象未被销毁,则不会再次实例化对象,只进行对象引用的返回
参数
- {Function} fun_log 输出日志的回调方法,为null则不进行日志的处理
返回值
- {com.msyq.keyboard.KeyBoardEvent} KeyBoardEvent 对象的引用
//为串口模板实例化KeyBoardEvent类
this.UsbModel.getKeyBoardEvent((point, type, command) => {
log("键盘命令:" + command);
});
26.按下键盘的键码- 但不释放(只按下不抬起)
参数
- {Number} keyNum 键码 - 所有的键码可参照com.msyq.keyboard.KeyBoard的声明的键码来获取
返回值
- {Boolean} :执行结果 true 执行成功;false 执行失败
//喊话功能
//设置粘贴板
setClip("这里是Ch34x串口测试");
//使用ctrl+V进行粘贴
//按下左Ctrl
this.UsbModel.keyDown(com.msyq.keyboard.KeyBoard.Keyboard_LeftControl);
//按下V
this.UsbModel.keyDown(com.msyq.keyboard.KeyBoard.Keyboard_V);
//松开ctrl+v
this.UsbModel.keyUp(com.msyq.keyboard.KeyBoard.Keyboard_LeftControl, com.msyq.keyboard.KeyBoard.Keyboard_V);
27.抬起指定的键位
参数
- {Number} keyNum 可变参数-键码(为空则抬起所有的键盘)
返回值
- {Boolean} :执行结果 true 执行成功;false 执行失败
//抬起所有的按键
this.UsbModel.keyUp();
//抬起指定的按键
this.UsbModel.keyUp(com.msyq.keyboard.KeyBoard.Keyboard_LeftControl);
//同时抬起多个组合键
this.UsbModel.keyUp(com.msyq.keyboard.KeyBoard.Keyboard_LeftControl, com.msyq.keyboard.KeyBoard.Keyboard_V);
三、DataCreater.jar帮助文档
jar内为各种指令生成器转换器,分别为:
- TouchEvent (屏幕触摸坐标事件生成器)
- TouchPointConverter (android坐标与硬件串口坐标转换器)
- Multimedia (多媒体事件生成器)
- KeyBoardEvent(键盘事件生成器)
- MouseEvent (鼠标事件生成器)
1.TouchEvent 屏幕触摸坐标事件生成器
(1).使用屏幕分辨率来实例化对象
参数
- {int} screenWidth 屏幕的宽
- {int} screenHeight 屏幕的高
返回值
- {TouchEvent} 屏幕触摸坐标事件生成器对象
// 初始化一个屏幕宽960,高为1024分辨率的屏幕
TouchEvent touchEvent = new TouchEvent(960,1024);
(2).使用分辨率+屏幕朝向来实例化对象
参数
- {int} screenWidth 屏幕的宽
- {int} screenHeight 屏幕的高
- {int} screenOrientation 屏幕朝向
共有四个取值:
TouchEvent.SCREEN_HOME_BUTTOM home在屏幕下方
TouchEvent.SCREEN_HOME_LEFT home在屏幕左侧
TouchEvent.SCREEN_HOME_RIGHT home在屏幕右侧
TouchEvent.SCREEN_HOME_TOP home在屏幕顶部
返回值
- {TouchEvent} 屏幕触摸坐标事件生成器对象
// 初始化一个屏幕宽960,高为1024分辨率的屏幕,且朝向为home在下
TouchEvent touchEvent = new TouchEvent(960,1024,TouchEvent.SCREEN_HOME_BUTTOM);
(3).setScreenOrientation 设置屏幕朝向
- 说明:串口的屏幕朝向是始终以正放屏幕的左上角为原点,无论无何旋转屏幕,原点不变,所以在android和autojs中时,需要监听屏幕旋转,并且动态修改屏幕朝向,以保证生成的坐标正确。
参数
- {int} screenOrientation 屏幕朝向
共有四个取值:
TouchEvent.SCREEN_HOME_BUTTOM home在屏幕下方
TouchEvent.SCREEN_HOME_LEFT home在屏幕左侧
TouchEvent.SCREEN_HOME_RIGHT home在屏幕右侧
TouchEvent.SCREEN_HOME_TOP home在屏幕顶部
返回值
- 无
//设定屏幕的朝向正常
touchEvent.setScreenOrientation(TouchEvent.SCREEN_HOME_LEFT);
(4).setMsgLog 设定日志处理器
- 说明:日志处理器用于实时输出产生的日志信息,如有需要,请调用本方法,否则日志处理器不生效
参数
- {MsgLog<Point>} MsgLog 实现MsgLog日志处理器接口的类
返回值
- 无
//设定日志处理器,需要实现MsgLog接口
touchEvent.setMsgLog(new MsgLog<Point>() {
@Override
public void commandLog(Point point, String eventType, String command) {
System.out.println("坐标:"+point+";类型:"+eventType+";指令"+command);
}
});
(5).setScreenSize 重设屏幕尺寸
参数
- {int} screenWidth 屏幕的宽
- {int} screenHeight 屏幕的高
返回值
- 无
//重设屏幕尺寸为960,1024
touchEvent.setScreenSize(960,1024);
(6).touchPoint 使用指定id,按下指定坐标
说明:
- 触摸id为使用者任意指定的0-255之间的整数,任意且在释放前唯一
- 返回值为字节数组,如需字符串数组,可以使用日志处理器查看
- 生成的指令为按下但不松手
- 手机产生滑动的效果方法:使用该方法后不释放,再次按下别的位置,即可产生滑动效果
- 最大的触摸个数为10,若未释放的个数为10,再次调用本方法则会抛出CH34xUARTException异常
参数
- {Point} 触摸的坐标
- {Integer} touchId 按下的手指序列(0-255)
返回值
- {byte[ ]} 指令的二进制数组
//触摸坐标(100,200),并绑定到触摸id 1上
byte[] bytes = touchEvent.touchPoint(new Point(100, 200), 1);
(7).unTouch 释放单个触摸id
参数
- {int} touchId 释放的触摸id
返回值
- {byte[ ]} 指令的二进制数组
//释放触摸id 1的按下状态
byte[] bytes = touchEvent.unTouch(1);
(8).unTouch 释放所有触摸id
参数
- 无
返回值
- {byte[ ][ ]} 指令的二进制的二维数组
//释放所有的触摸id
byte[][] bytes = touchEvent.unTouch();
(9).isFreeId 判断触摸id是否被占用
参数
- {int} id 触摸id
返回值
- {boolean} 是否暂用
//判断触摸id 1是否占用
boolean freeId = touchEvent.isFreeId(1);
(10).getFreeTouchId获取一个未被占用的触摸id
参数
- 无
返回值
- {int} 未被占用的触摸id
//获取一个未被占用的触摸id
int freeTouchId = touchEvent.getFreeTouchId();
2.KeyBoardEvent键盘事件生成器
(1).实例化对象
参数
- 无
返回值
- {KeyBoardEvent} 键盘事件生成器对象
//实例化KeyBoardEvent对象
KeyBoardEvent keyBoardEvent = new KeyBoardEvent();
(2).setMsgLog 设定日志处理器
- 说明:日志处理器用于实时输出产生的日志信息,如有需要,请调用本方法,否则日志处理器不生效
参数- {MsgLog} MsgLog 实现MsgLog日志处理器接口的类
返回值
- 无
//设定键盘事件生成器的日志处理器
keyBoardEvent.setMsgLog(new MsgLog() {
@Override
public void commandLog(Object o, String eventType, String command) {
System.out.println("命令:"+command);
}
});
(3).keyDown 按下键盘键位
说明:
- 生成的指令为按下但不松手
参数
- {int} keyBoard 键盘键码
所有的可用键码在类com.msyq.keyboard.KeyBoard中 不建议直接传入数字
返回值
- {byte[ ]} 二进制命令
//按下键盘A
byte[] bytes = keyBoardEvent.keyDown(KeyBoard.Keyboard_A);
(4).keyUp 释放单个/多个键盘键位
参数
- {int…} keyBoard 键盘键码,可变参数,可以传入单个/多个键位键码
所有的可用键码在类com.msyq.keyboard.KeyBoard中 不建议直接传入数字
返回值
- {byte[ ]} 二进制命令
//释放键位 A + 左ctrl
byte[] bytes = keyBoardEvent.keyUp(KeyBoard.Keyboard_A, KeyBoard.Keyboard_LeftControl);
(5).keyUp 释放所有的键盘键码
参数
- 无
返回值
- {byte[ ]} 二进制命令
//释放所有的键盘键码
byte[] bytes = keyBoardEvent.keyUp();
3.Multimedia多媒体事件生成器
(1).实例化对象
参数
- 无
返回值
- {Multimedia} 多媒体事件生成器对象
//实例化多媒体事件生成器对象
Multimedia multimedia = new Multimedia();
(2).setMsgLog 设定日志处理器
- 说明:日志处理器用于实时输出产生的日志信息,如有需要,请调用本方法,否则日志处理器不生效
参数
- {MsgLog} MsgLog 实现MsgLog日志处理器接口的类
返回值
- 无
//设置Multimedia的日志处理器
multimedia.setMsgLog(new MsgLog<String>() {
@Override
public void commandLog(String name, String eventType, String command) {
System.out.println("操作:"+name+";类型:"+eventType+";指令:"+command);
}
});
(3).androidBack 松开/按下返回键
参数
- {boolean} isDown 按键状态是否是按下
返回值
- {byte[ ]} 二进制命令
//按下返回键
byte[] bytes = multimedia.androidBack(true);
(4).androidHome 松开/按下主页键
参数
- {boolean} isDown 按键状态是否是按下
返回值
- {byte[ ]} 二进制命令
//按下主页键
byte[] bytes = multimedia.androidHome(true);
(5).androidMenu 松开/按下菜单键
参数
- {boolean} isDown 按键状态是否是按下
返回值
- {byte[ ]} 二进制命令
//按下菜单键
byte[] bytes = multimedia.androidMenu(true);
(6).androidPower 按下并松开电源键
说明:
- 该方法是短按电源键,因串口未提供相关api,故无法实现关机
参数
- 无
返回值
- {byte[ ]} 二进制命令
//按下并松开电源键
byte[] bytes = multimedia.androidPower();
(7).androidVolumeDown 松开/按下音量-
参数
- {boolean} isDown 按键状态是否是按下
返回值
- {byte[ ]} 二进制命令
//按下音量-
byte[] bytes = multimedia.androidVolumeDown(true);
(8).androidVolumeUp 松开/按下音量+
参数
- {boolean} isDown 按键状态是否是按下
返回值
- {byte[ ]} 二进制命令
//按下音量+
byte[] bytes = multimedia.androidVolumeUp(true);
(9).androidVolumeNone 按下并松开静音键
说明:
- 该方法是短按静音键,因串口未提供相关api,故无法实现长按静音键
参数
- 无
返回值
- {byte[ ]} 二进制命令
//按下并松开静音键
byte[] bytes = multimedia.androidVolumeNone();
(10).lastSong 松开/按下上一首
参数
- {boolean} isDown 按键状态是否是按下
返回值
- {byte[ ]} 二进制命令
//按下上一首
byte[] bytes = multimedia.lastSong(true);
(11).nextSong 松开/按下下一首
参数
- {boolean} isDown 按键状态是否是按下
返回值
- {byte[ ]} 二进制命令
//按下下一首
byte[] bytes = multimedia.nextSong(true);
(12).changeSongStatus 松开/按下改变音乐播放状态
说明:
- 当前为播放,按下后变为暂停
- 当前为暂停,按下后变为播放
参数- {boolean} isDown 按键状态是否是按下
返回值
- {byte[ ]} 二进制命令
//按下改变音乐播放状态
byte[] bytes = multimedia.changeSongStatus(true);
4.MouseEvent鼠标事件生成器
- 因大部分手机不支持此方式的点击,暂未完成该部分的代码
5.CH34xUARTException异常类
说明 :可以在调用本jar时,捕获此异常。抛出异常的时机包括但不仅限于:
- TouchEvent.touchPoint时,已有10个触摸id
- TouchEvent.getFreeTouchId时,已有10个触摸id
- TouchEvent.isFreeId时,已有10个触摸id
- TouchPointConverter设置屏幕方向错误