您现在的位置是:首页 > 数码 > 

STM2与BLE蓝牙通信 Android APP配置(二)

2025-07-18 22:56:32
STM2与BLE蓝牙通信 Android APP配置(二) 事务的难度远远低于对事物的恐惧 0.前言 在 Android BLE蓝牙配置全流程(一) 附APP源码 中已经完成了前期的准备工作,在这里我们得到了需要连接的蓝牙设备的名字和地址,需要完成蓝牙设备的连接和数据传输功能。 1.初始化界面 首先需要完成对这个界面包含的控件进行

STM2与BLE蓝牙通信 Android APP配置(二)

事务的难度远远低于对事物的恐惧

0.前言

Android BLE蓝牙配置全流程(一) 附APP源码 中已经完成了前期的准备工作,在这里我们得到了需要连接的蓝牙设备的名字和地址,需要完成蓝牙设备的连接和数据传输功能。

1.初始化界面

首先需要完成对这个界面包含的控件进行初始化,代码如下:

private TextView text1, text2;
private EditText editText;
private Button btn_send;
private String status = Disconnected;
private final static String TAG = hello;//界面初始化private void initView() {text1 = findViewById(R.);text2 = findViewById(R.);editText = findViewById(R._text);btn_send = findViewById(R.id.btn_send);text1.setText(状态:  status);btn_send.setOnClickListener(this);}

控件text1中显示目前的连接状态,控件text2中显示接收到的数据,控件edittext中输入要发送的数据,控件btn_send是发送按钮

2.获取前一个界面传来的数据

首先得到前一个界面传来的数据,代码如下:

public static String EXTRAS_DEVICE_AME = DEVICE_AME;
public static String EXTRAS_DEVICE_ADDRESS = DEVICE_ADDRESS;private Bundle bundle;
private String name;
private String address;bundle = getIntent().getExtras();
name = bundle.getString(EXTRAS_DEVICE_AME);
address = bundle.getString(EXTRAS_DEVICE_ADDRESS);

name中存放蓝牙设备的名字,address中存放蓝牙设备的地址。

.创建一个服务类并继承Service

本文中创建了一个BlutoothBLEService 并继承了Service,完成蓝牙设备的初始化、连接、断开连接、读取特征值、写入特征值、设置特征值变化通知以及获取已连接蓝牙的所有服务等操作。

public class BlutoothBLEService extends Service {...............................
}

.1 蓝牙设备初始化

public final static String ACTIO_GATT_COECTED = bluebledemo.ACTIO_GATT_COECTED;
public final static String ACTIO_GATT_DISCOECTED = bluebledemo.ACTIO_GATT_DISCOECTED;
public final static String ACTIO_GATT_SERVICES_DISCOVERED = bluebledemo.ACTIO_GATT_SERVICES_DISCOVERED;
public final static String ACTIO_DATA_AVAILABLE = bluebledemo.ACTIO_DATA_AVAILABLE;
public final static String EXTRA_DATA = bluebledemo.EXTRA_DATA;private final static int STATE_DISCOECTED = 0;
private final static int STATE_COECTIG = 1;
private final static int STATE_COECTED = 2;private final static String TAG = hello;private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;//蓝牙初始化 在第二个界面中的ServiceConnection中调用
public boolean initialize() {if (mBluetoothManager == null) {mBluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);if (mBluetoothManager == null) {Log.i(TAG, initialize: mBluetoothManager 初始化失败);return false;}}mBluetoothAdapter = mBluetoothManager.getAdapter();if (mBluetoothAdapter == null) {Log.i(TAG, initialize: mBluetoothAdapter 初始化失败);return false;}return true;
}

上面代码是在第二个界面成功绑定这个服务之后,在回调函数ServiceConnection中被执行,下文将详细介绍,这里先把这个服务详细的说清楚。

.2 蓝牙设备的连接

private BluetoothGatt mBluetoothGatt;//蓝牙连接外围设备
public boolean connect(final String address) {if (mBluetoothAdapter == null || address == null) {Log.i(TAG, connect: BLE not init);return false;}if (mBluetoothDeviceAddress != null && mBluetoothGatt != null && (address)) {Log.i(TAG, connect: Trying to use an existing mBluetoothGatt for connection);if (()) {mConnectionState = STATE_COECTIG;return true;} else {return false;}}final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);if (device == null) {Log.i(TAG, connect: device not found);return false;}mBluetoothGatt = (this, false, mGattCallback);Log.i(TAG, connect: Trying to create a connection);mBluetoothDeviceAddress = address;mConnectionState = STATE_COECTIG;return true;
}

