BLE全名为Bluetooth Low Energy 顾名思义,蓝牙低能耗。
蓝牙4.0以上称之为BLE4.0以下称之为传统蓝牙,二者的区别为:
1、低能耗,蓝牙4.0设备与周围设备交流时,其峰值能耗仅为传统蓝牙设备的一半
2、传输距离,100米以上
3、使用128-bit AES完全加密,为数据封包提供高度加密性及认证度
4、低延时。最短可在3ms内完成连接设置并开始传输数据(传统蓝牙设备延时最高达100ms)
BLE的使用流程
1、必须添加权限
<uses-permissionandroid:name="android.permission.BLUETOOTH"/><uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/>
2、检查设备是否支持BLE
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this,“此设备不支持BLE”, Toast.LENGTH_SHORT).show();
finish();
}
3、获取BluetoothAdapter适配器
BluetoothManager bluetoothManager =(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
4、开启蓝牙
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// User chose not to enable Bluetooth.
if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
finish();
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
5、搜索BLE设备
startLeScan()方法用来搜索BLE设备,这个方法需要一个BluetoothAdapter. LeScanCallback
你必须实现它的回调函数,那就是返回的扫描结果,因为扫描非常耗电量,所以只要找到所需的设备,停止扫描,对扫描设置时间限制
privatevoid scanLeDevice(finalboolean enable) {
if (enable) {
// 经过预定扫描期后停止扫描,防止大量消耗电量
mHandler.postDelayed(new Runnable() {
@Overridepublicvoid run() {
mScanning = false;
//先停止搜索
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
//开始搜索
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
6、搜索设备的回调方法LeScanCallback
在4.3之前的api是通过注册广播来处理搜索时发生的一些事件,而支持ble的新api中,是通过回调的方式来处理的而mLeScanCallback就是一个接口对象
7、连接搜索到的蓝牙设备private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Overridepublicvoid onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { //device 搜索到的蓝牙设备 runOnUiThread(new Runnable() { @Overridepublicvoid run() { //device.getName();获取蓝牙设备名字 //device.getAddress();获取蓝牙设备mac地址 可以将数据使用EventBus进行需要传递 mLeDeviceListAdapter.addDevice(device); mLeDeviceListAdapter.notifyDataSetChanged(); } }); } };
listview的onItemClick方法获取到选择连接的某一个蓝牙设备,这里可以通过getremoteDevice(address)获取设备,然后device.connectGatt(this,false,mGattCallback)正是连接蓝牙设备,连接后会返回一个BluetooothGatt类型的对象,这个对象比较重要,后面的读写设备等操作都是通过该对象。
代码里建设了一个service,里面封装了连接,读写设备等操作,连接是通过获取的mac地址去进行连接操作就可以了
public boolean connect(final String address) {
if (mBluetoothAdapter ==null|| address ==null) {
Log.w(TAG,"BluetoothAdapter not initialized or unspecified address.");
returnfalse;
}
// 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;
returntrue;
} else {
returnfalse;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device ==null) {
Log.w(TAG, "Device not found. Unable to connect.");
returnfalse;
}
// We want to directly connect to the device, so we are setting the// autoConnect// parameter to false.//该函数才是真正的去进行连接 参数三是连接后的接口回调 函数返回值为mBluetoothGatt
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
Log.d(TAG, "Trying to create a new connection.");
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
returntrue;
}
8、连接后会回调
BluetoothGattCallback接口,包括读取设备,往设备里读取数据及设备发出通知等都会回调该接口,其中比较重要的是BluetoothGatt
BluetoothGattCallback接口 里的onConnectionStateChange函数 表示连接状态监听函数。onServicesDiscovered函数表示服务监听函数里面的characteristic分别是读写通知属性。