1***@163.com
1***@163.com
  • 发布:2021-04-09 10:07
  • 更新:2026-08-06 08:41
  • 阅读:1950

uniapp什么时候能出一个支持经典蓝蓝牙的api,最好加上文件传输

分类:uni-app

uniapp什么时候能出一个支持经典蓝蓝牙的api,最好加上文件传输,可以传输数据量大效率高的api

2021-04-09 10:07 负责人:无 分享
已邀请:
Azikou

Azikou

2022年3.25了 还是没有。逼着搞nativejs 烦躁

徐州老铁

徐州老铁 - 开发者

2024了还没有

1***@qq.com

1***@qq.com

2025也没有

Azikou

Azikou

我自己写了个蓝牙插件了。

  • 仙古梦回

    请问一下连接蓝牙的时候如何被连接的设备未开启导致页面长时间卡顿是怎么解决的?卡在这好几天了,用thread开子线程也没用

    const bluetoothSocket = device.createRfcommSocketToServiceRecord(uuid);

    bluetoothSocket.connect();

    2026-03-16 17:45

  • Azikou

    回复 仙古梦回: if (this.mSocket == null) {

    try {

    this.mSocket = remoteDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));

    // Log.d(TAG, "this.mSocket1: " + this.mSocket);

    this.mID++;

    } catch (IOException e) {

    // 处理异常

    }


                    }  
    this.readThread = createReadThread();
    this.readThread.start();

    2026-03-19 08:31

c***@163.com

c***@163.com

2026也没有

  • Azikou

    2026年了 买个月ai,鞭策它写一个

    2026-07-15 13:18

1***@qq.com

1***@qq.com - 23

主要难点是把文件转arraybuffer,
<template>
<view class="content">
<button type="primary" @click="selectImage" class="select-btn">
选择文件
</button>

    <view v-if="loading" class="loading-wrapper">  
        <text class="loading-text">处理中...</text>  
    </view>  

    <view v-if="error" class="error-wrapper">  
        <text class="error-text">{{ error }}</text>  
    </view>  

    <xe-upload ref="XeUpload" :options="uploadOptions" @callback="handleUploadCallback"></xe-upload>  
</view>  

</template>

<script>
export default {
data() {
return {
imageInfo: null,
loading: false,
error: '',
uploadOptions: {

            },  
        }  
    },  
    onLoad() {  

    },  
    methods: {  
        handleUploadCallback(res) {  
            console.log("选择文件:", res);  
            if (res && res.data) {  

                    let tempFilePath=res.data[0].tempFilePath;  
                this.execCovert(tempFilePath);  

            } else {  
                console.log("未选择任何文件");  
            }  
        },  
        selectImage() {  
            this.imageInfo = null;  
            this.error = '';  

            // #ifdef APP-PLUS  
            this.loading = true;  
            this.chooseImageFromAlbum();  
            // #endif  

            // #ifndef APP-PLUS  
            this.error = '此功能仅支持 App 端(5+ 运行时)';  
            // #endif  
        },  

        chooseImageFromAlbum() {  
            //选择文件  
            this.$refs.XeUpload.upload('file');  

            //选择视频  
            // uni.chooseVideo({  
            //  sourceType: ['album'],  
            //  compressed: false, // 关闭视频压缩  
            //  success: (res) => {  

            //      let tempFilePath = res.tempFilePath;  
            //      this.execCovert(tempFilePath);  
            //  }  
            // });  

            //选择图片  
            // uni.chooseImage({  
            //  count: 1,  
            //  sizeType: ['compressed'],  
            //  sourceType: ['album'],  
            //  success: (res) => {  
            //      const tempFilePath = res.tempFilePaths[0];  
            //      console.log('选择图片路径:', tempFilePath);  
            //      this.execCovert(tempFilePath);  

            //  },  
            //  fail: (err) => {  
            //      console.error('选择图片失败:', err);    
            // });  
        },  
        execCovert(tempFilePath) {  
            this.readFileAsArrayBuffer(tempFilePath)  
                .then((arrayBuffer) => {  
                    const uint8Array = new Uint8Array(arrayBuffer);  
                    let str = Array.from(uint8Array)  
                        .map(b => b.toString(16).padStart(2, '0').toUpperCase())  
                        .join(' ');  

                    console.log("str=", str);//  

                    this.loading = false;  
                })  
                .catch((err) => {  
                    console.error('读取失败:', err);  
                    this.error = typeof err === 'string' ? err : (err.message || '读取文件失败');  
                    this.loading = false;  
                });  
        },  
        // ✅ 核心方法:通过 DataURL 转为 ArrayBuffer  
        readFileAsArrayBuffer(filePath) {  
            return new Promise((resolve, reject) => {  
                if (!filePath) {  
                    return reject(new Error('文件路径不能为空'));  
                }  

                try {  
                    // #ifdef APP-PLUS  
                    const plusPath = plus.io.convertLocalFileSystemURL(filePath);  
                    console.log('转换后的路径:', plusPath);  

                    const reader = new plus.io.FileReader();  

                    reader.onloadend = (e) => {  
                        const dataUrl = e.target.result;  
                        if (dataUrl) {  
                            try {  
                                // 将 DataURL 转为 ArrayBuffer  
                                const arrayBuffer = this.dataURLToArrayBuffer(dataUrl);  
                                resolve(arrayBuffer);  
                            } catch (err) {  
                                reject(new Error('DataURL 转换失败:' + err.message));  
                            }  
                        } else {  
                            reject(new Error('读取结果为空'));  
                        }  
                    };  

                    reader.onerror = (err) => {  
                        console.error('FileReader error:', err);  
                        reject(new Error('文件读取错误:' + (err.target ? err.target.error : JSON.stringify(  
                            err))));  
                    };  

                    reader.readAsDataURL(plusPath);  
                    // #endif  

                    // #ifndef APP-PLUS  
                    reject(new Error('plus.io 仅支持 App 端'));  
                    // #endif  
                } catch (e) {  
                    reject(new Error('执行异常:' + e.message));  
                }  
            });  
        },  

        // DataURL 转 ArrayBuffer  
        dataURLToArrayBuffer(dataUrl) {  

            const base64String = dataUrl.split(',')[1];  
            if (!base64String) {  
                throw new Error('无效的 DataURL 格式');  
            }  

            // Base64 解码为二进制字符串  
            const binaryString = atob(base64String);  

            // 二进制字符串转 ArrayBuffer  
            const bytes = new Uint8Array(binaryString.length);  
            for (let i = 0; i < binaryString.length; i++) {  
                bytes[i] = binaryString.charCodeAt(i);  
            }  
            return bytes.buffer;  
        }  
    }  
}  