在第二个界面中会创建一个BlutoothBLEService类的对象,然后调用这个方法并传入地址,即可连接成功。mBluetoothGatt = (this, false, mGattCallback)通过绑定回调函数,本节的后续操作都可在回调函数中完成相应的操作。

. 蓝牙设备取消连接

//取消连接
public void disconnect() {if (mBluetoothAdapter == null || mBluetoothGatt == null) {Log.i(TAG, disconnect: BLE not init);return;}mBluetoothGatt.disconnect();
}//关闭所有蓝牙连接
public void close() {if (mBluetoothGatt == null) {return;}();mBluetoothGatt = null;
}

同样通过BlutoothBLEService类的对象调用这个方法即可取消连接。

.4 读取特征值

//读取特征值
public void readCharacteristic(BluetoothGattCharacteristic characteristic) {if (mBluetoothAdapter == null || mBluetoothGatt == null) {Log.i(TAG, readCharacteristic: BLE not init);return;}mBluetoothGatt.readCharacteristic(characteristic);
}

在蓝牙设备连接成功后自动读一次特征值。

.5 写入特征值

//写入特征值
public void writeCharacteristic(BluetoothGattCharacteristic characteristic) {if (mBluetoothAdapter == null || mBluetoothGatt == null) {Log.i(TAG, writeCharacteristic: BLE not init);return;}mBluetoothGatt.writeCharacteristic(characteristic);
}

这是完成手机APP向蓝牙设备写数据的操作。

.6 设置特征值变化通知
这个很重要,如果不设置话,手机APP是接收不到蓝牙设备发送的数据。

//设置特征值变化通知
public void setCharacteristicotification(BluetoothGattCharacteristic characteristicotification, boolean enabled) {if (mBluetoothAdapter == null || mBluetoothGatt == null) {Log.i(TAG, setCharacteristicotification: BLE not init);return;}mBluetoothGatt.setCharacteristicotification(characteristicotification, enabled);BluetoothGattDescriptor descriptor = characteristicotification.getDescriptor(UUID.fromString(00002902-0000-1000-8000-00805f9b4fb));if (enabled) {descriptor.setValue(BluetoothGattDescriptor.EABLE_OTIFICATIO_VALUE);} else {descriptor.setValue(BluetoothGattDescriptor.DISABLE_OTIFICATIO_VALUE);}mBluetoothGatt.writeDescriptor(descriptor);
}

