Android BLE 蓝牙学习总结(二):手机作为中央BluetoothGatt的实现
2017-10-30 14:30
676 查看
一、创建中央基本概念
1.1、中央涉及的类有:
说明:为了拿到中央BluetoothGatt,需要经历以下过程:
1、先拿到BluetoothManager:bluetoothManager=(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
2、再拿到BluetoothAdapter:bluetoothAdapter=bluetoothManager.getAdapter();
3、开始扫描:bluetoothAdapter.startLeScan(BluetoothAdpater.LeScanCallback);
4、从LeScanCallback中得到BluetoothDevice:public void onLeScan(BluetoothDevice device,int rssi,byte[] scanRecord){……};
5、用BluetoothDevice得到BluetoothGatt:gatt=device.connectGatt(this,true,gattCallback);
6、接下来调用BluetoothGatt的方法,通过BluetoothGattCallback和周边的BluetoothServer进行交互
1.2、扫描以及读取与写入数据的相关概念:
监听扫描结果:
mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {}
};
device 搜索到的bye设备。
rssi 信号强度
scanRecord 远程设备广告记录的内容(蓝牙名称)
发起连接请求,获得中央。
mBluetoothGatt = device.connectGatt(mContext, false,mGattCallback);
第二个参数autoConnect 如果为false直接立即连接。
true 等待远程设备可用时(在范围内,。。)连接。并不是断开后重新连接。
第三个参数 Gatt callback 。
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {};
连接成功后,发送 gatt服务发现请求。
//连接状态改变回调
onConnectionStateChange(BluetoothGatt gatt, int status, int newState){
if(newState == BluetoothProfile.STATE_CONNECTED){
//连接成功后,发送发现服务请求。
mBluetoothGatt.discoverServices();
}
}
//发现服务回调。
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if(status == BluetoothGatt.GATT_SUCCESS){
//发现成功后,则可以通过下面方法获取service 列表。
mBluetoothGatt.getServices();
}
}
1.3、中央与周边的数据交互过程总结(写入):
1、当点击事件调用该方法时BluetoothGatt.writeCharacteristic(characteristic),
a、系统异步回调onCharacteristicChanged()方法,
b、与此同时服务端:系统回调onCharacteristicWriteRequest()方法,通过该方法的参数value得到客户端发送过来的数据,在该回调方法中调用sendResponse()回复客户端响应成功,接着处理接受的数据,并通过BluetoothGattServer.notityCharacteristicChanged(device,characteristicRead,false)将回应的数据发送给客户端,该回应的数据就通过onCharacteristicChanged()方法的参数传递到客户端。
c、a与b是异步进行的
二、中央实现的案例讲解
2.1、添加权限
2.2、初始化蓝牙,
1、在onCreate()中检查手机是否支持BLE蓝牙
2、在onResume()中开启蓝牙设备
2.3、扫描设备
1、首先实现扫描回调参数:mLeScanCallback
2、然后再调用 mBluetoothAdapter.stopLeScan(mLeScanCallback)
2.4、建立连接
1、首先先实现中央回调参数:mGattCallback;
2、其次再实现mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
2.5、数据交互
1、输入数据,点击按钮将数据发送出去;
2、将数据绑定特定服务的特征,本案例中绑定的时UUID=”0000fff1-0000-1000-8000-00805f9b34fb”的这个特征
3、点击按钮后,中央将数据发送给了周边,周边会响应中央的请求
案例地址:https://github.com/lihongandroid/BleGattDemo.git
1.1、中央涉及的类有:
说明:为了拿到中央BluetoothGatt,需要经历以下过程:
1、先拿到BluetoothManager:bluetoothManager=(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
2、再拿到BluetoothAdapter:bluetoothAdapter=bluetoothManager.getAdapter();
3、开始扫描:bluetoothAdapter.startLeScan(BluetoothAdpater.LeScanCallback);
4、从LeScanCallback中得到BluetoothDevice:public void onLeScan(BluetoothDevice device,int rssi,byte[] scanRecord){……};
5、用BluetoothDevice得到BluetoothGatt:gatt=device.connectGatt(this,true,gattCallback);
6、接下来调用BluetoothGatt的方法,通过BluetoothGattCallback和周边的BluetoothServer进行交互
1.2、扫描以及读取与写入数据的相关概念:
监听扫描结果:
mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {}
};
device 搜索到的bye设备。
rssi 信号强度
scanRecord 远程设备广告记录的内容(蓝牙名称)
发起连接请求,获得中央。
mBluetoothGatt = device.connectGatt(mContext, false,mGattCallback);
第二个参数autoConnect 如果为false直接立即连接。
true 等待远程设备可用时(在范围内,。。)连接。并不是断开后重新连接。
第三个参数 Gatt callback 。
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {};
连接成功后,发送 gatt服务发现请求。
//连接状态改变回调
onConnectionStateChange(BluetoothGatt gatt, int status, int newState){
if(newState == BluetoothProfile.STATE_CONNECTED){
//连接成功后,发送发现服务请求。
mBluetoothGatt.discoverServices();
}
}
//发现服务回调。
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if(status == BluetoothGatt.GATT_SUCCESS){
//发现成功后,则可以通过下面方法获取service 列表。
mBluetoothGatt.getServices();
}
}
1.3、中央与周边的数据交互过程总结(写入):
1、当点击事件调用该方法时BluetoothGatt.writeCharacteristic(characteristic),
a、系统异步回调onCharacteristicChanged()方法,
b、与此同时服务端:系统回调onCharacteristicWriteRequest()方法,通过该方法的参数value得到客户端发送过来的数据,在该回调方法中调用sendResponse()回复客户端响应成功,接着处理接受的数据,并通过BluetoothGattServer.notityCharacteristicChanged(device,characteristicRead,false)将回应的数据发送给客户端,该回应的数据就通过onCharacteristicChanged()方法的参数传递到客户端。
c、a与b是异步进行的
二、中央实现的案例讲解
2.1、添加权限
<uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
2.2、初始化蓝牙,
1、在onCreate()中检查手机是否支持BLE蓝牙
2、在onResume()中开启蓝牙设备
// 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, "ble_not_supported", Toast.LENGTH_SHORT).show(); finish(); } // Initializes a Bluetooth adapter. For API level 18 and above, get a reference to // BluetoothAdapter through BluetoothManager. final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); // Checks if Bluetooth is supported on the device. if (mBluetoothAdapter == null) { Toast.makeText(this,"error_bluetooth_not_supported", Toast.LENGTH_SHORT).show(); finish(); return; } // Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled, // fire an intent to display a dialog asking the user to grant permission to enable it. if (!mBluetoothAdapter.isEnabled()) { if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } }
2.3、扫描设备
1、首先实现扫描回调参数:mLeScanCallback
2、然后再调用 mBluetoothAdapter.stopLeScan(mLeScanCallback)
// Device scan callback.系统将扫描到的结果通过该回调方法的参数传递出来 private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { //该线程用于更新UI runOnUiThread(new Runnable() { @Override public void run() { mLeDeviceListAdapter.addDevice(device); mLeDeviceListAdapter.notifyDataSetChanged(); } }); } }; private void scanLeDevice(final boolean enable) { if (enable) { // Stops scanning after a pre-defined scan period.该段代码表示扫描10秒后停止, // mhandler相当于计时10秒后执行停止扫描的操作 mHandler.postDelayed(new Runnable() { @Override public void run() { mScanning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback);//即10秒后执行该语句 invalidateOptionsMenu(); } }, SCAN_PERIOD); mScanning = true; mBluetoothAdapter.startLeScan(mLeScanCallback); } else { mScanning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); } invalidateOptionsMenu(); }
2.4、建立连接
1、首先先实现中央回调参数:mGattCallback;
2、其次再实现mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
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, "连接上了GATT服务器,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, "不能从GATT服务器连接,Disconnected from GATT server."); broadcastUpdate(intentAction); } } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); Log.w(TAG,"o 4000 nServicesDiscovered被系统回调,并广播出去"); } else { Log.w(TAG, "onServicesDiscovered被系统回调,没有发现服务,不广播,status= " + status); } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); } Log.w(TAG,"安卓系统回调onCharacteristicRead成功,并将数据广播出去"); } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); Log.w(TAG,"回调onCharacteristicChanged,并将数据广播出去"); } //当BluetoothGatt.writeCharacteristic(BluetoothGattCharacteristic)执行时,系统异步调用该回调方法 @Override public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,int status){ super.onCharacteristicWrite(gatt,characteristic,status); if(status==BluetoothGatt.GATT_SUCCESS) { Log.w(TAG,"回调了onCharacteristicWrite"); } } }; public boolean connect(final String address) { if (mBluetoothAdapter == null || address == null) { Log.w(TAG, "连接失败,BluetoothAdapter not initialized or unspecified address."); return false; } // 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; } } final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); if (device == null) { Log.w(TAG, "没有找到设备,Device not found. Unable to connect."); return false; } // We want to directly connect to the device, so we are setting the autoConnect // parameter to false. mBluetoothGatt = device.connectGatt(this, false, mGattCallback);//连接时,此处得到BluetoothGatt实例 Log.d(TAG, "Trying to create a new connection."); mBluetoothDeviceAddress = address;//在连接当中传入设备地址到BluetoothService类中 mConnectionState = STATE_CONNECTING; return true; }
2.5、数据交互
1、输入数据,点击按钮将数据发送出去;
2、将数据绑定特定服务的特征,本案例中绑定的时UUID=”0000fff1-0000-1000-8000-00805f9b34fb”的这个特征
3、点击按钮后,中央将数据发送给了周边,周边会响应中央的请求
sendButton.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ String str=dateEditText.getText().toString().trim(); byte[] bytes=str.getBytes(); if (mConnected){ mBluetoothLeService.writeBle(bytes, UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb")); dateEditText.setText(""); Log.d(TAG,"点击发送按钮了"); }else { Toast.makeText(DeviceControlActivity.this,"设备连接失败,请重连",Toast.LENGTH_SHORT).show(); } private final ExpandableListView.OnChildClickListener servicesListClickListner = new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { if (mGattCharacteristics != null) { final BluetoothGattCharacteristic characteristic = mGattCharacteristics.get(groupPosition).get(childPosition); final int charaProp = characteristic.getProperties(); if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) { // If there is an active notification on a characteristic, clear // it first so it doesn't update the data field on the user interface. if (mNotifyCharacteristic != null) { mBluetoothLeService.setCharacteristicNotification( mNotifyCharacteristic, false); mNotifyCharacteristic = null; } mBluetoothLeService.readCharacteristic(characteristic);//此时异步调用回调方法onCharacteristicRead(), // 在该回调方法中得到读取的结果数据,在该应用中,在BluetoothLeService中的该回调方法将结果广播出去, // 然后在DeviceControlActivity的广播接收器中得到读取到的数据,并展示出来 } if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { mNotifyCharacteristic = characteristic; mBluetoothLeService.setCharacteristicNotification( characteristic, true);//通知安卓系统我要接受characristic这个特征的数据,true为接受,false为不接受 } return true; } return false; } };
案例地址:https://github.com/lihongandroid/BleGattDemo.git
相关文章推荐
- Android BLE 蓝牙学习总结(一):手机作为周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- Android蓝牙开发教程:中央BluetoothGatt和周边BluetoothGattServer的实现
- android BluetoothAdapter蓝牙BLE扫描总结
- Android BLE低功耗蓝牙开发(下) BLE客户端(中央设备)与GATT服务的通讯
- Android BLE 蓝牙低功耗教程,中央和周边的实现
- Android BLE 蓝牙低功耗教程,中央和周边的实现
- Android BLE学习(二): Android与51822蓝牙模块通信流程的实现与分析
- 安卓蓝牙技术之中央BluetoothGatt和周边BluetoothGattServer的实现
- Android BLE学习(二): Android与51822蓝牙模块通信流程的实现与分析
- Android开发学习笔记:Button事件实现方法的总结