1.BLE权限定义
Android低功耗蓝牙只支持4.3(API 18)以后的设备
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
如果你只想你的APP运行在支持低功耗蓝牙的设备上你可以在manifest上加入
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
或者在运行时加入以下代码:
if (!getPackageManager().hasSystemFeature(
PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
2.配置蓝牙
2.1.获取BluetoothAdapter
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
2.2.打开蓝牙
private BluetoothAdapter mBluetoothAdapter;
...
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
3.查找蓝牙设备
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// 通过 device.getName(),device.getAddress()获取到蓝牙设备名称和地址
}
});
}
};
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
...
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
...
}
3.连接蓝牙设备
private final BluetoothGattCallback mGattCallback =
new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
// 连接成功后要查询蓝牙服务
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
}
}
@Override
// New services discovered
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
//发现蓝牙服务后可获取到
List<BluetoothGattService> gattServices=mBluetoothGatt.getServices();
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
@Override
// Result of a characteristic read operation
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
...
};
BluetoothGatt mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
// Previously connected device. Try to reconnect.
if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null) {
Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
4.获取蓝牙属性
在回调方法onServicesDiscovered中获取蓝牙设备的Service和Characteristic;
@Override
// New services discovered
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
List<BluetoothGattService> gattServices=mBluetoothGatt.getServices();
List<BluetoothGattCharacteristic> gattCharacteristics =
gattService.getCharacteristics();
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
5.对蓝牙Characteristic进行操作
5.1 写操作(W - Write)
byte[] dataToWrite;
characteristic.setValue(dataToWrite)
mBluetoothGatt.writeCharacteristic(characteristic);
//写操作完成会回调
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
//写入成功
}
else {
//写入失败
}
}
5.2 读操作(R - Read)
mBluetoothGatt.readCharacteristic(characteristic);
//读操作会回调
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
// we got response regarding our request to fetch characteristic value
if (status == BluetoothGatt.GATT_SUCCESS) {
// and it success, so we can get the value
//在此处取值
byte[] rawValue = characteristic.getValue();
}
}
5.3 通知或指示操作(I - Indication or N - Notify)
boolean success = mBluetoothGatt.setCharacteristicNotification(ch, enabled);
if (!success) {
Log.e("------", "Seting proper notification status for characteristic failed!");
}
BluetoothGattDescriptor descriptor = ch.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
// 启用或停用 I - Indication or N - Notify
// BluetoothGattDescriptor.ENABLE_INDICATION_VALUE
// BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE
descriptor.setValue(enabled ?
BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
// 通知或指示操作会回调
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
// characteristic's value was updated due to enabled notification, lets get this value
// the value itself will be reported to the UI inside getCharacteristicValue
}
6.断开连接,关闭连接
mBluetoothGatt.disconnect();
public void close() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}