这个方法同样也是在第二个界面中调用的,其中UUID.fromString(00002902-0000-1000-8000-00805f9b4fbHC-08蓝牙设备的监听UUID,如果蓝牙设备不是一个型号,请更改为自己所用的蓝牙设备的监听UUID

.7 获取已连接蓝牙的所有服务

//获取已连接蓝牙的所有服务
public List<BluetoothGattService> getDupportedGattServices() {if (mBluetoothGatt == null) {return null;}return mBluetoothGatt.getServices();
}

返回已经连接蓝牙设备的所有服务。

.8 读取蓝牙设备的RSSI值

//读取RSSI
public void readRssi() {if (mBluetoothAdapter == null || mBluetoothGatt == null) {Log.i(TAG, readRssi: BLE not init);return;}mBluetoothGatt.readRemoteRssi();
}

该方法返回的是已连接的蓝牙设备的信号值(RSSI)。

.9 连接外围设备的回调函数

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {@Override//重写 蓝牙连接状态public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {if (status == BluetoothGatt.GATT_SUCCESS) {String intentAction;if (newState == BluetoothProfile.STATE_COECTED) {intentAction = ACTIO_GATT_COECTED;mConnectionState = STATE_COECTED;broadcastUpdate(intentAction);mBluetoothGatt.discoverServices();   //发现服务} else if (newState == BluetoothProfile.STATE_DISCOECTED) {intentAction = ACTIO_GATT_DISCOECTED;mConnectionState = STATE_DISCOECTED;broadcastUpdate(intentAction);}}}//重写 蓝牙发现服务@Overridepublic void onServicesDiscovered(BluetoothGatt gatt, int status) {if (status == BluetoothGatt.GATT_SUCCESS) {broadcastUpdate(ACTIO_GATT_SERVICES_DISCOVERED);Log.i(TAG, onServicesDiscovered: 蓝牙发现服务);} else {Log.i(TAG, onServicesDiscovered: 蓝牙发现服务失败  status);}}//重写 蓝牙读特征@Overridepublic void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {if (status == BluetoothGatt.GATT_SUCCESS) {Log.i(TAG, onCharacteristicRead: is called);byte[] sucString = characteristic.getValue();broadcastUpdate(ACTIO_DATA_AVAILABLE, characteristic);}}//重写 蓝牙写特征@Overridepublic void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {Log.i(TAG, onCharacteristicWrite: 写数据成功);}//重写 蓝牙特征改变@Overridepublic void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {Log.i(TAG, onCharacteristicChanged: changed changed changed changed changed );broadcastUpdate(ACTIO_DATA_AVAILABLE, characteristic);}//重写 蓝牙读描述值@Overridepublic void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {if (status == BluetoothGatt.GATT_SUCCESS) {Log.i(TAG, onDescriptorRead: Read Read Read);byte[] desc = descriptor.getValue();if (desc == null) {Log.i(TAG, onDescriptorRead: desc is null null null);}}}//重写 蓝牙写描述值@Overridepublic void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {if (status == BluetoothGatt.GATT_SUCCESS) {Log.i(TAG, onDescriptorWrite: Write Write Write);}}@Overridepublic void onReliableWriteCompleted(BluetoothGatt gatt, int status) {if (status == BluetoothGatt.GATT_SUCCESS) {Log.i(TAG, onReliableWriteCompleted: onReliableWriteCompleted onReliableWriteCompleted onReliableWriteCompleted);}}//重写 获取蓝牙信号值@Overridepublic void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {if (status == BluetoothGatt.GATT_SUCCESS) {Log.i(TAG, onReliableWriteCompleted: RSSI RSSI RSSI);broadcastUpdate(ACTIO_DATA_AVAILABLE, rssi);}}
};

在这个回调函数中可以得到已连接的蓝牙设备的所有状态,包括:是否连接成功、是否发送数据成功以及是否读取数据成功等等,然后在这个服务中通过BroadCast(广播)将信息发出去,在第二个界面中设置广播的监听接收器,进而完成数据的传输。

.10 发送广播

//更新广播
private void broadcastUpdate(final String action) {final Intent intent = new Intent(action);sendBroadcast(intent);
}//更新广播
private void broadcastUpdate(final String action, int rssi) {final Intent intent = new Intent(action);intent.putExtra(EXTRA_DATA, rssi);sendBroadcast(intent);
}//更新广播
private void broadcastUpdate(final String action, final BluetoothGattCharacteristic characteristic) {final Intent intent = new Intent(action);final byte[] data = characteristic.getValue();//将data的数据传输给主空间中保存if (data != null && data.length > 0) {final StringBuilder stringBuilder = new StringBuilder(data.length);for (byte byteChar : data) {stringBuilder.append(String.format(%02X, byteChar));Log.i(TAG, broadcastUpdate: byteChar is:  byteChar);}intent.putExtra(BLE_BYTE_DATA, data);intent.putExtra(EXTRA_DATA, new String(data));}sendBroadcast(intent);}

通过广播的形式将数据发出去,在第二个界面中通过设置过滤器接收对应的广播。

.11 获取服务的对象

当在第二个界面中成功绑定了该服务,通过调用这个方法即可返回一个该服务的对象。

public class LocalBinder extends Binder {public BlutoothBLEService getService() {return ;}}@ullable
@Override
public IBinder onBind(Intent intent) {return mBinder;
}public boolean onUnbind(Intent intent) {close();return (intent);
}

4.绑定服务

在完成服务的代码编写之后,接着需要在第二个界面中绑定该服务,在onCreat方法中进行绑定,代码如下:

Intent getServiceIntent = new Intent(this, );
bindService(getServiceIntent, mServiceConnection, BID_AUTO_CREATE);

5.绑定服务的回调函数

是否成功的绑定了服务,我们可以在回调函数中获知,代码如下:

private BlutoothBLEService mBlutoothBLEService;//服务()连接 回调函数
private final ServiceConnection mServiceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(Componentame name, IBinder service) {mBlutoothBLEService = ((BlutoothBLEService.LocalBinder) service).getService();if (!mBlutoothBLEService.initialize()) {Log.i(TAG, onServiceConnected: MainActivity BLE not init);finish();}Log.i(TAG, onServiceConnected: 8888888888888);(address);}@Overridepublic void onServiceDisconnected(Componentame name) {mBlutoothBLEService = null;}
};

如果绑定成功,首先执行mBlutoothBLEService = ((BlutoothBLEService.LocalBinder) service).getService()获取这个服务的对象,然后执行mBlutoothBLEService.initialize()对服务进行初始化。

6.注册/取消注册广播

//注册广播和IntentFilter
@Override
protected void onResume() {registerReceiver(mBroadCastReceiver, makeGattUpdateIntentFilter());if (mBlutoothBLEService != null) {Log.i(TAG, onResume: 99999999999999);boolean res = (address);Log.i(TAG, onResume:   res);}();
}//取消注册广播和IntentFilter
@Override
protected void onDestroy() {unregisterReceiver(mBroadCastReceiver);mBlutoothBLEService = null;();
}

上述代码利用registerReceiver(mBroadCastReceiver, makeGattUpdateIntentFilter())unregisterReceiver(mBroadCastReceiver)方法完成注册和取消注册广播,下面的代码是设置广播接收和过滤器。

//IntentFilter 设置过滤 与广播进行注册
public IntentFilter makeGattUpdateIntentFilter() {IntentFilter filter = new IntentFilter();filter.addAction(BlutoothBLEService.ACTIO_GATT_COECTED);filter.addAction(BlutoothBLEService.ACTIO_GATT_DISCOECTED);filter.addAction(BlutoothBLEService.ACTIO_GATT_SERVICES_DISCOVERED);filter.addAction(BlutoothBLEService.ACTIO_DATA_AVAILABLE);return filter;
}
//设置广播接收 服务()传过来得信息
BroadcastReceiver mBroadCastReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String actionString = intent.getAction();if (BlutoothBLEService.ACTIO_GATT_(actionString)) {	//蓝牙设备连接成功Log.i(TAG, onReceive:   name   连接成功);status = Connected;updateConnectionState(status);} else if (BlutoothBLEService.ACTIO_GATT_DIS(actionString)) {	//蓝牙设备连接失败Log.i(TAG, onReceive:   name   断开连接);status = Disconnected;updateConnectionState(status);} else if (BlutoothBLEService.ACTIO_GATT_SERVICES_(actionString)) {	//蓝牙设备设置服务Log.i(TAG, onReceive: 广播接收到服务);displayGattServices(mBlutoothBLEService.getDupportedGattServices());} else if (BlutoothBLEService.ACTIO_DATA_(actionString)) {	//蓝牙设备有数据提供Log.i(TAG, onReceive: 有数据);displayData(intent.getExtras().getString(BlutoothBLEService.EXTRA_DATA), intent);}}
};

其中displayGattServices(mBlutoothBLEService.getDupportedGattServices())进一步完成发现服务,displayData(intent.getExtras().getString(BlutoothBLEService.EXTRA_DATA), intent)进一步完成数据接收的处理,updateConnectionState(status)是完成蓝牙状态的更新操作,这三个代码将在下文进行说明。

7.发现已连接蓝牙设备服务

public static String CHARACTERISTIC_UUID = 0000ffe1-0000-1000-8000-00805f9b4fb;
private BluetoothGattCharacteristic target_chara;
private Handler mHandler = new Handler();//服务
public void displayGattServices(List<BluetoothGattService> gattServices) {if (gattServices == null) {return;}for (BluetoothGattService service : gattServices) {List<BluetoothGattCharacteristic> gattCharacteristics = service.getCharacteristics();for (final BluetoothGattCharacteristic characteristic : gattCharacteristics) {if (characteristic.getUuid().toString().equals(CHARACTERISTIC_UUID)) {mHandler.postDelayed(new Runnable() {@Overridepublic void run() {mBlutoothBLEService.readCharacteristic(characteristic);}}, 200);mBlutoothBLEService.setCharacteristicotification(characteristic, true);target_chara = characteristic;}}}
}

其中CHARACTERISTIC_UUIDHC-08蓝牙设备的读写特征UUID,如果使用的蓝牙设备型号不一样请改为自己所用的蓝牙设备的读写特征UUID,根据这个UUID到蓝牙设备的读写特征,从而设置特征变化通知和记录这个特征。

8.数据的接收

//接收的数据
public void displayData(String rev_string, Intent intent) {try {byte[] data = intent.getByteArrayExtra(BLE_BYTE_DATA);if (data == null) {Log.i(TAG, displayData: data is empty);return;}rev_string = new String(data, 0, data.length, GB212);} catch (UnsupportedEncodingException e) {e.printStackTrace();}rev_str = rev_str  rev_string;runOnUiThread(new Runnable() {@Overridepublic void run() {text2.setText(rev_str);}});
}

上面的代码完成数据的接收,并将接收到的数据放入控件text2中进行追加显示。

9.更新蓝牙连接状态

private tempHandler myHandler = new tempHandler();
private String rev_str = ;//更新蓝牙连接状态
private void updateConnectionState(String Status) {Message msg = new Message();msg.what = 1;Bundle bundle = new Bundle();bundle.putString(connect_state, status);msg.setData(bundle);myHandler.sendMessage(msg);
}private class tempHandler extends Handler {@Overridepublic void handleMessage(@onull Message msg) {switch (msg.what) {case 1:String str;str = msg.getData().getString(connect_state);text1.setText(状态:  str);break;}super.handleMessage(msg);}
}

在控件text1中更新显示当前蓝牙的连接状态。

10.发送数据

//发送数据线程
public class sendDataThread implements Runnable {public sendDataThread() {new Thread(this).start();}@Overridepublic void run() {if (editText.getText() != null) {byte[] buff = null;try {buff = editText.getText().toString().getBytes(GB212);Log.i(TAG, run:   buff.length);} catch (UnsupportedEncodingException e) {e.printStackTrace();}int[] sendDataLens = dataSparate(buff.length);for (int i = 0; i < sendDataLens[0]; i) {byte[] data20 = new byte[20];for (int j = 0; j < 20; j) {data20[j] = buff[i * 20  j];}target_chara.setValue(data20);mBlutoothBLEService.writeCharacteristic(target_chara);}if (sendDataLens[1] != 0) {byte[] lastData = new byte[sendDataLens[1]];for (int i = 0; i < sendDataLens[1]; i) {lastData[i] = buff[sendDataLens[0] * 20  i];}if (lastData != null) {target_chara.setValue(lastData);mBlutoothBLEService.writeCharacteristic(target_chara);} else {Log.i(TAG, run: last是空的);}}}}
}//发送数据实现点击事件
@Override
public void onClick(View v) {new sendDataThread();
}//数据分包处理
private int[] dataSparate(int len) {int[] lens = new int[2];lens[0] = len / 20;lens[1] = len % 20;return lens;
}

通过点击发送按钮,创建一个发送数据的线程,发送的数据将进行分包处理依次发送,确保即使数据太大也能成功的发送。

至此Android的BLE蓝牙(HC-08)的配置全流程都已详细的说明,如有任何问题可以留言或者私信我,看到会及时回复,上述的内容如果有误,还请各位大佬不吝赐教,在此,祝愿各位学习顺利,前途无限~

Android BLE蓝牙(HC-08)源码免费获取方式

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/shuma/845588.html

相关标签:无
上传时间: 2024-02-05 11:50:55
留言与评论(共有 13 条评论)
本站网友 牛粪有的是2
12分钟前 发表
onServiceConnected
本站网友 拓展教练
12分钟前 发表
is called);byte[] sucString = characteristic.getValue();broadcastUpdate(ACTIO_DATA_AVAILABLE
本站网友 汽车行业发展前景
22分钟前 发表
IBinder service) {mBlutoothBLEService = ((BlutoothBLEService.LocalBinder) service).getService();if (!mBlutoothBLEService.initialize()) {Log.i(TAG
本站网友 爱之深恨之切
30分钟前 发表
characteristic);}}//重写 蓝牙写特征@Overridepublic void onCharacteristicWrite(BluetoothGatt gatt
本站网友 食人蝇
2分钟前 发表
initialize
本站网友 油土鳖
13分钟前 发表
onReceive
本站网友 广东云联惠
21分钟前 发表
BLE not init);return false;}if (mBluetoothDeviceAddress != null && mBluetoothGatt != null && (address)) {Log.i(TAG
本站网友 万州高笋塘
5分钟前 发表
int status) {Log.i(TAG
本站网友 乳腺炎的症状
24分钟前 发表
BLE not init);return;}mBluetoothGatt.readRemoteRssi(); } 该方法返回的是已连接的蓝牙设备的信号值(RSSI)
本站网友 厨卫吊顶
15分钟前 发表
.创建一个服务类并继承Service 本文中创建了一个BlutoothBLEService 并继承了Service,完成蓝牙设备的初始化
本站网友 向南方
5分钟前 发表
onReceive
本站网友 手机下载
12分钟前 发表
onReceive