</script>

<style>
.content {
padding: 40rpx;
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
background-color: #f8f8f8;
}

.select-btn {  
    width: 80%;  
    margin: 40rpx 0;  
    border-radius: 50rpx;  
    background: linear-gradient(135deg, #007aff, #0066cc);  
    color: #fff;  
    font-size: 32rpx;  
    padding: 30rpx 0;  
    box-shadow: 0 8rpx 20rpx rgba(0, 122, 255, 0.3);  
}  

.select-btn:active {  
    transform: scale(0.96);  
    opacity: 0.8;  
}  

.result-container {  
    width: 100%;  
    max-width: 700rpx;  
    background: #ffffff;  
    border-radius: 24rpx;  
    padding: 30rpx;  
    margin-top: 30rpx;  
    box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);  
}  

.image-wrapper {  
    width: 100%;  
    height: 400rpx;  
    background: #f0f0f0;  
    border-radius: 16rpx;  
    overflow: hidden;  
    display: flex;  
    align-items: center;  
    justify-content: center;  
}  

.preview-image {  
    width: 100%;  
    height: 100%;  
}  

.info-wrapper {  
    margin-top: 30rpx;  
}  

.info-item {  
    display: flex;  
    flex-wrap: wrap;  
    padding: 16rpx 0;  
    border-bottom: 1rpx solid #f0f0f0;  
}  

.info-item:last-child {  
    border-bottom: none;  
}  

.label {  
    font-size: 28rpx;  
    color: #666;  
    font-weight: 500;  
    min-width: 180rpx;  
}  

.value {  
    font-size: 28rpx;  
    color: #333;  
    flex: 1;  
    word-break: break-all;  
}  

.base64-preview {  
    font-family: 'Courier New', monospace;  
    font-size: 22rpx;  
    color: #007aff;  
    background: #f5f7fa;  
    padding: 12rpx 16rpx;  
    border-radius: 8rpx;  
    margin-top: 8rpx;  
}  

.loading-wrapper {  
    margin-top: 40rpx;  
    padding: 20rpx 40rpx;  
    background: rgba(0, 122, 255, 0.1);  
    border-radius: 50rpx;  
}  

.loading-text {  
    font-size: 28rpx;  
    color: #007aff;  
}  

.error-wrapper {  
    margin-top: 40rpx;  
    padding: 20rpx 40rpx;  
    background: rgba(255, 59, 48, 0.1);  
    border-radius: 16rpx;  
    border: 1rpx solid rgba(255, 59, 48, 0.2);  
}  

.error-text {  
    font-size: 28rpx;  
    color: #ff3b30;  
}  

</style>

要回复问题请先登录注册