1.BLE權(quán)限定義
Android低功耗藍(lán)牙只支持4.3(API 18)以后的設(shè)備
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
如果你只想你的APP運(yùn)行在支持低功耗藍(lán)牙的設(shè)備上你可以在manifest上加入
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
或者在運(yùn)行時(shí)加入以下代碼:
if (!getPackageManager().hasSystemFeature(
PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
2.配置藍(lán)牙
2.1.獲取BluetoothAdapter
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
2.2.打開(kāi)藍(lán)牙
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.查找藍(lán)牙設(shè)備
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() {
// 通過(guò) device.getName(),device.getAddress()獲取到藍(lán)牙設(shè)備名稱(chēng)和地址
}
});
}
};
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.連接藍(lán)牙設(shè)備
private final BluetoothGattCallback mGattCallback =
new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
// 連接成功后要查詢(xún)藍(lán)牙服務(wù)
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) {
//發(fā)現(xiàn)藍(lán)牙服務(wù)后可獲取到
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.獲取藍(lán)牙屬性
在回調(diào)方法onServicesDiscovered中獲取藍(lán)牙設(shè)備的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.對(duì)藍(lán)牙Characteristic進(jìn)行操作
5.1 寫(xiě)操作(W - Write)
byte[] dataToWrite;
characteristic.setValue(dataToWrite)
mBluetoothGatt.writeCharacteristic(characteristic);
//寫(xiě)操作完成會(huì)回調(diào)
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
//寫(xiě)入成功
}
else {
//寫(xiě)入失敗
}
}
5.2 讀操作(R - Read)
mBluetoothGatt.readCharacteristic(characteristic);
//讀操作會(huì)回調(diào)
@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);
// 通知或指示操作會(huì)回調(diào)
@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.斷開(kāi)連接,關(guān)閉連接
mBluetoothGatt.disconnect();
public void close() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}