在 Android 中实现蓝牙连接可以分为两部分:
- 启用蓝牙和搜索设备。
- 与设备配对和建立通信连接。
下面是如何通过代码实现蓝牙连接的详细步骤,包括权限申请、蓝牙设备扫描和连接。我们会基于经典蓝牙(Bluetooth Classic)的通信方式进行演示。
步骤 1:在 AndroidManifest.xml 中声明权限
首先,你需要在 AndroidManifest.xml
文件中声明使用蓝牙的权限。
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <!-- 扫描设备时需要定位权限 -->
步骤 2:启用蓝牙并搜索设备
接下来,我们编写一个 Java 类来实现蓝牙的启用和设备扫描。
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import java.util.Set;
public class BluetoothUtils {
private BluetoothAdapter bluetoothAdapter;
private Context context;
public BluetoothUtils(Context context) {
this.context = context;
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // 获取蓝牙适配器
}
// 启用蓝牙
public void enableBluetooth() {
if (bluetoothAdapter == null) {
Log.d("BluetoothUtils", "设备不支持蓝牙");
} else if (!bluetoothAdapter.isEnabled()) {
// 如果蓝牙未启用,请求启用
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
context.startActivity(enableBtIntent);
} else {
Log.d("BluetoothUtils", "蓝牙已启用");
}
}
// 获取已配对的设备
public Set<BluetoothDevice> getPairedDevices() {
return bluetoothAdapter.getBondedDevices();
}
// 开始扫描蓝牙设备
public void startDiscovery() {
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery(); // 停止当前的扫描
}
bluetoothAdapter.startDiscovery(); // 开始新的扫描
Log.d("BluetoothUtils", "开始扫描蓝牙设备");
// 注册广播接收器,用于接收找到的设备
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
context.registerReceiver(receiver, filter);
}
// 广播接收器,接收扫描到的设备
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// 从Intent中获取BluetoothDevice对象
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d("BluetoothUtils", "找到设备: " + device.getName() + " - " + device.getAddress());
}
}
};
// 停止扫描
public void stopDiscovery() {
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
context.unregisterReceiver(receiver);
Log.d("BluetoothUtils", "停止扫描蓝牙设备");
}
}
代码说明:
- 启用蓝牙:调用
BluetoothAdapter.ACTION_REQUEST_ENABLE
让用户启用蓝牙。 - 获取已配对的设备:通过
bluetoothAdapter.getBondedDevices()
获取设备的列表。 - 扫描设备:通过
bluetoothAdapter.startDiscovery()
开始扫描附近的蓝牙设备,并使用BroadcastReceiver
来接收找到的设备信息。 - 广播接收器:用于接收扫描到的设备,设备信息通过
BluetoothDevice
对象获取,包括设备名称和地址。
步骤 3:与蓝牙设备连接
当找到目标设备后,可以通过其 MAC 地址与之建立连接。我们可以使用 BluetoothSocket
来进行连接和通信。
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
public class BluetoothConnection {
private BluetoothSocket bluetoothSocket;
private InputStream inputStream;
private OutputStream outputStream;
// UUID用于标识蓝牙服务
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
/**
* 与蓝牙设备建立连接
* @param device 蓝牙设备对象
* @throws IOException 连接失败时抛出
*/
public void connect(BluetoothDevice device) throws IOException {
// 使用设备创建一个BluetoothSocket
bluetoothSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
// 尝试连接
bluetoothSocket.connect();
// 获取输入输出流
inputStream = bluetoothSocket.getInputStream();
outputStream = bluetoothSocket.getOutputStream();
System.out.println("连接成功!");
}
/**
* 向蓝牙设备发送数据
* @param data 发送的数据
* @throws IOException 发送失败时抛出
*/
public void sendData(String data) throws IOException {
if (outputStream != null) {
outputStream.write(data.getBytes());
}
}
/**
* 从蓝牙设备读取数据
* @return 返回读取的数据
* @throws IOException 读取失败时抛出
*/
public String readData() throws IOException {
byte[] buffer = new byte[1024];
int bytes;
if (inputStream != null) {
bytes = inputStream.read(buffer);
return new String(buffer, 0, bytes);
}
return null;
}
/**
* 断开连接
*/
public void disconnect() {
try {
if (bluetoothSocket != null) {
bluetoothSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
代码说明:
- UUID:每个蓝牙设备都有一个独特的 UUID 用于标识其服务。通常可以使用
00001101-0000-1000-8000-00805F9B34FB
,这是用于经典蓝牙的标准串口通信协议(SPP)UUID。 BluetoothSocket
:通过BluetoothDevice.createRfcommSocketToServiceRecord()
创建套接字来进行连接。- 输入输出流:使用
InputStream
和OutputStream
进行数据的读取和发送。 - 连接设备:通过调用
bluetoothSocket.connect()
建立连接。
步骤 4:使用权限和功能
在 Android 6.0(API 23)及以上版本中,需要在运行时请求蓝牙和位置权限。你可以通过以下代码在 Activity 中请求权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.ACCESS_FINE_LOCATION
}, 1);
}
总结:
- 蓝牙启用与扫描:使用
BluetoothAdapter
来启用蓝牙、扫描设备。 - 设备连接:通过
BluetoothDevice
与目标设备建立连接,并使用BluetoothSocket
进行通信。 - 权限管理:确保动态申请了蓝牙和位置权限,特别是在 Android 6.0 及以上版本。
这个蓝牙连接示例适用于经典蓝牙设备。如果你想使用 BLE(蓝牙低功耗),代码和实现方式会有所不同。