android 蓝牙官方实,Android 蓝牙BLE开发从官方源码demo开始(二)

一、前言

在上一篇文章Android 蓝牙BLE开发从官方源码demo开始(一)我们已经看了官方的demo,知道了怎么开始配置Android蓝牙4.0,并且也成功地进行扫描并获取回调的蓝牙设备参数,然后对参数进行处理展示,其中第一个参数device,表示一个远程蓝牙设备,里面有它独有的蓝牙地址Address和Name;我们要拿到这个设备Address进行蓝牙连接和读写操作。

谷歌给我们提供了官方源码demo:

接下来我们继续来学习谷歌官方给我们提供的蓝牙BLE源码

二、创建BluetoothLeService服务类并初始化蓝牙连接

在官方demo中,蓝牙ble的连接和读写操作都是在DeviceControlActivity中实现,可以下载demo源码,编译运行一遍!

来到此Activity,我们先看onCreate()方法可知,程序先执行bindService开启了一个服务

Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);

bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);

并在服务回调已经成功连接时,获取了BlueToohtLeService的实例,接着就执行蓝牙连接操作:

// Code to manage Service lifecycle.

private final ServiceConnection mServiceConnection = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName componentName, IBinder service) {

mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();

if (!mBluetoothLeService.initialize()) {

Log.e(TAG, "Unable to initialize Bluetooth");

finish();

}

// Automatically connects to the device upon successful start-up initialization.

mBluetoothLeService.connect(mDeviceAddress);

}

@Override

public void onServiceDisconnected(ComponentName componentName) {

mBluetoothLeService = null;

}

};

这个BlueToohtLeService类既然是服务类,那它父类肯定是继承于Service;接着实现了Service的先进入onBind()方法;

1.onBind()是使用bindService开启的服务才会有回调的一个方法。

这里官方demo在onBind()方法给我们的Activity返回了BluetoothLeService实例,方便Activity后续的连接和读写操作;

private final IBinder mBinder = new LocalBinder();

public class LocalBinder extends Binder {

BluetoothLeService getService() {

return BluetoothLeService.this;

}

}

@Override

public IBinder onBind(Intent intent) {

return mBinder;

}

2.当服务调用unbindService时,服务的生命周期将会进入onUnbind()方法;接着执行了关闭蓝牙的方法;

@Override

public boolean onUnbind(Intent intent) {

// After using a given device, you should make sure that BluetoothGatt.close() is called

// such that resources are cleaned up properly.  In this particular example, close() is

// invoked when the UI is disconnected from the Service.

close();

return super.onUnbind(intent);

}

3.initialize() 初始化蓝牙适配器;接着在这demo里这个方法是在服务建立后在Activity通过拿到BlueToohtLeService实例调用的。

/**

* Initializes a reference to the local Bluetooth adapter.

*

* @return Return true if the initialization is successful.

*/

public boolean initialize() {

// For API level 18 and above, get a reference to BluetoothAdapter through

// BluetoothManager.

if (mBluetoothManager == null) {

mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

if (mBluetoothManager == null) {

Log.e(TAG, "Unable to initialize BluetoothManager.");

return false;

}

}

mBluetoothAdapter = mBluetoothManager.getAdapter();

if (mBluetoothAdapter == null) {

Log.e(TAG, "Unable to obtain a BluetoothAdapter.");

return false;

}

return true;

}

4.connect()方法 传入蓝牙地址进行连接蓝牙操作;先判断蓝牙适配器是否为空,然后判断是否刚断开需要重连的设备,否则就通过蓝牙适配器获取BluetoothGatt实例去连接蓝牙操作,后续还会使用到BluetoothGatt去读写操作和断开、关闭操作;

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 我们想直接连接到设备,因此我们设置autoConnect

// parameter to false.

mBluetoothGatt = device.connectGatt(this, false, mGattCallback);

Log.d(TAG, "Trying to create a new connection.");

mBluetoothDeviceAddress = address;

mConnectionState = STATE_CONNECTING;

return true;

}

5.BluetoothGattCallback 回调;这个回调可以说很重要,核心部分,主要对BluetoothGatt的蓝牙连接、断开、读、写、特征值变化等的回调监听,然后我们可以将这些回调信息通过广播机制传播回给广播监听器。

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {

@Override

public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {

}

@Override

public void onServicesDiscovered(BluetoothGatt gatt, int status) {

}

@Override

public void onCharacteristicRead(BluetoothGatt gatt,

BluetoothGattCharacteristic characteristic,

int status) {

}

@Override

public void onCharacteristicChanged(BluetoothGatt gatt,

BluetoothGattCharacteristic characteristic) {

}

};

