Android蓝牙连接远程蓝牙事例

来源:互联网 发布:程序员培训班怎么样 编辑:程序博客网 时间:2024/04/27 16:04

一、应用背景

本文介绍的事例,使用android蓝牙连接远程蓝牙(益体康电子血压计),将血压计采集到高压、低压、心率数据解析后通过蓝牙连接传入android端处理。程序为项目节选,依工程形式打包发布到此,能完整运行,附送源码,希望能对有需要的朋友们有所帮助。


二、流程说明


三、主要源代码

(1)、public class MainActivity extends Activity

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.main);// 数据处理handlerhandler = new BloodPressureHandler(this);// 本地蓝牙操作线程bluetoothDeviceAdapter实现Runnalbe接口bluetoothDeviceAdapter = new BluetoothDeviceAdapter(this, handler);// 启动线程完成蓝牙相关操作:开启、搜索发现、查询配对设备信息、建立与目标设备的连接、进行数据传输、释放连接等new Thread(bluetoothDeviceAdapter).start();}

(2)、public class BluetoothDeviceAdapter implements Runnable

/** *  * @name 蓝牙操作线程 * @descripation 完成蓝牙相关操作:开启、搜索发现、查询配对设备信息、建立与目标设备的连接、进行数据传输、释放连接等 * @author 樊俊彬 * @date 2014-3-22 * @version 1.0 */@SuppressLint("NewApi")public class BluetoothDeviceAdapter implements Runnable {protected Context context;protected UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");protected Map<String, String> measureResult;protected BluetoothDevice bluetoothDevice;protected BluetoothAdapter bluetoothAdapter;protected static BluetoothReciever bluetoothReceiver;protected BluetoothSocket socket;protected Handler handlerBluetooth;protected InputStream inputStream;protected OutputStream outputStream;public int dataLeng = 32;private byte dataHead = (byte) 0x0A;private String DEVICE_NAME = "BP:HC-503B";/** * 构造方法:获取本地蓝牙实例,打开蓝牙,搜索设备信息,查询已配对的设备 *  * @param handler * @throws IOException */public BluetoothDeviceAdapter(Context context, Handler handler) {Log.w("BluetoothDeviceAdapter()", "获取本地蓝牙实例,打开蓝牙,搜索设备信息,查询已配对的设备");bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();openBluetoothAdapter();// registerAndDiscover();queryPairedDevicesInfo();this.context = context;this.handlerBluetooth = handler;measureResult = new HashMap<String, String>();}/** * 根据当前本地蓝牙适配器的状态选择性询问用户启动它 */protected void openBluetoothAdapter() {Log.w("openBluetoothAdapter()", "打开本地蓝牙" + bluetoothAdapter.getName());if (bluetoothAdapter != null) {if (!bluetoothAdapter.isEnabled()) {bluetoothAdapter.enable();Log.i("openBluetoothAdapter", "当前状态为关闭,系统自动打开");}} else {Log.i("openBluetoothAdapter()", "本地设备驱动异常!");}}/** * 注册广播事件监听器,并开始扫描发现设备 */private void registerAndDiscover() {Log.w("registerScan()", "注册广播事件并准备扫描发现周边设备");bluetoothReceiver = new BluetoothReciever();IntentFilter infilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);context.registerReceiver(bluetoothReceiver, infilter);if (bluetoothAdapter.startDiscovery()) {Log.i("bluetoothAdapter", "开始扫描");}}/** * 查询已配对的设备 */private void queryPairedDevicesInfo() {// 通过getBondedDevices方法来获取已经与本设备配对的远程设备信息列表Log.w("queryPairedDevicesInfo()", "查询已配对的设备");Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();if (pairedDevices.size() > 0) {for (BluetoothDevice device : pairedDevices) {Log.i("已配对的设备名称", device.getName());Log.i("已配对的设备地址", device.getAddress());// 查找已配对的,按此目标创建远程bluetoothDeviceif (DEVICE_NAME.equals(device.getName())) {Log.w("发现目标设备,按此创建远程端", DEVICE_NAME);bluetoothDevice = device;break;}}}if (bluetoothDevice == null)Log.i("queryPairedDevices2()", "没有与目标远程端配对的信息");}/** * 线程体:执行连接和读取数据 */@Overridepublic void run() {Log.w("run()", "线程体:执行连接和读取数据");// TODO Auto-generated method stubtry {connect();readData();} catch (IOException e) {measureResult.put("errorInfo", e.getMessage());}Message msg = handlerBluetooth.obtainMessage();msg.obj = this.measureResult;handlerBluetooth.sendMessage(msg);Log.i("AbstractedAdapter", "run()");}/** * 请求与服务端建立连接 */private void connect() {Log.w("connect()", "请求与服务端建立连接");// 客户端bluetoothDevice请求与Server建立连接socketBluetoothSocket socket = null;try {socket = bluetoothDevice.createRfcommSocketToServiceRecord(MY_UUID);socket.connect();if (socket.isConnected()) {Log.i("connect()", "成功连接");}inputStream = socket.getInputStream();} catch (IOException e) {Log.e("connect()", "连接异常");destory();}}/** * 读取socket上InputStream输入流数据 */protected void readData() throws IOException {Log.w("read()", "开始读取socket上InputStream");byte[] dataBuf = new byte[dataLeng];int recTotalCount = 0;try {if (inputStream == null) {destory();return;}int count = 0;while (true) {count = inputStream.available();Log.i("count", String.valueOf(count));Log.i("inputStream.available()",String.valueOf(inputStream.available()));if (count > 0) {int readCount = inputStream.read(dataBuf, recTotalCount,count);recTotalCount += readCount;if (readCount == dataLeng) {break;}} else {Log.i("Thread.sleep(100);", "线程阻塞");Thread.sleep(100);}}// 解析到高压、低压、心率数据String strTemp = this.parseData(dataBuf);String highBloodMeasure = Integer.valueOf(strTemp.substring(4, 8),16).toString();String lowBloodMeasure = Integer.valueOf(strTemp.substring(8, 10),16).toString();String pulseRate = Integer.valueOf(strTemp.substring(10, 12), 16).toString();Log.i("测量到的高压数据", highBloodMeasure);Log.i("测量到的低压数据", lowBloodMeasure);Log.i("测量到的心率", pulseRate);measureResult.put("highBloodMeasure", highBloodMeasure);measureResult.put("lowBloodMeasure", lowBloodMeasure);measureResult.put("pulseRate", pulseRate);} catch (IOException e) {e.printStackTrace();throw new IOException("蓝牙数据传送异常!");} catch (InterruptedException e) {e.printStackTrace();throw new IOException("未知异常,建议重启程序!");} finally {destory();}}/** * 解析byte[]中的字节流到字符串cs中 *  * @param bs * @return */private String parseData(byte[] bs) {Log.i("parseData()", "---");char[] cs = new char[bs.length];for (int i = 0; i < bs.length; i++) {cs[i] = (char) bs[i];}return new String(cs);}/** * 关闭输入输出流,释放连接,关闭蓝牙 */protected void destory() {Log.w("destory()", "关闭输入输出流,释放连接,关闭蓝牙");try {if (inputStream != null) {inputStream.close();inputStream = null;}if (outputStream != null) {outputStream.close();outputStream = null;}if (socket != null) {socket.close();socket = null;}/* * if (bluetoothAdapter != null) { bluetoothAdapter.disable(); } */} catch (IOException e) {e.printStackTrace();}}}


(3)、public class BluetoothReciever extends BroadcastReceiver

/** *  * @name 接收查找到的蓝牙设备信息的广播 * @descripation 注册一个BroadcastReceiver的ACTION_FOUND对象,通过Filter来过滤ACTION_FOUND这个 *               Intent动作以获取每个远程设备的详细信息,通过Intent字段EXTRA_DEVICE 和 *               EXTRA_CLASS可以获得包含了每个BluetoothDevice 对象和对象的该设备类型 BluetoothClass * @author 樊俊彬 * @date 2014-3-22 * @version 1.0 */public class BluetoothReciever extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubLog.w("onReceive()", "发现设备...");String action = intent.getAction();if (BluetoothDevice.ACTION_FOUND.equals(action)) {BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);Log.i("设备名称", device.getName());Log.i("设备地址", device.getAddress());}}}

(4)、public class BloodPressureHandler extends Handler

/** *  * @name 按消息处理数据 * @descripation BluetoothHC503 * @author 樊俊彬 * @date 2014-3-22 * @version 1.0 */public class BloodPressureHandler extends Handler {private Context context;private EditText txtHighBlood; // 血压(mmHg)1private EditText txtLowBlood; // 血压(mmHg)2private EditText txtRate; // 心率public BloodPressureHandler(Context context){this.context = context;}public void handleMessage(Message msg) {//把消息上携带的obj给Map<> bluetoothMeasureDataMap<String, String> bluetoothMeasureData = (Map) msg.obj;if (bluetoothMeasureData == null || bluetoothMeasureData.isEmpty())return;String errorInfo = bluetoothMeasureData.get("errorInfo");Log.i("测量到的高压数据", bluetoothMeasureData.get("highBloodMeasure"));Log.i("测量到的低压数据", bluetoothMeasureData.get("lowBloodMeasure"));Log.i("测量到的心率", bluetoothMeasureData.get("pulseRate"));Log.i("错误信息", bluetoothMeasureData.get("errorInfo"));}}

四、血压计设备相关参数说明


五、附送源码

Bluetooth.rar

0 0
原创粉丝点击