更新记录

1.0.3(2024-06-17)

添加iOS平台BLE,TCP,UDP支持

1.0.2(2023-10-27)

支持网络(TCP/UDP)、蓝牙(SPP/BLE)、USB、串口等接口通讯。
自动缓存收取到的数据,应用程序可无阻塞直接读取数据。
部分接口能及时获知对端断开(TCP/SPP/BLE/USB)。
提供搜索接口,搜索蓝牙设备、USB设备、串口设备。
提供统一的读、写、关闭接口,不同的端口使用不同的接口和参数打开。


平台兼容性

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

原生插件通用使用流程:

  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原生插件配置”->”云端插件“列表中删除该插件重新选择


插件概览

安卓支持网络(TCP/UDP)、蓝牙(SPP/BLE)、USB、串口等接口通讯。
iOS支持网络(TCP/UDP)、蓝牙(BLE)、等接口通讯。
自动缓存收取到的数据,应用程序可无阻塞直接读取数据。
部分接口能及时获知对端断开(TCP/SPP/BLE/USB)。
提供搜索接口,搜索蓝牙设备、USB设备、串口设备。
提供统一的读、写、关闭接口,不同的端口使用不同的接口和参数打开。
各项功能都经过长时间大量测试非常稳定。
注意:
目前版本安卓ble使用蓝牙地址连接,ios版本ble使用蓝牙名称连接,具体看例子。
建议在进入app或者进入特定页面时,提前判断并申请蓝牙权限。
如果等到调用具体接口的时候再申请,那一次调用就会因为没有权限而失败,导致要点两次。

插件调用流程

1 获取插件实例:

    var SSIOUniModule = uni.requireNativePlugin("wyj-ssio_SSIOUniModule");

2 声明端口句柄:(最好是全局的)

    var handle = 0;  

3 打开端口:(判断端口是否已打开,如果没有打开才需要打开,如果已经打开了则跳过这一步)
例如:

    if (!SSIOUniModule.SSIO_Port_IsOpened(handle)) {  
        this.message = "正在打开端口...";  
        modal.toast({  
            message: "正在打开端口...",  
            duration: 1.5  
        });  
        var device = this.deviceArray[this.deviceIndex];  
        var baudrate = this.baudrateArray[this.baudrateIndex];  
        var databits = 8;  
        var parity = 0;  
        var stopbits = 0;  
        var flowcontrol = this.flowcontrolIndex;  
        handle = SSIOUniModule.SSIO_Port_OpenSerialPort(device, baudrate, databits, parity, stopbits, flowcontrol);  
        if (SSIOUniModule.SSIO_Port_IsOpened(handle)) {  
            this.message = "端口打开成功";  
            var portInfo = SSIOUniModule.SSIO_Port_GetPortInfoMap(handle);  
            modal.toast({  
                message: portInfo,  
                duration: 1.5  
            });  
        } else {  
            this.message = "端口打开失败";  
        }  
    }  

4 写数据/读数据/其他业务逻辑
例如:

    this.message = "正在写入...";  
    modal.toast({  
        message: "正在写入...",  
        duration: 1.5  
    });  
    if (SSIOUniModule.SSIO_Port_WriteBytesFromBase64String(handle, uni.arrayBufferToBase64(new Uint8Array([0x30, 0x31, 0x32, 0x0D, 0x0A]))) <= 0) {  
        this.message = "写入失败";  
        return;  
    }  
    if (SSIOUniModule.SSIO_Port_WriteStringUsingEncoding(handle, "Hello\r\n你好\r\n中國\r\n", "UTF-8") <= 0) {  
        this.message = "写入失败";  
        return;  
    }  
    if (SSIOUniModule.SSIO_Port_WriteStringUsingUTF8Encoding(handle, "Hello\r\n你好\r\n中國\r\n") <= 0) {  
        this.message = "写入失败";  
        return;  
    }  
    if (SSIOUniModule.SSIO_Port_WriteStringUsingGBKEncoding(handle, "Hello\r\n你好\r\n") <= 0) {  
        this.message = "写入失败";  
        return;  
    }  
    if (SSIOUniModule.SSIO_Port_WriteStringUsingBig5Encoding(handle, "Hello\r\n中國\r\n") <= 0) {  
        this.message = "写入失败";  
        return;  
    }  
    this.message = "写入成功"; 