三、广播监听器

在这个官方demo中,就是使用了广播来作为activity和service之间的数据传递;继续回到源码:activity开启前面所说的服务之后,就注册了这个mGattUpdateReceiver广播;

registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());

if (mBluetoothLeService != null) {

final boolean result = mBluetoothLeService.connect(mDeviceAddress);

Log.d(TAG, "Connect request result=" + result) ;

}

private static IntentFilter makeGattUpdateIntentFilter() {

final IntentFilter intentFilter = new IntentFilter();

intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);

intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);

intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);

intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);

return intentFilter;

}

关于这个广播的回调监听如下:有注释就不多解释了,它的作用就是接收从service发送回来的信息;上文有说到BluetoothGattCallback,就是从这里发送广播的。

// Handles various events fired by the Service. 处理服务部门发起的各种事件

// ACTION_GATT_CONNECTED: connected to a GATT server. 连接到GATT服务器。

// ACTION_GATT_DISCONNECTED: disconnected from a GATT server. 与GATT服务器断开连接。

// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.发现GATT服务

// ACTION_DATA_AVAILABLE: received data from the device.  This can be a result of read

//                        or notification operations. 从设备接收数据。 这可能是阅读的结果

//     //或通知操作。

private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

final String action = intent.getAction();

if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {

mConnected = true;

updateConnectionState(R.string.connected);

invalidateOptionsMenu();

} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {

mConnected = false;

updateConnectionState(R.string.disconnected);

invalidateOptionsMenu();

clearUI();

} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {

// Show all the supported services and characteristics on the user interface.

displayGattServices(mBluetoothLeService.getSupportedGattServices());

} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {

displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));

}

}

};

这里留意一下:当连接成功后,首先service那边会发现服务特征值,通过广播传输回来,然后执行下面的方法:

displayGattServices(mBluetoothLeService.getSupportedGattServices());

四、其他方法

1. setCharacteristicNotification();调用此方法开启特征值的通知;

mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);

2.开启读,我们可以用如下方法,但是此方法有个缺点:要不断轮询 才能达到不断监听;

mBluetoothGatt.readCharacteristic(characteristic);

如果成功,将返回BluetoothGattCallback回调 进入其如下方法

@Override

public void onCharacteristicRead(BluetoothGatt gatt,

BluetoothGattCharacteristic characteristic,

int status) {

if (status == BluetoothGatt.GATT_SUCCESS) {

broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);

}

}

使用如下方法,传入特征值,true

mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);

如果成功,将返回BluetoothGattCallback回调 进入其如下方法

@Override

public void onCharacteristicRead(BluetoothGatt gatt,

BluetoothGattCharacteristic characteristic,

int status) {

if (status == BluetoothGatt.GATT_SUCCESS) {

broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);

}

}

具体选择哪种方法就要看具体需求了。

3.还有一个很重要的方法,demo没有给出例子的:

mBluetoothGatt.writeCharacteristic(characteristic);

这是向蓝牙设备写入数据,几乎都会用到的。

如果成功,将返回BluetoothGattCallback回调 进入其如下方法

@Override

public void onCharacteristicWrite(BluetoothGatt gatt,

BluetoothGattCharacteristic characteristic,

int status) {

}

4. disconnect();调用BluetoothGatt.disconnect()断开蓝牙连接;

public void disconnect() {

if (mBluetoothAdapter == null || mBluetoothGatt == null) {

Log.w(TAG, "BluetoothAdapter not initialized");

return;

}

mBluetoothGatt.disconnect();

}

5.close();关闭蓝牙

/**

* After using a given BLE device, the app must call this method to ensure resources are

* released properly.

*/

public void close() {

if (mBluetoothGatt == null) {

return;

}

mBluetoothGatt.close();

mBluetoothGatt = null;

}

最后,关于Android蓝牙BLE的使用在此结束,我从下载官方demo到一步一步地去理解具体的调用,最后已经算是走通了整个蓝牙开发流程,如果想再深入点的话就要考虑具体的底层实现,和真实项目中怎么去更好地封装!

>>>支持我的话可以关注下我的公众号,一起学习Android、小程序、跨平台开发~

扫一扫关注我的微信公众号:程序猿在广东

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值