vue app混合开发蓝牙串口连接(报错java.io.IOException: read failed, socket might closed or timeout, read ret: -1;at android.bluetooth.BluetoothSocket.connect at js/BluetoothTool.js:329)

我使用的 uni-app
<template>
    <view class="bluetooth">
        <!-- 发送数据 -->
        <view class="send" v-if="send_data_onoff">
            <view class="uni-textarea">
                <textarea placeholder-style="color:#F76260" v-model="send_data_list" placeholder="请输入发送数据"/>
                <view @tap="send_data" class="fasong"> 发送 </view>
            </view>
        </view>
        <!-- 没有匹配的蓝牙设备 -->
        <view class="no_match_bluetooth_list" v-if="no_match_list.length!=0">
            <view class="h1"> 已搜索的蓝牙:</view>
            <block  v-for="(item,index) in no_match_list" :key="index">
                <view class="uni-list" @tap="search_bluetooth(item.SN)">
                    <view class="uni-list-cell" hover-class="uni-list-cell-hover">
                        <view class="uni-list-cell-navigate uni-navigate-right uni-media-list ">
                            <view class="uni-media-list-body">
                                <view> 蓝牙名称:{{item.name}}</view>
                                <view>SN:{{item.SN}}</view>
                            </view>
                        </view>
                    </view>
                </view>
            </block>
        </view>
    &lt;!-- 已匹配的蓝牙设备 --&gt;
    &lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">no_match_bluetooth_list</span><span style="color: rgba(128, 0, 0, 1)">"</span> v-<span style="color: rgba(0, 0, 255, 1)">if</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">match_list.length!=0</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
        &lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">h1</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;已匹配的蓝牙:&lt;/view&gt;
        &lt;block  v-<span style="color: rgba(0, 0, 255, 1)">for</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">(item,index) in match_list</span><span style="color: rgba(128, 0, 0, 1)">"</span> :key=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">index</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
            &lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">uni-list</span><span style="color: rgba(128, 0, 0, 1)">"</span> @tap=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">print(item.SN)</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
                &lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">uni-list-cell</span><span style="color: rgba(128, 0, 0, 1)">"</span> hover-<span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">uni-list-cell-hover</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
                    &lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">uni-list-cell-navigate uni-navigate-right uni-media-list </span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
                        &lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">uni-media-list-body</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
                            &lt;view&gt;蓝牙名称:{{item.name}}&lt;/view&gt;
                            &lt;view&gt;SN:{{item.SN}}&lt;/view&gt;
                        &lt;/view&gt;
                    &lt;/view&gt;
                &lt;/view&gt;
            &lt;/view&gt;
        &lt;/block&gt;
    &lt;/view&gt;
    
    
    
    &lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">btn</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
        &lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">btn_1</span><span style="color: rgba(128, 0, 0, 1)">"</span> @tap=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">open_bluetooth</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;打开蓝牙&lt;/view&gt;
        &lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">btn_2</span><span style="color: rgba(128, 0, 0, 1)">"</span> @tap=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">close_bluetooth</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;关闭蓝牙&lt;/view&gt;
        &lt;view <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">btn_3</span><span style="color: rgba(128, 0, 0, 1)">"</span> @tap=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">search_bluetooth</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;搜索蓝牙&lt;/view&gt;
    &lt;/view&gt;
&lt;/view&gt;

</template>