5 关闭端口(或不关闭端口)
如果应用独占端口,则可以不用关闭端口,下次使用的时候直接用已有的句柄handle去操作。
如果是写完数据立刻关闭,部分端口可能需要延时,具体请看例子,里面每个接口都有测试例子,很详细。

    if (SSIOUniModule.SSIO_Port_IsOpened(handle)) {
        this.message = this.currentDateTime() + "\r\n" +
            "正在关闭端口...";
        SSIOUniModule.SSIO_Port_Close(handle);
        this.message = this.currentDateTime() + "\r\n" +
            "端口已关闭";
    }

6 列举当前已打开端口(句柄忘记保存的时候,可以通过这种方式找回)
例如

    //注意句柄一定要自己管理好。
    //如果有端口未关闭,然后又没有保存端口句柄,可以通过如下方式来找回句柄。
    var handleList = SSIOUniModule.SSIO_Port_GetPortHandleList();
    for (let i = 0; i < handleList.length; i++) {
        if (SSIOUniModule.SSIO_Port_IsOpened(handleList[i])) {
            var portInfo = SSIOUniModule.SSIO_Port_GetPortInfoMap(handleList[i]);
            this.message += handleList[i] + " " + JSON.stringify(portInfo, false, 4) + "\n";
        }
    }

7 权限配置
权限配置要正确,不然用不了,app会闪退,具体参考例子的manifest.json文件
如下是部分关键片段

    /* 应用发布信息 */
    "distribute" : {
        /* android打包配置 */
        "android" : {
            "permissions" : [
                "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
                "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
                "<uses-permission android:name=\"android.permission.BLUETOOTH\"/>",
                "<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\"/>",
                "<uses-permission android:name=\"android.permission.BLUETOOTH_PRIVILEGED\"/>",
                "<uses-permission android:name=\"android.permission.INTERNET\"/>"
            ],
            "abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ]
        },
        /* ios打包配置 */
        "ios" : {
            "dSYMs" : false,
            "idfa" : false,
            "privacyDescription" : {
                "NSBluetoothPeripheralUsageDescription" : "需要通过蓝牙与外部设备通讯",
                "NSBluetoothAlwaysUsageDescription" : "需要通过蓝牙与外部设备通讯",
                "NSLocalNetworkUsageDescription" : "需要通过网络与外部设备通讯"
            },
            "UIBackgroundModes" : "bluetooth-central"
        },
        /* SDK配置 */
        "sdkConfigs" : {
            "ad" : {}
        }
    },

接口列表及说明

SSIO_Plugin_Version

String SSIO_Plugin_Version()  

获取SSIO插件版本
可用于验证插件是否正确加载,如果能取得版本号,证明插件配置成功。

SSIO_Port_OpenTcp

long SSIO_Port_OpenTcp(String dest_ip, int dest_port, String local_ip, int local_port, int timeout_ms)  

打开TCP连接
dest_ip:目标IP
dest_port:目标端口
local_ip:是否绑定到特定本地IP,可不填
local_port:是否绑定到特定本地端口,可填0表示自动选择本地可用端口
timeout_ms:连接超时毫秒时间
返回端口句柄

SSIO_Port_OpenUdp

long SSIO_Port_OpenUdp(String dest_ip, int dest_port, String local_ip, int local_port)  

打开UDP连接
dest_ip:目标IP
dest_port:目标端口
local_ip:是否绑定到特定本地IP,可不填
local_port:是否绑定到特定本地端口,可填0表示自动选择本地可用端口
返回端口句柄

SSIO_Port_OpenBtSpp

long SSIO_Port_OpenBtSpp(String address, int secure, int timeout_ms)  

打开蓝牙SPP连接
address:蓝牙地址,可以通过搜索得到蓝牙设备信息
secure:是否是安全连接,1表示安全,0表示不安全。当服务器和客户端都使用不安全连接时,SPP连接无需密码即可通讯。
timeout_ms:连接超时毫秒时间
返回端口句柄

