上一篇
安卓开发两个蓝牙传输数据
- 行业动态
- 2025-04-23
- 6
在安卓中实现两设备蓝牙传输需:1.开启
蓝牙并搜索配对;2.建立BluetoothSocket连接;3.通过输入输出流读写数据;4.处理线程同步与权限(BLUETOOTH/BLUETOOTH_ADMIN
蓝牙基础概念
在安卓开发中,蓝牙通信主要依赖以下核心类:
- BluetoothAdapter:代表本地蓝牙设备,所有操作的起点。
- BluetoothDevice:代表远程蓝牙设备。
- BluetoothSocket:用于建立蓝牙连接的接口,类似TCP Socket。
- UUID:蓝牙服务的唯一标识符,需双方一致。
权限配置
AndroidManifest.xml 声明权限
权限 | 作用 |
---|---|
BLUETOOTH |
基础蓝牙功能 |
BLUETOOTH_ADMIN |
管理蓝牙(如开启/关闭) |
ACCESS_FINE_LOCATION |
Android 6.0+ 扫描设备需定位权限 |
动态申请权限(Android 6.0+)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE); }
开启蓝牙与设备配对
检查蓝牙是否支持并启用
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter == null) { // 设备不支持蓝牙 } else if (!bluetoothAdapter.isEnabled()) { // 请求开启蓝牙 Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableIntent, REQUEST_ENABLE_BT); }
扫描并配对设备
// 注册广播接收器 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(receiver, filter); bluetoothAdapter.startDiscovery(); // 广播接收器监听设备发现 private final BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // 请求配对 device.createBond(); } } };
建立蓝牙连接
获取已配对设备列表
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices(); for (BluetoothDevice device : pairedDevices) { // 筛选目标设备(如通过名称或MAC地址) }
创建 BluetoothSocket 并连接
final BluetoothDevice targetDevice = ...; // 目标设备 final UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // 标准串口服务UUID new Thread(() -> { try { BluetoothSocket socket = targetDevice.createRfcommSocketToServiceRecord(uuid); socket.connect(); // 阻塞直到连接成功或超时 // 连接成功后处理输入输出流 } catch (IOException e) { e.printStackTrace(); } }).start();
数据传输实现
输入输出流操作
InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); // 发送数据 String data = "Hello Bluetooth"; outputStream.write(data.getBytes()); // 接收数据 byte[] buffer = new byte[1024]; int bytes; while ((bytes = inputStream.read(buffer)) != -1) { String received = new String(buffer, 0, bytes); // 处理接收到的数据 }
线程管理(避免阻塞主线程)
- 子线程:负责连接、读写操作。
- 主线程:更新UI或处理业务逻辑。
- Handler:子线程通过Handler通知主线程。
常见问题与解决方案
问题 | 解决方案 |
---|---|
权限被拒 | 确保动态申请ACCESS_FINE_LOCATION 权限 |
连接失败 | 检查UUID是否一致,确保设备可见性 |
主线程阻塞 | 将connect() 和read() 放在子线程 |
设备不兼容 | 测试不同安卓版本和厂商ROM |
连接不稳定 | 增加重试机制,优化信号强度 |
相关问题与解答
问题1:如何实现双向通信?
解答:
双方均创建BluetoothSocket
,一方作为服务器(监听连接),另一方作为客户端(主动连接)。
- 设备A:
listenUsingRfcommWithServiceRecord("AppService", uuid)
- 设备B:
createRfcommSocketToServiceRecord(uuid)
并连接A的MAC地址。
问题2:如何传输大文件(如图片、视频)?
解答:
- 分片传输:将大文件拆分为固定大小的数据块(如4KB),逐块发送。
- 确认机制:每发送一块数据后,等待接收方确认再继续。
- 优化性能:使用缓冲区(
BufferedOutputStream
)减少I/O