<script>
var main, Context, BluetoothManager, BluetoothAdapter, BManager, BAdapter,BluetoothDevice,IntentFilter,bluetoothSocket,device;
export
default {
data() {
return {
bArray:[],
//用于搜索蓝牙去重用的
no_match_list:[],//没有配对的蓝牙列表
match_list:[],//已配对的蓝牙列表
send_data_onoff:false,
send_data_list:
'',//要发送的数据
};
},
onShow() {
//获取 android 应用 Activity 对象
main = plus.android.runtimeMainActivity();
Context
= plus.android.importClass("android.content.Context");
BManager
= main.getSystemService(Context.BLUETOOTH_SERVICE);
//蓝牙适配器
BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
//蓝牙本地适配器
BAdapter = BluetoothAdapter.getDefaultAdapter();
//蓝牙设备
BluetoothDevice = plus.android.importClass('android.bluetooth.BluetoothDevice');
//过滤器
IntentFilter = plus.android.importClass('android.content.IntentFilter');
},
methods:{
/
* 根据蓝牙地址,连接设备
* @param {Object} address
* @return {Boolean}
*/
print(address){
console.log(address)
let that
=this
uni.showModal({
title:
'提示',
content:
'是连接此蓝牙?',
success: function (res) {
if (res.confirm) {
console.log(
'用户点击确定');
uni.showLoading({
title:
'蓝牙连接中...'
});
that.print_bluetooth(address)

                    }
                }
            });
        },
        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">连接蓝牙</span>

print_bluetooth(mac_address){
let that
=this
uni.hideLoading()
let UUID
= plus.android.importClass("java.util.UUID");
let uuid
= UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
device
= BAdapter.getRemoteDevice(mac_address);
plus.android.importClass(device);
bluetoothSocket
= device.createInsecureRfcommSocketToServiceRecord(uuid);
plus.android.importClass(bluetoothSocket);
if (!bluetoothSocket.isConnected()) {
console.log(
'检测到设备未连接,尝试连接....');
bluetoothSocket.connect();
}
console.log(
'设备已连接');
// 打开输入发送数据
that.send_data_onoff=true;

        },
        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">发送蓝牙数据</span>

send_data(){
let that
=this
console.log()
if (bluetoothSocket.isConnected()) {
console.log(
22222)
var outputStream = bluetoothSocket.getOutputStream();
plus.android.importClass(outputStream);
var string = that.send_data_list
var bytes = plus.android.invoke(string, 'getBytes', 'gbk');//创建输出流失败
outputStream.write(bytes);
// outputStream.flush();
// device = null //这里关键
// bluetoothSocket.close(); //必须关闭蓝牙连接否则意外断开的话打印错误
}
},
open_bluetooth(){
if(!BAdapter.isEnabled()) {
BAdapter.enable();
//启动蓝牙
uni.showToast({
title:
'蓝牙已启动',
duration:
2000
})
}
},
//关闭蓝牙
close_bluetooth(){
let that
=this
//关闭蓝牙都把之前的清空
that.no_match_list=[];
that.match_list
=[]
if (BAdapter.isEnabled()) {
BAdapter.disable();
//关闭蓝牙
uni.showToast({
title:
'蓝牙已关闭',
duration:
2000
})
}
},
//获取已匹配蓝牙设备
bluetooth_list(){
let that
=this
//先清空
that.match_list=[]

            </span><span style="color: rgba(0, 0, 255, 1)">var</span> lists =<span style="color: rgba(0, 0, 0, 1)"> BAdapter.getBondedDevices();
            plus.android.importClass(lists);
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> iterator =<span style="color: rgba(0, 0, 0, 1)"> lists.iterator();
            plus.android.importClass(iterator);
            </span><span style="color: rgba(0, 0, 255, 1)">while</span><span style="color: rgba(0, 0, 0, 1)"> (iterator.hasNext()) {
                </span><span style="color: rgba(0, 0, 255, 1)">var</span> d =<span style="color: rgba(0, 0, 0, 1)"> iterator.next();
                plus.android.importClass(d);
                let arr</span>=<span style="color: rgba(0, 0, 0, 1)">{
                    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: d.getName(),
                    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">SN</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: d.getAddress()
                }
                that.match_list.push(arr)
            }
        },
        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">搜索没匹配的蓝牙设备</span>

search_bluetooth(address){
let that
=this
//判断蓝牙是否开启
if (!BAdapter.isEnabled()) {
uni.showToast({
title:
'请先打开蓝牙',
duration:
3000
});
return
}
if(address.length!=undefined){
uni.showModal({
title:
'提示',
content:
'是否配对此蓝牙?',
success: function (res) {
if (res.confirm) {
console.log(
'用户点击确定');
uni.showLoading({
title:
'蓝牙匹配中...'
});
that.search_pipei(address)
}
}
});
}
else{
uni.showLoading({
title:
'蓝牙搜索中...'
});
that.search_pipei()
}
},
//搜索和匹配蓝牙
search_pipei(address){
let that
=this
//获取已匹配的蓝牙
that.bluetooth_list()
//每次搜索都把之前的清空
that.bArray=[];
that.no_match_list
=[];

            </span><span style="color: rgba(0, 0, 255, 1)">var</span> filter = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> IntentFilter();
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> BDevice = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> BluetoothDevice();
            BAdapter.startDiscovery(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">开启搜索</span>
            <span style="color: rgba(0, 0, 255, 1)">var</span> receiver = plus.android.implements(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">io.dcloud.android.content.BroadcastReceiver</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, {
                onReceive: function(context, intent) { </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">回调</span>
                    <span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {               
                        plus.android.importClass(intent); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">通过intent实例引入intent类</span>
                        <span style="color: rgba(0, 0, 255, 1)">if</span>(intent.getAction() == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">android.bluetooth.adapter.action.DISCOVERY_FINISHED</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">) {
                            uni.hideLoading()
                            main.unregisterReceiver(receiver); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">取消监听 </span>
                        } <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
                            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">从Intent中获取设备对象</span>
                            BDevice=<span style="color: rgba(0, 0, 0, 1)"> intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">配对蓝牙</span>
                            <span style="color: rgba(0, 0, 255, 1)">if</span> (address ==<span style="color: rgba(0, 0, 0, 1)"> BDevice.getAddress()) {
                                </span><span style="color: rgba(0, 0, 255, 1)">if</span> (BDevice.createBond()) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">配对命令.createBond()</span>
                                    console.log(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">配对成功</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
                                    uni.hideLoading()
                                }
            
                            }
                            </span><span style="color: rgba(0, 0, 255, 1)">if</span>(BDevice == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
                                main.unregisterReceiver(receiver); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">取消监听</span>

uni.hideLoading()
//获取已匹配的蓝牙
that.bluetooth_list()
return;
}
var name=BDevice.getAddress()+BDevice.getName();
if(that.bArray.indexOf(name) == -1){ //去重
that.bArray.push(name);//用于去重的
let arr={
"name": BDevice.getName(),
"SN": BDevice.getAddress()
}
that.no_match_list.push(arr)
console.log(JSON.stringify(that.no_match_list))
}

                        }
                    } </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)">(e) {
                        console.error(e);
                    }
                }
            });
            filter.addAction(BDevice.ACTION_FOUND);
            filter.addAction(BAdapter.ACTION_DISCOVERY_STARTED);
            filter.addAction(BAdapter.ACTION_DISCOVERY_FINISHED);
            filter.addAction(BAdapter.ACTION_STATE_CHANGED);
            main.registerReceiver(receiver, filter); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">注册监听 </span>

},
}
}
</script>

