前言
接着上一篇博客记录,这里记录4.0的开发,废话不多说,直接开始吧。
BluetoothBle
1.权限
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!--高版本需要这个权限,不然搜不到蓝牙设备-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
至于动态申请权限,这里就不展开说了,自行百度吧。
2.扫描设备
/**
* 是否支持蓝牙
*
* @return
*/
private boolean isSupportBluetooth() {
return bluetoothAdapter != null;
}
/**
* 是否支持BLE
*
* @return
*/
private boolean isSupportBle() {
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
}
/**
* 是否开启蓝牙
*
* @return
*/
private boolean isEnableBluetooth() {
return bluetoothAdapter.isEnabled();
}
/**
* 开启蓝牙
*/
private void enableBluetooth() {
if (!isEnableBluetooth()) {
Log.e(TAG, "enable bluetooth.......");
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
mContext.startActivityForResult(intent, Constant.REQUEST_CODE_ENABLE_BLUETOOTH_BLE);
} else {
Log.e(TAG, "bluetooth is already enabled........");
}
}
/**
* 请求开启蓝牙回调
*/
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (resultCode != Activity.RESULT_OK)
return;
if (requestCode == Constant.REQUEST_CODE_ENABLE_BLUETOOTH_BLE) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
startDiscoveryBLE();
}
}, 3000);
}
}
跟蓝牙3.0其实差不多,就是多了一步判断是否支持BLE模式。
接着才是扫描设备,这里就完全不同了。
/**
* 开始扫描BLE,
* 扫描会一直进行,所以需要设定一个停止时间
*/
public void startDiscoveryBLE() {
bluetoothAdapter.stopLeScan(scanCallback);
bluetoothAdapter.startLeScan(scanCallback);
mHandler.removeCallbacks(cancelRunnable);
mHandler.postDelayed(cancelRunnable, 10 * 1000);
}
/**
* 停止扫描
*/
public void stopDiscoveryBLE() {
if (bluetoothAdapter != null)
bluetoothAdapter.stopLeScan(scanCallback);
}
private Runnable cancelRunnable = new Runnable() {
@Override
public void run() {
//BLE会一直扫描,所以设置一个扫描时间
stopDiscoveryBLE();
mHandler.sendEmptyMessage(Constant.BLUETOOTH_FINISH_DISCOVERY_BLE);
}
};
private BluetoothAdapter.LeScanCallback scanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
Log.e(TAG, "onLeScan....."+device.getName());
if (device == null || device.getAddress() == null || device.getName() == null) {
return;
}
BTDevice btDevice = new BTDevice(device.getName(), device.getAddress(), device.getBondState(), device.getUuids(), Constant.BLUETOOTH_KIND_BLE);
Message msg = mHandler.obtainMessage(Constant.BLUETOOTH_BLE_FOUND_DEVICE);
Bundle bundle = new Bundle();
bundle.putParcelable(Constant.EXTRA_DEVICE, btDevice);
msg.setData(bundle);
mHandler.sendMessage(msg);
}
};
蓝牙连接
连接也跟3.0完全不同,这里启用了后台服务
/**
* 启动连接服务
*/
private void startService() {
Log.e(TAG,"startService....");
Intent intent = new Intent(mContext, BluetoothLeService.class);
mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
/**
* 断开连接,解绑
*/
public void onDestory() {
stopDiscoveryBLE();
mContext.unbindService(mServiceConnection);
if (bluetoothLeService != null) {
bluetoothLeService.disconnect();
}
bluetoothLeService = null;
}
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e(TAG, "onservice connected..........");
bluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
if(!bluetoothLeService.initialize()){
return;
}
if (!TextUtils.isEmpty(mAddress)) {
bluetoothLeService.connect(mAddress);
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e(TAG, "onservice disconnected..........");
bluetoothLeService = null;
}
};
连接的核心都在Service实现
public class BluetoothLeService extends Service {
private final String TAG = this.getClass().getSimpleName();
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
private final IBinder mBinder = new LocalBinder();
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothGatt mBluetoothGatt;
private String mAddress;
private int mConnectionState = STATE_DISCONNECTED;
private BluetoothHandler mHandler;
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
// String intentAction;
if(newState== BluetoothProfile.STATE_CONNECTED){//连接上
mConnectionState = STATE_CONNECTED;
Log.e(TAG, "-----onConnectionStateChange------STATE_CONNECTED");
mHandler.obtainMessage(Constant.BLUETOOTH_LE_GATT_CONNECTED).sendToTarget();
}
if(newState==BluetoothProfile.STATE_DISCONNECTED){
mConnectionState = STATE_DISCONNECTED;
Log.e(TAG, "-----onConnectionStateChange------STATE_DISCONNECTED");
mHandler.obtainMessage(Constant.BLUETOOTH_LE_GATT_DISCONNECTED).sendToTarget();
}
}
//发现设备的服务回调,需要在这里处理订阅事件
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if(status!=BluetoothGatt.GATT_SUCCESS){//成功订阅
return;
}
Log.e(TAG, "-----onServicesDiscovered------GATT_SUCCESS");
mHandler.obtainMessage(Constant.BLUETOOTH_LE_GATT_SERVICES_DISCOVERED).sendToTarget();
List<BluetoothGattService> services = gatt.getServices();
for(BluetoothGattService service:services){
for(BluetoothGattCharacteristic characteristic:service.getCharacteristics()){
if(TextUtils.equals(Constant.READ_UUID,characteristic.getUuid().toString())){
//依据协议订阅相关信息,否则收不到数据
mBluetoothGatt.setCharacteristicNotification(characteristic,true);
// 大坑,适配某些手机!!!比如小米...
mBluetoothGatt.readCharacteristic(characteristic);
for(BluetoothGattDescriptor descriptor:characteristic.getDescriptors()){
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
}
}
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
if(status==BluetoothGatt.GATT_SUCCESS){
Log.e(TAG, "-----onCharacteristicRead------onCharacteristicRead");
// mHandler.obtainMessage(Constant.BLUETOOTH_LE_DATA_AVAILABLE).sendToTarget();
}
}
//发送消息结果回调
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
if(status==BluetoothGatt.GATT_SUCCESS){
Log.e(TAG,"------write data success---");
return;
}
if(status==BluetoothGatt.GATT_FAILURE){
Log.e(TAG,"---write data failure---");
return;
}
if(status==BluetoothGatt.GATT_WRITE_NOT_PERMITTED){
Log.e(TAG,"----write no permission---");
}
}
// 当订阅的Characteristic接收到消息时回调
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
Log.e(TAG, "-----onCharacteristicChanged------onCharacteristicChanged");
mHandler.obtainMessage(Constant.READ_DATA,characteristic.getValue()).sendToTarget();
}
};
public boolean initialize() {
if(mHandler ==null){
mHandler = BluetoothHandler.getInstance(this);
}
if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
}
if (mBluetoothManager == null) {
return false;
}
if (mBluetoothAdapter == null) {
mBluetoothAdapter = mBluetoothManager.getAdapter();
}
if (mBluetoothAdapter == null) {
return false;
}
return true;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
close();
return super.onUnbind(intent);
}
public class LocalBinder extends Binder {
BluetoothLeService getService() {
return BluetoothLeService.this;
}
}
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
return false;
}
//如果是之前已连接的,重连即可
if (mAddress != null && address.equals(mAddress) && mBluetoothGatt != null) {
Log.e(TAG, "trying to use an existing connection");
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.e(TAG, "device not found,unable to connect");
return false;
}
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
Log.e(TAG, " trying to create a new connection");
mAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}
public void disconnect() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.e(TAG, "bluetoothadapter not initialized");
return;
}
mBluetoothGatt.disconnect();
}
private void close() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}
}
结束语
蓝牙4.0就这么一点内容,记录一下,方便自己查找。都是经过我实测可用的,可放心,不是单纯copy paste的结果。
我把核心代码打包贴出来,仅供参考,不足之处欢迎留言指正。