有关蓝牙Ble连接的一些开发探讨
2016-12-28 14:33
274 查看
最近在做手机连接蓝牙血压计、血氧仪和血糖仪的开发,一般这样在设备端是不做任何操作的,只需在手机客户端发送指令达到数据传输。
一、蓝牙的连接
1.首先得判断手机是否支持蓝牙或者打开蓝牙吧,代码如下:
2.打开系统蓝牙设置
3.开启蓝牙后,启动扫描
4.蓝牙连接成功后,回调这个最重要了。
二、加权限
三、附完整代码(我这里做的是美的蓝牙血糖仪的连接)
一、蓝牙的连接
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)); } }
相关文章推荐
- Android 低功耗蓝牙(BLE)开发(4)-- 蓝牙扫描和连接
- 蓝牙协议分析(7)_BLE连接有关的技术分析
- 蓝牙协议分析——BLE连接有关的技术分析
- Android BLE低功耗蓝牙开发极简系列(一)之扫描与连接
- 关于samsung连接BLE设备的一些资料汇总和开发过程一些经验总结
- TI BLE开发(二)修改蓝牙连接参数
- 关于samsung连接BLE设备的一些资料汇总和开发过程一些经验总结
- 蓝牙协议分析(7)_BLE连接有关的技术分析
- android 蓝牙ble app开发(二) -- 关键概念,连接参数,连接请求
- 蓝牙协议分析(7)_BLE连接有关的技术分析
- 有关android蓝牙的一些资料连接
- android 蓝牙ble app开发(二) -- 关键概念,连接参数,连接请求
- 有关WEB开发时session的一些基础
- 有关项目开发过程中,管理工具的使用等方面的一些文章。
- 分享: 有关主机和SAN存储连接, LUN识别的一些原理
- 基于《关于Java开发不明白的一些问题》,探讨一下Struts1和Struts2
- 设备安全配置不允许连接。请确保您具有所开发设备的适当证书。有关连接此设备的正确安全设置,请查阅 SDK 文档
- 有关web开发的一些想法
- 移动开发上有关终端上GPRS 连接和 PDP 上下文的对应关系的讨论
- 设备安全配置不允许连接。请确保您具有所开发设备的适当证书。有关连接此设备的正确安全设置,请查阅 SDK 文档