<style scoped="scoped" lang="scss">
@import
"./Bluetooth.scss";
</style>

css

.bluetooth{
    padding: 20upx 20upx 120upx;
    .h1{
        padding: 20upx 0;color: #1482D1;border-top: 1upx solid #EFEFF4;
    }
.btn{
    display:flex;position:</span><span style="color: rgba(0, 0, 255, 1)">fixed</span>;bottom:0upx;padding:20upx 10upx;justify-content:space-around;width: <span style="color: rgba(128, 0, 128, 1)">100</span>%;color:#fff;border-top:1px solid #f2f2f2;background-<span style="color: rgba(0, 0, 0, 1)">color: #fff;
    view{
        width: 200upx;height: 80upx;line</span>-height:80upx;text-align: center;border-<span style="color: rgba(0, 0, 0, 1)">radius:10upx;
    }
    .btn_1{
        background</span>-<span style="color: rgba(0, 0, 0, 1)">color: #009BDE;
    }
    .btn_2{
        background</span>-<span style="color: rgba(0, 0, 0, 1)">color: red;
    }
    .btn_3{
        background</span>-<span style="color: rgba(0, 0, 0, 1)">color: #3CB371;
    }
}
.uni</span>-<span style="color: rgba(0, 0, 0, 1)">textarea{
    textarea{
        border: 1px solid #EFEFF4;border</span>-radius: 10px;width: <span style="color: rgba(128, 0, 128, 1)">100</span>%;padding: 10upx;box-sizing: border-<span style="color: rgba(0, 0, 0, 1)">box;
    }
    .fasong{
        width: </span><span style="color: rgba(128, 0, 128, 1)">100</span>%;padding:15upx 10upx;box-sizing: border-box;border-radius: 10px;background: #1482D1;text-align: center;color: white;margin: 10px <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
    }
}

}

如果报错你可能需要下载一个蓝牙开发助手当服务端