Bluetooth Low Energy,蓝牙低功耗,是从蓝牙4.0开始支持的技术。相较传统蓝牙,传输速度更快、覆盖范围广、安全性高、延时短、耗电低等特点。
如果需要声明应用仅对低功耗蓝牙有效,还需要在app的manifest中声明
// Initializes Bluetooth adapter.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
1.扫描设备:
//搜索附近所有的外围设备
mBluetoothAdapter.startLeScan(mLeScanCallback);
//搜索某些uuid的外围设备。 可指定uuid
mBluetoothAdapter.startLeScan(uuid[] ,mLeScanCallback);
停止扫描
mBluetoothAdapter.stopLeScan(mLeScanCallback);
mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
}
}
其中,返回的 device:搜索到的ble设备 rssi:信号强度 scanRecord:远程设备广告记录的内容(蓝牙名称)
根据第七步搜索到的外围设备,我们需要去链接它。链接,指的是链接到GATT服务器设备,
此处我们需要传进去三个参数:
1.context
2.false:直接立即链接 true:等待远端设备可用时自动链接
3.蓝牙链接回调 其中包括:链接状态改变、characteristic的read、write、change、和MTU change的监听
// Implements callback methods for GATT events that the app cares about. For example,
// connection change and services discovered.,所有函数的回调函数
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
String intentAction;
//收到设备notify值 (设备上报值) 链接状态改变回调方法,此处处理链接成功
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) { //链接成功后,从下面获取service列表
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
if(MTU>20){
boolean ret = mBluetoothGatt.requestMtu(MTU);
Log.d("BLE","requestMTU "+MTU+" ret="+ret);
}
}
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
System.out.println("onServicesDiscovered received: " + status);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
//读取从周边设备传递过来的数据值,在这里读数据
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) { //特征状态改变
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.e(TAG, "onMtuChanged: "+mtu);
//local var to record MTU size
}
}
};
1.通过onServicesDiscovered()成功回调获取的BluetoothGatt 我们可以调用gatt的getServices()方法,来获取Listcharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
characteristic.setValue(string);
boolean isSuccess = mBluetoothLeService.writeCharacteristic(characteristic);
mGattServer = mBluetoothManager.openGattServer(mContext, callback);
//其中callback是一个MyGattServerCallback(继承了BluetoothGattServerCallback)对象。
BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(
UUID.fromString("0000bbb1-0000-1000-8000-00805f9b34fb"),
BluetoothGattCharacteristic.PROPERTY_NOTIFY +BluetoothGattCharacteristic.PROPERTY_WRITE +BluetoothGattCharacteristic.PROPERTY_READ ,
BluetoothGattCharacteristic.PERMISSION_WRITE+BluetoothGattCharacteristic.PERMISSION_READ );
BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"), BluetoothGattDescriptor.PERMISSION_WRITE);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
characteristic.addDescriptor(descriptor);
4.设置服务
第二个参数为service type,
SERVICE_TYPE_PRIMARY 基础服务、主要服务。
SERVICE_TYPE_SECONDARY 辅助服务(由初级服务包含在内)。
BluetoothGattService 类中方法
addService(bluetoothGattService),将辅助服务添加到主要服务中。
getIncludeedServices() 获取包含的服务列表。
getType() 获取服务的type。
getUuid() 获取服务的UUID。
final BluetoothGattService service = new BluetoothGattService(UUID.fromString("0000bbb0-0000-1000-8000-00805f9b34fb"),
BluetoothGattService.SERVICE_TYPE_PRIMARY);
service.addCharacteristic(characteristic);
boolean isSuccess = gattServer.addService(service);
LogUtils.e(TAG," 添加service2:"+isSuccess );
private void startService() {
//判断你的设备到底支持不支持BLE Peripheral,不支持则返回空
mBluetoothLeAdvertiser = bluetoothAdapter.getBluetoothLeAdvertiser();
Log.e(TAG,"mBluetoothLeAdvertiser"+mBluetoothLeAdvertiser);
if(mBluetoothLeAdvertiser == null){
return;
}
startAdvertising(); //初始化BLE蓝牙广播
}
public void startAdvertising() {
byte[] broadcastData = {0x34, 0x56};
String bleName = "小郎";
byte[] broadcastData = bleName.getBytes();
//广播设置参数,广播数据,还有一个是Callback
mBluetoothLeAdvertiser.startAdvertising(createAdvSettings(true, 0), createAdvertiseData(broadcastData), mAdvertiseCallback);
}
public AdvertiseSettings createAdvSettings(boolean connectable, int timeoutMillis) {
AdvertiseSettings.Builder mSettingsbuilder = new AdvertiseSettings.Builder();
mSettingsbuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY);
mSettingsbuilder.setConnectable(connectable);
mSettingsbuilder.setTimeout(timeoutMillis);
AdvertiseSettings mAdvertiseSettings = mSettingsbuilder.build();
return mAdvertiseSettings;
}
public AdvertiseData createAdvertiseData(byte[] data) {
AdvertiseData.Builder mDataBuilder = new AdvertiseData.Builder();
mDataBuilder.addManufacturerData(0x01AC, data);
mDataBuilder.addServiceUuid(ParcelUuid.fromString(uid));
mDataBuilder.setIncludeDeviceName(true); //设置是否携带设备名称
AdvertiseData mAdvertiseData = mDataBuilder.build();
return mAdvertiseData;
}
(3)广播开启回调
private AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
super.onStartSuccess(settingsInEffect);
LogUtils.e(TAG, "开启广播成功");
ToastUtils.showToast(BLEConnectService.this, "开启广播成功", 2000);
initGattServer(); //初始化GATT服务
}
@Override
public void onStartFailure(int errorCode) {
super.onStartFailure(errorCode);
ToastUtils.showToast(BLEConnectService.this, "开启广播失败 errorCode:" + errorCode, 2000);
}
};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
if(MTU>20){
boolean ret = mBluetoothGatt.requestMtu(MTU);
Log.d("BLE","requestMTU "+MTU+" ret="+ret);
}
}