有关蓝牙Ble连接的一些开发探讨
来源:互联网 发布:电子商务专用软件 编辑:程序博客网 时间:2024/05/15 06:52
最近在做手机连接蓝牙血压计、血氧仪和血糖仪的开发,一般这样在设备端是不做任何操作的,只需在手机客户端发送指令达到数据传输。
一、蓝牙的连接
1.首先得判断手机是否支持蓝牙或者打开蓝牙吧,代码如下:
private BluetoothAdapter mBluetoothAdapter;private BluetoothGatt mBluetoothGatt;private List<BluetoothGattService> mGattServiceList;……………………BluetoothManager manager = (BluetoothManager) getSystemService("bluetooth");mBluetoothAdapter = manager.getAdapter(); //判断蓝牙是否可用与是否打开了蓝牙 if(mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { tv_status.setText("please open your bluetooth first"); showOpenBtDialog(); //选择打开蓝牙对话框}
2.打开系统蓝牙设置
/** * 打开蓝牙对话框 */private void showOpenBtDialog() { new AlertDialog.Builder(this) .setMessage("please open your bluetooth") .setPositiveButton("Yes", newDialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int arg1) { // TODO Auto-generated method stub dialog.cancel(); Intent intent = new Inteny(Settings.ACTION_BLUETOOTH_SETTINGS); startActivity(intent); } }).show();}
3.开启蓝牙后,启动扫描
/** * 开始扫描 */private void startScan() { if(!isScanning && !ifSucc && mBluetoothAdapter != null) { tv_status.setText("Scanning..."); mBluetoothAdapter.startLeScan(mLeScanCallback); isScanning = true; }}/** * 结束扫描 */private void stopScan() { if(mBluetoothAdapter != null) { mBluetoothAdapter.stopLeScan(mLeScanCallback); isScanning = false; }}/** * 扫描设备回调 */private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int paramAnonymousInt, byte[] paramAnonymousArrayOfByte) { // TODO Auto-generated method stub runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub Log.i("wsjInfo", "device name= " + device.getName()); if(device.getName() != null && device.getName().equals("MEDXING-BGM")) { //我这里的设备名称是这个 stopScan(); //找到设备停止扫描 mBluetoothGatt = device.connectGatt(BloodSugarActivity.this, false, mBluetoothGattCallback); tv_status.setText("Connecting..."); } } }); } };
4.蓝牙连接成功后,回调这个最重要了。
/** * 蓝牙中央回调 */ private BluetoothGattCallback mBluetoothGattCallback = new BluetoothGattCallback() { @Override //接发数据 public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {// Log.e("onCharacteristicChanged", "onDataChanged"); //获取到蓝牙设备发送的字节数组数据过来 byte[] res = characteristic.getValue(); for(int i=0; i < res.length; i++) { Log.e("wsjInfo", "byte[" + i + "]=" + res[i]); } //具体的处理就看设备通讯协议 Message msg = mHandler.obtainMessage(); msg.what = WHAT_DATACHANGED; msg.obj = res; mHandler.sendMessage(msg); } @Override //连接状态改变 public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {// Log.e("onConnectionStateChange", "status=" + status + ",newState=" + newState); if(newState == BluetoothGatt.STATE_CONNECTED) { //已建立连接 do { ifSucc = mBluetoothGatt.discoverServices(); //discoverServices为异步操作,回调方法为onServicesDiscovered try { Thread.sleep(CONN_AGAIN); } catch (InterruptedException e) { e.printStackTrace(); Log.e("Thread.sleep", "Thread"); } } while(!ifSucc); //没连接成功循环连接 } else if(newState == BluetoothGatt.STATE_DISCONNECTED) { //已断开 mHandler.sendEmptyMessage(WHAT_DISCONNECTED); } } @Override //发现周边服务 public void onServicesDiscovered(BluetoothGatt gatt, int status) {// Log.e("onServicesDiscovered", "status=" + status); if(status == 0) { mHandler.sendEmptyMessage(WHAT_CONNECTED); mGattServiceList = gatt.getServices(); Iterator<BluetoothGattService> iteratorServices = mGattServiceList.iterator(); while(iteratorServices.hasNext()) { BluetoothGattService service = iteratorServices.next(); Iterator<BluetoothGattCharacteristic> itChars = service.getCharacteristics().iterator(); while(itChars.hasNext()) { BluetoothGattCharacteristic characteristic = itChars.next(); String uuid = characteristic.getUuid().toString(); //这里很重要,要找到对应的该设备UUID,然后发指令 if(uuid.equals(UUID5)) { Log.e("wsjInfo", "uuid=" + uuid); characteristic.setValue("C2H"); //可以发字符串指令,可以发byte[]指令,要看每个设备协议 gatt.writeCharacteristic(characteristic); gatt.setCharacteristicNotification(characteristic, true); } } } } } };
二、加权限
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- 蓝牙低功耗设备 --> <uses-feature android:name="android.hardware.bluetooth_le" />
三、附完整代码(我这里做的是美的蓝牙血糖仪的连接)
package com.chainway.nursestation.bluetooth;import java.util.Iterator;import java.util.List;import com.chainway.nursestation.R;import android.app.Activity;import android.app.AlertDialog;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothGatt;import android.bluetooth.BluetoothGattCallback;import android.bluetooth.BluetoothGattCharacteristic;import android.bluetooth.BluetoothGattService;import android.bluetooth.BluetoothManager;import android.content.DialogInterface;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.provider.Settings;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;public class BloodSugarActivity extends Activity implements OnClickListener { private static final long CONN_AGAIN = 3000L; // 重连(3s) /** * 因为开发文档和协议有些没有,UUID是我一个一个Log打印出来尝试 * 发现那个设备后,可以获取它的所有UUID,每个试着匹配发指令 */// private static final String UUID1 = "00002a00-0000-1000-8000-00805f9b34fb";// private static final String UUID2 = "00002a01-0000-1000-8000-00805f9b34fb";// private static final String UUID3 = "00002a05-0000-1000-8000-00805f9b34fb";// private static final String UUID4 = "0000ffb1-0000-1000-8000-00805f9b34fb"; private static final String UUID5 = "0000ffb2-0000-1000-8000-00805f9b34fb"; //// private static final String UUID6 = "00002a24-0000-1000-8000-00805f9b34fb";// private static final String UUID7 = "00002a25-0000-1000-8000-00805f9b34fb";// private static final String UUID8 = "00002a27-0000-1000-8000-00805f9b34fb";// private static final String UUID9 = "00002a28-0000-1000-8000-00805f9b34fb";// private static final String UUID10 = "00002a29-0000-1000-8000-00805f9b34fb"; private BluetoothAdapter mBluetoothAdapter; private BluetoothGatt mBluetoothGatt; private List<BluetoothGattService> mGattServiceList; private boolean ifSucc; //是否连接成功 private boolean isScanning; //正在扫描 private TextView tv_status, tv_tips, tv_result; private TextView tv_back, tv_reconnect, tv_upload; private static final int WHAT_DISCONNECTED = 0; //连接断开 private static final int WHAT_CONNECTED = 1; //已连接 private static final int WHAT_DATACHANGED = 2; //数据获取 private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case WHAT_CONNECTED: //已连接 tv_status.setText("Connected(MEDXING-BGM)"); break; case WHAT_DISCONNECTED: //连接断开 tv_status.setText("Disconnected"); tv_tips.setText(R.string.text_disconn); tv_result.setText("--"); ifSucc = false; break; case WHAT_DATACHANGED: //获取数据 byte[] res = (byte[]) msg.obj; if(res.length == 6 && res[3] == -102 && res[5] == 113) { //还没插入测试纸 tv_tips.setText(R.string.text_tips1); tv_result.setText("--"); } else if(res.length == 6 && res[3] == -99 && res[5] == 116) { //测试纸有误 tv_tips.setText(R.string.text_tips2); tv_result.setText("--"); } else if(res.length == 12) { //已插入测试纸 tv_tips.setText(R.string.text_tips3); tv_result.setText("--"); } else if(res.length == 7) { //测量中,倒计时5,4,3,2,1 tv_tips.setText(R.string.text_tips4); tv_result.setText(String.valueOf(res[6])); } else if(res.length == 9) { //测量结果 if(res[6] == 0 && res[7] == 0) { tv_tips.setText(R.string.text_tips5); tv_result.setText("--"); } else { tv_tips.setText(R.string.text_tips6); tv_result.setText((res[6] * 256.0 + res[7] / 10.0) + " mmol/L"); } } break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_blood_sugar); init(); //初始化 } private void init() { tv_status = (TextView) findViewById(R.id.tv_status); tv_tips = (TextView) findViewById(R.id.tv_tips); tv_result = (TextView) findViewById(R.id.tv_result); tv_back = (TextView) findViewById(R.id.tv_back); tv_back.setOnClickListener(this); tv_reconnect = (TextView) findViewById(R.id.tv_reconnect); tv_reconnect.setOnClickListener(this); tv_upload = (TextView) findViewById(R.id.tv_upload); tv_upload.setOnClickListener(this); BluetoothManager manager = (BluetoothManager) getSystemService("bluetooth"); mBluetoothAdapter = manager.getAdapter(); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); if(mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { tv_status.setText("please open your bluetooth first"); showOpenBtDialog(); } else { startScan(); //开始扫描 } } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); stopScan(); } /** * 打开蓝牙对话框 */ private void showOpenBtDialog() { new AlertDialog.Builder(this) .setMessage("please open your bluetooth") .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int arg1) { // TODO Auto-generated method stub dialog.cancel(); Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS); startActivity(intent); } }).show(); } /** * 开始扫描 */ private void startScan() { if(!isScanning && !ifSucc && mBluetoothAdapter != null) { tv_status.setText("Scanning..."); mBluetoothAdapter.startLeScan(mLeScanCallback); isScanning = true; } } /** * 结束扫描 */ private void stopScan() { if(mBluetoothAdapter != null) { mBluetoothAdapter.stopLeScan(mLeScanCallback); isScanning = false; } } private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int paramAnonymousInt, byte[] paramAnonymousArrayOfByte) { // TODO Auto-generated method stub runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub Log.e("wsjInfo", "device name= " + device.getName()); if(device.getName() != null && device.getName().equals("MEDXING-BGM")) { stopScan(); //找到设备停止扫描 mBluetoothGatt = device.connectGatt(BloodSugarActivity.this, false, mBluetoothGattCallback); tv_status.setText("Connecting..."); } } }); } }; /** * 蓝牙中央回调 */ private BluetoothGattCallback mBluetoothGattCallback = new BluetoothGattCallback() { @Override //接发数据 public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {// Log.e("onCharacteristicChanged", "onDataChanged"); byte[] res = characteristic.getValue(); for(int i=0; i < res.length; i++) { Log.e("wsjInfo", "byte[" + i + "]=" + res[i]); } Message msg = mHandler.obtainMessage(); msg.what = WHAT_DATACHANGED; msg.obj = res; mHandler.sendMessage(msg); } @Override //连接状态改变 public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {// Log.e("onConnectionStateChange", "status=" + status + ",newState=" + newState); if(newState == BluetoothGatt.STATE_CONNECTED) { //已建立连接 do { ifSucc = mBluetoothGatt.discoverServices(); //discoverServices为异步操作,回调方法为onServicesDiscovered try { Thread.sleep(CONN_AGAIN); } catch (InterruptedException e) { e.printStackTrace(); Log.e("Thread.sleep", "Thread"); } } while(!ifSucc); //没连接成功循环连接 } else if(newState == BluetoothGatt.STATE_DISCONNECTED) { //已断开 mHandler.sendEmptyMessage(WHAT_DISCONNECTED); } } @Override //发现周边服务 public void onServicesDiscovered(BluetoothGatt gatt, int status) {// Log.e("onServicesDiscovered", "status=" + status); if(status == 0) { mHandler.sendEmptyMessage(WHAT_CONNECTED); mGattServiceList = gatt.getServices(); Iterator<BluetoothGattService> iteratorServices = mGattServiceList.iterator(); while(iteratorServices.hasNext()) { BluetoothGattService service = iteratorServices.next(); Iterator<BluetoothGattCharacteristic> itChars = service.getCharacteristics().iterator(); while(itChars.hasNext()) { BluetoothGattCharacteristic characteristic = itChars.next(); String uuid = characteristic.getUuid().toString(); if(uuid.equals(UUID5)) { Log.e("wsjInfo", "uuid=" + uuid); characteristic.setValue("C2H"); gatt.writeCharacteristic(characteristic); gatt.setCharacteristicNotification(characteristic, true); } } } } } }; @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.tv_back: //返回 finish(); break; case R.id.tv_reconnect: //重新连接 if(!isScanning && !ifSucc) { startScan(); } else { toastMsg(R.string.msg_conned); } break; case R.id.tv_upload: //上传 if(tv_result.getText().toString().contains("mmol/L")) { toastMsg(R.string.msg_upload_succ); } else { toastMsg(R.string.msg_noresult); } break; default: break; } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); stopScan(); ifSucc = true; if(mBluetoothGatt != null) { mBluetoothGatt.disconnect(); mBluetoothGatt.close(); } } private Toast toast; private void toastMsg(String msg) { if(toast != null) { toast.cancel(); } toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT); toast.show(); } private void toastMsg(int resId) { toastMsg(getString(resId)); }}
0 0
- 有关蓝牙Ble连接的一些开发探讨
- 有关android蓝牙的一些资料连接
- 收集的一些蓝牙4.0 BLE开发资料
- 收集的一些蓝牙4.0 BLE开发资料
- 蓝牙协议分析——BLE连接有关的技术分析
- BLE和传统蓝牙的一些比较
- 蓝牙解析(part7):BLE的连接
- Ble 蓝牙连接
- 医疗设备BLE蓝牙开发的总结。
- Android 蓝牙4.0(ble)开发的解决方案
- BLE蓝牙开发的基本步骤
- 初学BLE蓝牙底层开发的常识
- 蓝牙BLE开发的各种坑
- Android蓝牙BLE应用的开发
- iOS开发—蓝牙4.0(BLE)与外设连接及收发数据的流程
- iOS蓝牙Ble开发
- Android Ble蓝牙开发
- android BLE蓝牙开发
- eclipse无法进入调试程序
- 编译安装vim-8.0 (centos)
- 关于服务器operating system not found的一些问题
- JVM如何判断一个Java对象是否可以回收
- ZooKeeper分布式环境部署
- 有关蓝牙Ble连接的一些开发探讨
- 查看lib导出函数的方法
- javascript中的预编译问题
- Jquery 的each事件
- USB OTG学习笔记
- Android ImageView 正确使用姿势
- 报表平台
- firebug的使用
- guava之BiMap