IM岁月无痕
IM岁月无痕
  • 发布:2019-11-12 20:31
  • 更新:2019-11-12 20:39
  • 阅读:1555

关于Native.JS蓝牙问题

分类:uni-app
'use strict';  

var EE = require('events').EventEmitter;  
var util = require('util');  

var BluetoothTool = function(callback) {  
    console.log("BluetoothPort/used");  
    EE.call(this);  
    var BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");  
    this.mAdapter = BluetoothAdapter.getDefaultAdapter();  
    this.BluetoothAdapter = BluetoothAdapter;  
    this.BTSocket = null;  
    var args = Array.prototype.slice.call(arguments);  
    callback = args.pop();  
    if (typeof(callback) !== 'function') {  
        callback = null;  
    }  
}  

util.inherits(BluetoothTool, EE);  
/**    
 * 是否支持蓝牙    
 * @return {boolean}    
 */  
BluetoothTool.prototype.isSupportBluetooth = function() {  
    var mAdapter = this.mAdapter;  
    if (mAdapter != null) {  
        return true;  
    }  
    return false;  
}  
/**    
 * 获取蓝牙的状态    
 * @return {boolean} 是否已开启    
 */  
BluetoothTool.prototype.getBluetoothStatus = function() {  
    var mAdapter = this.mAdapter;  
    if (mAdapter != null) {  
        return mAdapter.isEnabled();  
    }  
    return false;  
}  

/**    
 * 打开蓝牙    
 * @param activity    
 * @param requestCode    
 */  
BluetoothTool.prototype.turnOnBluetooth = function(activity, requestCode) {  
    var mAdapter = this.mAdapter;  
    if (mAdapter != null && !mAdapter.isEnabled()) {  
        var Intent = plus.android.importClass("android.content.Intent");  
        var intent = new Intent(this.BluetoothAdapter.ACTION_REQUEST_ENABLE);  
        activity.startActivityForResult(intent, requestCode);  
    }  
}  

/**    
 * 关闭蓝牙    
 */  
BluetoothTool.prototype.turnOffBluetooth = function() {  
    if (this.mAdapter != null && this.mAdapter.isEnabled()) {  
        this.mAdapter.disable();  
        this.BTSocket = null;  
    }  
}  

/**    
 * 获取已经配对的设备    
 * @return {Array} connetedDevices    
 */  
BluetoothTool.prototype.getConnetedDevices = function() {  
    var mAdapter = this.mAdapter;  
    var connetedDevices = [];  

    //蓝牙连接android原生对象,是一个set集合    
    var connetedDevicesAndroid = null;  
    if (mAdapter != null && mAdapter.isEnabled()) {  
        connetedDevicesAndroid = mAdapter.getBondedDevices();  
    }  

    if (!connetedDevicesAndroid) {  
        return connetedDevices;  
    }  

    //遍历连接设备的set集合,转换为js数组    
    var invoke = plus.android.invoke;  
    var it = invoke(connetedDevicesAndroid, "iterator");  
    while (plus.android.invoke(it, "hasNext")) {  
        var device = plus.android.invoke(it, "next");  
        connetedDevices.push({  
            "Name": plus.android.invoke(device, "getName"),  
            "Address": plus.android.invoke(device, "getAddress")  
        });  
    }  
    return connetedDevices;  
}  

/**    
 * 发现新设备    
 * @param {Object} activity 当前活动界面    
 * @param {Object} newDevices 用于接收发现的设备    
 */  
BluetoothTool.prototype.findDevices = function(activity, newDevices) {  
    var self = this;  
    var mAdapter = this.mAdapter;  

    var IntentFilter = plus.android.importClass("android.content.IntentFilter");  
    var BluetoothDevice = plus.android.importClass("android.bluetooth.BluetoothDevice");  
    var filter = new IntentFilter();  
    var BroadcastReceiver = plus.android.importClass("android.content.BroadcastReceiver");  
    newDevices = [];  
    var BTReceiver = plus.android.implements("io.dcloud.android.content.BroadcastReceiver", {  
        "onReceive": function(context, intent) {  
            plus.android.importClass(context);  
            plus.android.importClass(intent);  

            var action = intent.getAction();  
            //发现了设备    
            if (BluetoothDevice.ACTION_FOUND == action) {  
                //从Intent中获取设备的BluetoothDevice对象    
                var device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  
                newDevices.push({  
                    "Name": plus.android.invoke(device, "getName"),  
                    "Address": plus.android.invoke(device, "getAddress")  
                });  
                self.emit('BluetoothList', newDevices);  
            }  
        }  
    });  

    filter.addAction(BluetoothDevice.ACTION_FOUND);  
    filter.addAction(this.BluetoothAdapter.ACTION_DISCOVERY_FINISHED);  
    activity.registerReceiver(BTReceiver, filter);  
    mAdapter.startDiscovery(); //开启搜索    
}  

