First app for android
Update time:2018-04-13 Views:2561
Android BLE
Android 4.3(API Level 18)support the buletooth Low power function,It provide more API,API help developer found devices,check,read & write when develop application,BLE Low power let Android app work lunch more time,like proximity sensor, heart rate display,fitness equipment,etc.
Concepts
Generic Attribute Profile (GATT) GATT is the General specifications when BLE sent data or receive data.
Attribute Protocol (ATT) property protocol is base on UUID,it use for mark property.
Characteristic contains one vaule and“0”or several descriptor
Descriptor is a property use for Characteristic
Service is a unit for Characteristic
Roles and Responsibilities
The roles divided central and peripheral.For example,the Android phone and BLE heart rate display,Android phone is the central,it controls BLEheart rate display;BLE heart rate display is the peripheral,it is controlled by Android phone.
BLE Promissions
When devloping BLE,Android application need this permission:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
In addition,when application need to judge BLE exist or not,we can modify AndroidManifest.xml like this:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
in the code,we can judge like this:
// Use this check to determine whether BLE is supported on the device. Then // you can selectively disable BLE-related features. if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); finish(); }
BLE development
Setting of BLE
1.Get BluetoothAdapter
// Initializes Bluetooth adapter. final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter();
2.Open Bluetooth
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); }
Scanning BLE devices
When we need to find BLE device,we need to use startLeScan() function,this function use BluetoothAdapter.LeScanCallback Object as a parameter.When we stop to find Ble device,we need to use stopLeScan()function,this function use BluetoothAdapter.LeScanCallback Object as a parameter
/** * Activity for scanning and displaying available BLE devices. */ public class DeviceScanActivity extends ListActivity { 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); } ... } ... private LeDeviceListAdapter mLeDeviceListAdapter; ... // Device scan callback. 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() { mLeDeviceListAdapter.addDevice(device); mLeDeviceListAdapter.notifyDataSetChanged(); } }); } }; }
Connect to GATT Server
When we need to Connect Ble device,we need connectGatt() function,this function has 3 parameter,a Context object,a bool use for mark autoconnect,a BluetoothGattCallback object
mBluetoothGatt = device.connectGatt(this, false, mGattCallback); BluetoothGattCallback is a callback methods of BLE connecting status: // Various callback methods defined by the BLE API. private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { String intentAction; if (newState == BluetoothProfile.STATE_CONNECTED) { intentAction = ACTION_GATT_CONNECTED; mConnectionState = STATE_CONNECTED; broadcastUpdate(intentAction); Log.i(TAG, "Connected to GATT server."); 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 // New services discovered public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); } 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); } } ... };
Read GATT
When we Read GATT,we need use readCharacteristic() function,thie function have a BluetoothGattCharacteristic object as parameter:
public boolean readCharacteristic(UUID gatservice_uuid,UUID char_uuid){ synchronized(mGattLock){ try{ if(mBluetoothGatt==null || mBluetoothGattServiceList==null) return false; BluetoothGattService bgs = mBluetoothGatt.getService(gatservice_uuid); if(bgs==null) return false; BluetoothGattCharacteristic bgc = bgs.getCharacteristic(char_uuid); if(bgc==null) return false; int properties = bgc.getProperties(); if(((properties&BluetoothGattCharacteristic.PROPERTY_READ ) == BluetoothGattCharacteristic.PROPERTY_READ )) { return mBluetoothGatt.readCharacteristic(bgc); }else{ LOGD(gatservice_uuid+"->"+char_uuid+" can not read !"); return false; } }catch(Exception ex){ return false ; } } }
Write GATT
When we write GATT we need use writeCharacteristic()function,thie function have a BluetoothGattCharacteristic object as parameter:
public boolean writeCharacteristic(UUID gatservice_uuid,UUID char_uuid,String value){ synchronized(mGattLock){ try{ if(mBluetoothGatt==null || mBluetoothGattServiceList==null) return false; BluetoothGattService bgs = mBluetoothGatt.getService(gatservice_uuid); if(bgs==null){ LOGD("bgs:"+bgs+"->"+" can not find ! write error"); return false; } BluetoothGattCharacteristic bgc = bgs.getCharacteristic(char_uuid); if(bgc==null) { LOGD("bgc:"+bgc+"->"+" can not find ! write error"); return false; } int properties = bgc.getProperties(); if( ( ( properties&BluetoothGattCharacteristic.PROPERTY_WRITE ) == BluetoothGattCharacteristic.PROPERTY_WRITE ) || ( ( properties&BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE ) == BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE ) || ( ( properties&BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE ) == BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE ) ) { bgc.setValue(value); return mBluetoothGatt.writeCharacteristic(bgc); }else{ LOGD(gatservice_uuid+"->"+char_uuid+" can not write !"); return false; } }catch(Exception ex){ LOGD("writeCharacteristic mBluetoothGatt dead ."); return false ; } }
}
Receive BLE Notification
When we receive BLE notification we need use setCharacteristicNotification()function,thie function have a BluetoothGattDescriptor object as parameter:
private static String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; public boolean setCharacteristicNotification(UUID gatservice_uuid,UUID char_uuid,boolean enable){ synchronized(mGattLock){ try{ if(mBluetoothGatt==null || mBluetoothGattServiceList==null) return false; BluetoothGattService bgs = mBluetoothGatt.getService(gatservice_uuid); if(bgs==null) return false; BluetoothGattCharacteristic bgc = bgs.getCharacteristic(char_uuid); if(bgc==null) return false; int properties = bgc.getProperties(); if((properties&BluetoothGattCharacteristic.PROPERTY_NOTIFY ) == BluetoothGattCharacteristic.PROPERTY_NOTIFY ) { if(mBluetoothGatt.setCharacteristicNotification(bgc,enable)) { BluetoothGattDescriptor descriptor = bgc.getDescriptor(UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG)); descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); return mBluetoothGatt.writeDescriptor(descriptor); }else{ return false; } }else{ LOGD(gatservice_uuid+"->"+char_uuid+" can not notify !"); return false; } }catch(Exception ex){ LOGD("setCharacteristicNotification mBluetoothGatt dead ."); return false ; } } }
Close application
When we have no need to use the BLE device,we should use close()method to close application:
public void close() { if (mBluetoothGatt == null) { return; } mBluetoothGatt.close(); mBluetoothGatt = null; }