主要难点是把文件转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>
6 个回复
Azikou
2022年3.25了 还是没有。逼着搞nativejs 烦躁
徐州老铁 - 开发者
2024了还没有
1***@qq.com
2025也没有
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) {
// 处理异常
}
2026-03-19 08:31
c***@163.com
2026也没有
Azikou
2026年了 买个月ai,鞭策它写一个
2026-07-15 13:18
1***@qq.com - 23
主要难点是把文件转arraybuffer,
<template>
<view class="content">
<button type="primary" @click="selectImage" class="select-btn">
选择文件
</button>
</template>
<script>
export default {
data() {
return {
imageInfo: null,
loading: false,
error: '',
uploadOptions: {
</script>
<style>
.content {
padding: 40rpx;
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
background-color: #f8f8f8;
}
</style>