/**    
 * 根据蓝牙地址,连接设备    
 * @param {Object} address    
 * @return {Boolean}    
 */  
BluetoothTool.prototype.connDevice = function(activity, address) {  
    var self = this;  
    var invoke = plus.android.invoke;  
    var mAdapter = this.mAdapter;  
    var device = invoke(mAdapter, "getRemoteDevice", address);  

    var UUID = plus.android.importClass("java.util.UUID");  
    var InputStream = plus.android.importClass("java.io.InputStream");  
    var OutputStream = plus.android.importClass("java.io.OutputStream");  
    var BluetoothSocket = plus.android.importClass("android.bluetooth.BluetoothSocket");  
    var MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");  
    var BTSocket = null;  
    // console.log(MY_UUID);  
    try {  
        BTSocket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);  
        plus.android.importClass(BTSocket);  
    } catch (e) {  
        console.log("连接失败,获取Socket失败");  
        return false;  
    }  
    try {  
        BTSocket.connect();  
        // Toast.makeText(activity, "连接成功", Toast.LENGTH_SHORT).show();  
    } catch (e) {  
        console.log("连接失败");  
        // Toast.makeText(activity, "连接失败", Toast.LENGTH_SHORT).show();  
        try {  
            BTSocket.close();  
            BTSocket = null;  
        } catch (e1) {  

        }  
        return false;  
    };  
    console.log("连接成功", BTSocket);  
    self.BTSocket = BTSocket;  
    self.emit('open');  
    return true;  
}  

/**    
 * 读取数据    
 * @param {Object} activity    
 * @param {Function} callback    
 * @return {Boolean}    
 */  
BluetoothTool.prototype.AtCmd = function(str) {  
    var self = this;  
    console.log("xiexiexei", str);  
    var bytes = plus.android.invoke(str, 'getBytes', 'gbk');  
    // this.BTOutStream.write(bytes);  
    console.log("xiexiexei", str, bytes);  
    self.BTInStream.write(str);  
}  

BluetoothTool.prototype.readData = function(activity, str) {  
    console.log("开始创建数据流");  
    var self = this;  
    var invoke = plus.android.invoke;  
    var BTSocket = this.BTSocket;  
    if (!BTSocket) {  
        console.log("请先连接蓝牙设备");  
        return false;  
    }  
    try {  
        var BTInStream = BTSocket.getInputStream();  
        var BTOutStream = BTSocket.getOutputStream();  
    } catch (e) {  
        console.log("创建输入输出流失败");  
        try {  
            BTSocket.close();  
            BTSocket = null;  
        } catch (e1) {}  
        return false;  
    };  
    var readThreadState = false;  

    var s = plus.android.importClass('java.lang.String');  
    var string = new s(str); //必须以创建字符串对象的形式创建对象,否则返回NULL    
    var bytes = string.getBytes('gbk');  
    BTOutStream.write(bytes);  

    readData();  
    return true;  

    function readData() {  
        if (readThreadState) {  
            return;  
        }  
        console.log("开始监听获取流");  
        var count = 0;  
        while (BTSocket.isConnected()) {  //这里严重*******  
            // console.log("获取流");  
            readThreadState = true;  
            count++;  
            var data = BTInStream.read();  
            console.log(data);  
            self.emit('indata',String.fromCharCode(data));  
            if (data == 62) {  
                break;  
            }  
        }  
    }  
};  

function hexCharCodeToStr(hexCharCodeStr) {  
  var trimedStr = hexCharCodeStr.trim();  
  var rawStr =   
  trimedStr.substr(0,2).toLowerCase() === "0x"  
  ?   
  trimedStr.substr(2)   
  :   
  trimedStr;  
  var len = rawStr.length;  
  if(len % 2 !== 0) {  
    alert("Illegal Format ASCII Code!");  
    return "";  
  }  
  var curCharCode;  
  var resultStr = [];  
  for(var i = 0; i < len;i = i + 2) {  
    curCharCode = parseInt(rawStr.substr(i, 2), 16); // ASCII Code Value  
    resultStr.push(String.fromCharCode(curCharCode));  
  }  
  return resultStr.join("");  
};  

module.exports = {  
    BluetoothPort: BluetoothTool,  
    used: []  
};

想请问,如何多线程监听返回流和多线程发送,因为发送接收频率很高(串口类),100ms基本一个包,readData 总会阻塞,需要等到上一个包完成,才能继续下一个包,而且是单字节,需要循环获取。

2019-11-12 20:31 负责人:无 分享
已邀请:
IM岁月无痕

IM岁月无痕 (作者)

还有个问题,在发送接收期间,界面会卡死,想问各位大佬可以改善不?我这个设备低功耗蓝牙不能用,所有采用的这种方式

该问题目前已经被锁定, 无法添加新回复