SSIO_Port_OpenBtBle

long SSIO_Port_OpenBtBle(String address, int timeout_ms)  

打开蓝牙BLE连接
address:蓝牙地址,可以通过搜索得到蓝牙设备信息
timeout_ms:连接超时毫秒时间
返回端口句柄

SSIO_Port_OpenUsb

long SSIO_Port_OpenUsb(Map<String, String> matchingInfoMap)  

打开USB设备连接
matchingInfoMap:设备匹配信息。可任意指定一个或多个信息,匹配成功则打开对应的USB设备连接。
支持匹配的字段有:DeviceName、VendorId、ProductId、ManufacturerName、ProductName、SerialNumber、InterfaceClass、InterfaceSubclass、InterfaceProtocol。
如果无权限会自动申请权限,取得权限后会继续后续打开动作,使用方便。
返回端口句柄

SSIO_Port_OpenSerialPort

long SSIO_Port_OpenSerialPort(String device, int baudrate, int databits, int parity, int stopbits, int flowcontrol)  

打开串口设备连接
device:串口设备路径,比如/dev/ttyS0、/dev/ttyUSB0等。
baudrate:波特率
databits:数据位
parity:校验,支持0-无校验 1-奇校验 2-偶校验 3-标记校验 4-空白校验
stopbits:停止位 支持0-一位停止位 2-两位停止位
flowcontrol:流控制 支持0-无流控 1-XonXoff 2-RTS/CTS
返回端口句柄

SSIO_Port_IsOpened

boolean SSIO_Port_IsOpened(long handle)  

端口是否已打开
handle:端口句柄
备注:TCP/蓝牙/USB这三个端口能识别到对端断开。串口和UDP识别不到。

SSIO_Port_Close

void SSIO_Port_Close(long handle)  

关闭端口
handle:端口句柄
备注:如果端口不用了,要记得关闭端口。如果不关闭端口,并且也不保存句柄handle。
那么那个端口就相当于内部已经打开了,但是外面无法访问到,会有问题的。

SSIO_Port_GetPortHandleList

List<Long> SSIO_Port_GetPortHandleList()  

获取端口句柄列表

SSIO_Port_GetPortInfoMap

Map<String, String> SSIO_Port_GetPortInfoMap(long handle)  

获取端口信息
handle:端口句柄

SSIO_Port_WriteBytesFromBase64String

int SSIO_Port_WriteBytesFromBase64String(long handle, String bytesBase64String)  

写字节数组,但是字节数组无法作为参数直接传递给插件模块,因此字节数组从Base64String转过来
handle:端口句柄
bytesBase64String:字节数组base64字符串
返回写入的字节数,返回-1表示写入失败。

SSIO_Port_WriteStringUsingEncoding

int SSIO_Port_WriteStringUsingEncoding(long handle, String str, String encoding)  

将字符串按照指定编码发送
handle:端口句柄
str:要发送的字符串
encoding:指定的编码
返回写入的字节数,返回-1表示写入失败。
备注:可通过SSIO_Encoding_GetAvailableEncodingList接口获取编码列表

SSIO_Port_WriteStringUsingUTF8Encoding

int SSIO_Port_WriteStringUsingUTF8Encoding(long handle, String str)  

将字符串按照UTF8编码发送

SSIO_Port_WriteStringUsingGBKEncoding

int SSIO_Port_WriteStringUsingGBKEncoding(long handle, String str)  

将字符串按照GBK编码发送

SSIO_Port_WriteStringUsingBig5Encoding

int SSIO_Port_WriteStringUsingBig5Encoding(long handle, String str)  

将字符串按照Big5编码发送

SSIO_Port_ReadBytesToBase64String

String SSIO_Port_ReadBytesToBase64String(long handle, int byteCountToRead)  

读字节数组,但是字节数组不能作为结果直接返回,那字节数组怎么传出去?字节数组转成Base64String传出去。
handle:端口句柄
byteCountToRead:要读取的字节数
返回字节数组base64字符串,调用者需解码得到原始字节数组,如下:

var bytesBase64String = SSIOUniModule.SSIO_Port_ReadBytesToBase64String(handle, 0x100);  
var bytes = new Uint8Array(uni.base64ToArrayBuffer(bytesBase64String));  
if (bytes.length > 0) {  
    var str = "读取字节数:" + bytes.length + "\r\n";  
    for (let i = 0; i < bytes.length; i++) {  
        var hex = bytes[i].toString(16);  
        if (hex.length == 1)  
            hex = "0" + hex;  
        str += hex;  
        str += " ";  
    }  
    str += "\r\n";  
    this.message = str;  
} else {  
    this.message = "无数据可读";  
}  

SSIO_Port_BtBle_SetWriteCharacteristic

boolean SSIO_Port_BtBle_SetWriteCharacteristic(long handle, String characteristicUUIDString)  

指定BLE写属性
handle:端口句柄
characteristicUUIDString:属性UUID

SSIO_Port_BtBle_EnableCharacteristicNotification

boolean SSIO_Port_BtBle_EnableCharacteristicNotification(long handle, String characteristicUUIDString)  

启用BLE属性通知,只有启用了属性通知,才能自动收到对端传来的数据。
handle:端口句柄
characteristicUUIDString:属性UUID

SSIO_Port_BtBle_GetCharacteristicListWithWriteProperty

List<String> SSIO_Port_BtBle_GetCharacteristicListWithWriteProperty(long handle)  

获取BLE写属性列表
handle:端口句柄

SSIO_Port_BtBle_GetCharacteristicListWithNotifyProperty

List<String> SSIO_Port_BtBle_GetCharacteristicListWithNotifyProperty(long handle)  

获取BLE通知属性列表
handle:端口句柄

SSIO_Port_SerialPort_GetModemStatus

Map<String, String> SSIO_Port_SerialPort_GetModemStatus(long handle)  

获取串口Modem状态
handle:端口句柄

SSIO_SerialPort_GetDeviceList

List<String> SSIO_SerialPort_GetDeviceList()  

获取串口设备列表

SSIO_BluetoothAdapter_HasBluetoothPermissions

boolean SSIO_BluetoothAdapter_HasBluetoothPermissions()  

检查是否有蓝牙权限,如果没有蓝牙权限,则搜不到蓝牙并且连不上蓝牙设备

SSIO_BluetoothAdapter_RequestBluetoothPermissions

void SSIO_BluetoothAdapter_RequestBluetoothPermissions(int requestCode)   

请求蓝牙权限
requestCode:activity回调用的,可以随便填。比如11111。

SSIO_BluetoothAdapter_GetBondedDevices

List<Map<String, String>> SSIO_BluetoothAdapter_GetBondedDevices()  

获得蓝牙已配对设备列表

SSIO_BluetoothAdapter_GetDiscoveredDevices

List<Map<String, String>> SSIO_BluetoothAdapter_GetDiscoveredDevices()  

获得蓝牙已搜索设备列表

SSIO_BluetoothAdapter_ClearDiscoveredDevices

void SSIO_BluetoothAdapter_ClearDiscoveredDevices()  

清除蓝牙已搜索设备列表

SSIO_BluetoothAdapter_IsDiscovering

boolean SSIO_BluetoothAdapter_IsDiscovering()  

蓝牙是否在搜索中

SSIO_BluetoothAdapter_StartDiscovery

boolean SSIO_BluetoothAdapter_StartDiscovery(final UniJSCallback deviceFoundCallback, final UniJSCallback discoveryFinishedCallback)  

开始搜索蓝牙设备
deviceFoundCallback:搜到设备回调
discoveryFinishedCallback:搜索结束回调(搜索一般是12秒)

SSIO_UsbManager_GetUsbDevices

List<Map<String, Object>> SSIO_UsbManager_GetUsbDevices()  

获取USB设备列表

SSIO_Encoding_GetAvailableEncodingList

List<String> SSIO_Encoding_GetAvailableEncodingList()  

获取可用字符编码列表

SSIO_Misc_SleepMs

void SSIO_Misc_SleepMs(int ms)  

延时一段时间

隐私、权限声明

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

蓝牙权限、定位权限、网络权限。

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

插件不采集任何数据

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

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