手里有一台蓝牙的血压计,正好厂家发来了对接协议,于是开发了个安卓程序,可以实时接收血压计测量的数据。主要实现的功能有:
1、自动扫描蓝牙设备并配对
2、当发现设备工作时自动连接设备(因设备长时间休眠状态的,需要一旦发现设备工作就立刻保持蓝牙连接)
3、通过消息订阅实现设备状态的检测(如发现设备、匹配设备、连接设备,设备离线等)
4、收到测量结果后自动将数据通过网络上传至服务器用于统计和记录。
5、在手机app中可对设备进行控制,如开始测量、停止测量功能。
准备素材:
1、平板一个
2、血压设备(支持蓝牙)
开发工具:adnroid studio
开发语言:java
说明:代码中为了实现连接指定设备,代码中有配置蓝牙名称的变量,用以发现此蓝牙设备发起主动连接。
蓝牙电子血压计
工作中的状态
采集到的数据
开发代码环境
布局图
蓝牙工具类BleController:
使用单例模式实例化获取类,主要实现蓝牙设备的扫描、连接、状态检测及数据读写等操作。
具体功能可以看代码及注释。
package com.totcms.blefamdoc.bleutils;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.totcms.blefamdoc.bleutils.callback.BleDevceScanCallback;
import com.totcms.blefamdoc.bleutils.callback.ConnectCallback;
import com.totcms.blefamdoc.bleutils.callback.OnReceiverCallback;
import com.totcms.blefamdoc.bleutils.callback.OnWriteCallback;
import com.totcms.blefamdoc.bleutils.callback.ScanCallback;
import com.totcms.blefamdoc.bleutils.request.ReceiverRequestQueue;
import com.totcms.blefamdoc.utils.HexUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
public class BleController {
private static final String TAG = "BleController";
private static BleController mBleController;
private Context mContext;
private BluetoothManager mBlehManager;
private BluetoothAdapter mBleAdapter;
private BluetoothGatt mBleGatt;
private BluetoothGattCharacteristic mBleGattCharacteristic;
private Handler mHandler = new Handler(Looper.getMainLooper());
private BleGattCallback mGattCallback;
private OnWriteCallback writeCallback;
private boolean mScanning;
//默认扫描时间:10s
private static final int SCAN_TIME = 10000;
//默认连接超时时间:10s
private static final int CONNECTION_TIME_OUT = 10000;
//获取到所有服务的集合
private HashMap<String, Map<String, BluetoothGattCharacteristic>> servicesMap = new HashMap<>();
//连接请求是否ok
private boolean isConnectok = false;
//是否是用户手动断开
private boolean isMybreak = false;
//连接结果的回调
private ConnectCallback connectCallback;
//读操作请求队列
private ReceiverRequestQueue mReceiverRequestQueue = new ReceiverRequestQueue();
//此属性一般不用修改
private static final String BLUETOOTH_NOTIFY_D = "00002902-0000-1000-8000-00805f9b34fb";
//TODO 以下uuid根据公司硬件改变
public String UUID_SERVICE = "0000fff0-0000-1000-8000-00805f9b34fb";
public String UUID_INDICATE = "0000000-0000-0000-8000-00805f9b0000";
public String UUID_NOTIFY = "0000fff6-0000-1000-8000-00805f9b34fb";
public String UUID_WRITE = "0000fff6-0000-1000-8000-00805f9b34fb";
public String UUID_READ = "0000fff6-0000-1000-8000-00805f9b34fb";
public static synchronized BleController getInstance() {
if (null == mBleController) {
mBleController = new BleController();
}
return mBleController;
}
public BleController initble(Context context,String uuidService,String uuidNotify,String uuidWrite) {
UUID_SERVICE=uuidService;
UUID_NOTIFY=uuidNotify;
UUID_WRITE=uuidWrite;
if (mContext == null) {
mContext = context.getApplicationContext();
mBlehManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
if (null == mBlehManager) {
Log.e(TAG, "BluetoothManager init error!");
}
mBleAdapter = mBlehManager.getAdapter();
if (null == mBleAdapter) {
Log.e(TAG, "BluetoothManager init error!");
}
mGattCallback = new BleGattCallback();
}
return this;
}
/**
* 扫描设备
*
* @param time 指定扫描时间
* @param scanCallback 扫描回调
*/
public void ScanBle(int time, final boolean enable, final ScanCallback scanCallback) {
if (!isEnable()) {
mBleAdapter.enable();
Log.e(TAG, "蓝牙没有开启");
}
if (null != mBleGatt) {
mBleGatt.close();
}
reset();
final BleDevceScanCallback bleDeviceScanCallback = new BleDevceScanCallback(scanCallback);
if (enable) {
if (mScanning) return;
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
//time后停止扫描
mBleAdapter.stopLeScan(bleDeviceScanCallback);
scanCallback.onSuccess();
}
}, time <= 0 ? SCAN_TIME : time);
mScanning = true;
mBleAdapter.startLeScan(bleDeviceScanCallback);
} else {
mScanning = false;
mBleAdapter.stopLeScan(bleDeviceScanCallback);
}
}
/**
* 扫描设备
* 默认扫描10s
*
* @param scanCallback
*/
public void ScanBle(final boolean enable, final ScanCallback scanCallback) {
ScanBle(SCAN_TIME, enable, scanCallback);
}
/**
* 连接设备
*
* @param connectionTimeOut 指定连接超时
* @param address 设备mac地址
* @param connectCallback 连接回调
*/
public void Connect(final int connectionTimeOut, final String address, ConnectCallback connectCallback) {
if (mBleAdapter == null || address == null) {
Log.e(TAG, "地址或adapter为空:" + address);
return ;
}
BluetoothDevice remoteDevice = mBleAdapter.getRemoteDevice(address);
if (remoteDevice == null) {
Log.w(TAG, "没有找到设备.");
return;
}
this.connectCallback = connectCallback;
mBleGatt = remoteDevice.connectGatt(mContext, false, mGattCallback);
Log.e(TAG, "连接到地址:" + address);
delayConnectResponse(connectionTimeOut);
}
/**
* 连接设备
*
* @param address 设备mac地址
* @param connectCallback 连接回调
*/
public void Connect(final String address, ConnectCallback connectCallback) {
Connect(CONNECTION_TIME_OUT, address, connectCallback);
}
/**
* 发送数据
*
* @param value 指令
* @param writeCallback 发送回调
*/
public void WriteBuffer(String value, OnWriteCallback writeCallback) {
this.writeCallback = writeCallback;
if (!isEnable()) {
writeCallback.onFailed(OnWriteCallback.FAILED_BLUETOOTH_DISABLE);
Log.e(TAG, "无法写入数据");
return;
}
if (mBleGattCharacteristic == null) {
mBleGattCharacteristic = getBluetoothGattCharacteristic(UUID_SERVICE, UUID_WRITE);
}
if (null == mBleGattCharacteristic) {
writeCallback.onFailed(OnWriteCallback.FAILED_INVALID_CHARACTER);
Log.e(TAG, "找不到服务或特征值");
return;
}
//设置数组进去
mBleGattCharacteristic.setValue(HexUtil.hexStringToBytes(value));
//发送
boolean b = mBleGatt.writeCharacteristic(mBleGattCharacteristic);
Log.i(TAG, "发送结果:" + b + "数据:" + value);
}
/**
* 设置读取数据的监听
*
* @param requestKey
* @param onReceiverCallback
*/
public void RegistReciveListener(String requestKey, OnReceiverCallback onReceiverCallback) {
mReceiverRequestQueue.set(requestKey, onReceiverCallback);
}
/**
* 移除读取数据的监听
*
* @param requestKey
*/
public void UnregistReciveListener(String requestKey) {
mReceiverRequestQueue.removeRequest(requestKey);
}
/**
* 手动断开Ble连接
*/
public void CloseBleConn() {
disConnection();
isMybreak = true;
mBleGattCharacteristic = null;
mBlehManager = null;
}
//------------------------------------分割线--------------------------------------
/**
* 当前蓝牙是否打开
*/
private boolean isEnable() {
if (null != mBleAdapter) {
return mBleAdapter.isEnabled();
}
return false;
}
/**
* 重置数据
*/
private void reset() {
isConnectok = false;
servicesMap.clear();
}
/**
* 超时断开
*
* @param connectionTimeOut
*/
private void delayConnectResponse(int connectionTimeOut) {
mHandler.removeCallbacksAndMessages(null);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (!isConnectok && !isMybreak) {
Log.e(TAG, "连接超时");
disConnection();
reConnect();
} else {
isMybreak = false;
}
}
}, connectionTimeOut <= 0 ? CONNECTION_TIME_OUT : connectionTimeOut);
}
/**
* 断开连接
*/
private void disConnection() {
if (null == mBleAdapter || null == mBleGatt) {
Log.e(TAG, "disconnection error maybe no init");
return;
}
mBleGatt.disconnect();
reset();
}
/**
* 蓝牙GATT连接及操作事件回调
*/
private class BleGattCallback extends BluetoothGattCallback {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.i(TAG,"状态变化:"+newState);
if (newState == BluetoothProfile.STATE_CONNECTED) { //连接成功
isMybreak = false;
isConnectok = true;
mBleGatt.discoverServices();
connSuccess();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) { //断开连接
if (!isMybreak) {
reConnect();
}
reset();
}
}
//发现新服务
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
Log.i(TAG,"发现新服务:"+status);
if (null != mBleGatt && status == BluetoothGatt.GATT_SUCCESS) {
List<BluetoothGattService> services = mBleGatt.getServices();
for (int i = 0; i < services.size(); i++) {
HashMap<String, BluetoothGattCharacteristic> charMap = new HashMap<>();
BluetoothGattService bluetoothGattService = services.get(i);
String serviceUuid = bluetoothGattService.getUuid().toString();
List<BluetoothGattCharacteristic> characteristics = bluetoothGattService.getCharacteristics();
for (int j = 0; j < characteristics.size(); j++) {
charMap.put(characteristics.get(j).getUuid().toString(), characteristics.get(j));
}
servicesMap.put(serviceUuid, charMap);
}
BluetoothGattCharacteristic NotificationCharacteristic=getBluetoothGattCharacteristic(UUID_SERVICE,UUID_NOTIFY);
if (NotificationCharacteristic==null)
return;
enableNotification(true,NotificationCharacteristic);
}
}
//读数据
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
Log.i(TAG,"---读数据---");
super.onCharacteristicRead(gatt, characteristic, status);
}
//写数据
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
Log.i(TAG,"---写数据---");
if (null != writeCallback) {
if (status == BluetoothGatt.GATT_SUCCESS) {
runOnMainThread(new Runnable() {
@Override
public void run() {
writeCallback.onSuccess();
}
});
Log.e(TAG, "发送 success!");
} else {
runOnMainThread(new Runnable() {
@Override
public void run() {
writeCallback.onFailed(OnWriteCallback.FAILED_OPERATION);
}
});
Log.e(TAG, "发送 failed!");
}
}
}
//通知数据
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
Log.i(TAG,"---数据通知变化---");
if (null != mReceiverRequestQueue) {
HashMap<String, OnReceiverCallback> map = mReceiverRequestQueue.getMap();
final byte[] rec = characteristic.getValue();
for (String key : mReceiverRequestQueue.getMap().keySet()) {
final OnReceiverCallback onReceiverCallback = map.get(key);
runOnMainThread(new Runnable() {
@Override
public void run() {
onReceiverCallback.onReceiver(rec);
}
});
}
}
}
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
Log.i(TAG,"---读描述---");
super.onDescriptorRead(gatt, descriptor, status);
}
}
/**
* 设置通知
*
* @param enable true为开启false为关闭
* @param characteristic 通知特征
* @return
*/
private boolean enableNotification(boolean enable, BluetoothGattCharacteristic characteristic) {
if (mBleGatt == null || characteristic == null)
return false;
if (!mBleGatt.setCharacteristicNotification(characteristic, enable))
return false;
BluetoothGattDescriptor clientConfig = characteristic.getDescriptor(UUID.fromString(BLUETOOTH_NOTIFY_D));
if (clientConfig == null)
return false;
if (enable) {
clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
} else {
clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
}
return mBleGatt.writeDescriptor(clientConfig);
}
public BluetoothGattService getService(UUID uuid) {
if (mBleAdapter == null || mBleGatt == null) {
Log.e(TAG, "BluetoothAdapter not initialized");
return null;
}
return mBleGatt.getService(uuid);
}
/**
* 根据服务UUID和特征UUID,获取一个特征{@link BluetoothGattCharacteristic}
*
* @param serviceUUID 服务UUID
* @param characterUUID 特征UUID
*/
private BluetoothGattCharacteristic getBluetoothGattCharacteristic(String serviceUUID, String characterUUID) {
if (!isEnable()) {
throw new IllegalArgumentException(" Bluetooth is no enable please call BluetoothAdapter.enable()");
}
if (null == mBleGatt) {
Log.e(TAG, "mBluetoothGatt is null");
return null;
}
//找服务
Map<String, BluetoothGattCharacteristic> bluetoothGattCharacteristicMap = servicesMap.get(serviceUUID);
if (null == bluetoothGattCharacteristicMap) {
Log.e(TAG, "没有找到 serviceUUID!");
return null;
}
//找特征
Set<Map.Entry<String, BluetoothGattCharacteristic>> entries = bluetoothGattCharacteristicMap.entrySet();
BluetoothGattCharacteristic gattCharacteristic = null;
for (Map.Entry<String, BluetoothGattCharacteristic> entry : entries) {
if (characterUUID.equals(entry.getKey())) {
gattCharacteristic = entry.getValue();
break;
}
}
return gattCharacteristic;
}
private void runOnMainThread(Runnable runnable) {
if (isMainThread()) {
runnable.run();
} else {
if (mHandler != null) {
mHandler.post(runnable);
}
}
}
private boolean isMainThread() {
return Looper.myLooper() == Looper.getMainLooper();
}
// TODO 此方法断开连接或连接失败时会被调用。可在此处理自动重连,内部代码可自行修改,如发送广播
private void reConnect() {
if (connectCallback != null) {
runOnMainThread(new Runnable() {
@Override
public void run() {
connectCallback.onConnFailed();
}
});
}
Log.e(TAG, "Ble disconnect or connect failed!");
}
// TODO 此方法Notify成功时会被调用。可在通知界面连接成功,内部代码可自行修改,如发送广播
private void connSuccess() {
if (connectCallback != null) {
runOnMainThread(new Runnable() {
@Override
public void run() {
connectCallback.onConnSuccess();
}
});
}
Log.e(TAG, "Ble connect success!");
}
}
血压实体类:XueyaActivity.java
package
com.totcms.blefamdoc.activity;
import
androidx.core.app.ActivityCompat;
import
androidx.core.content.ContextCompat;
import android.Manifest;
import
android.app.ProgressDialog;
import
android.bluetooth.BluetoothAdapter;
import
android.bluetooth.BluetoothDevice;
import
android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import
android.content.IntentFilter;
import
android.content.SharedPreferences;
import
android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.totcms.blefamdoc.R;
import
com.totcms.blefamdoc.bleutils.BleController;
import
com.totcms.blefamdoc.bleutils.callback.ConnectCallback;
import
com.totcms.blefamdoc.bleutils.callback.OnReceiverCallback;
import
com.totcms.blefamdoc.bleutils.callback.OnWriteCallback;
import
com.totcms.blefamdoc.utils.AppUtil;
import
com.totcms.blefamdoc.utils.ClsUtils;
import
com.totcms.blefamdoc.utils.Constant;
import
com.totcms.blefamdoc.utils.HexUtil;
import
com.totcms.blefamdoc.utils.HttpUtil;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Set;
public class XueyaActivity extends BaseActivity {
private final int STOP_SCAN = 1;
private boolean scanStatus = false;
private ProgressDialog progressDialog = null;
private static final int
REQUEST_CODE_ACCESS_COARSE_LOCATION = 1;
private static final int
REQUEST_DISCOVERABLE_BLUETOOTH = 3;
private BluetoothAdapter mBluetoothAdapter;
private BleController mBleController;//蓝牙工具类
private Context mContenxt;
TextView etData;
String dvAddr=null;
HttpUtil hu=null;
public final String UUID_SERVICE = "
0000fff0-0000-1000-8000-00805f9b34fb";
public final String UUID_NOTIFY = "
0000fff6-0000-1000-8000-00805f9b34fb";
public final String UUID_WRITE = "
0000fff6-0000-1000-8000-00805f9b34fb";
private final String TAG = "XueyaActivity", PWD = "0000", TEST_DEVICE_NAME = "FSRKB_BT-001";
private final String ACTION_PAIRING_REQUEST = "
android.bluetooth.device.action.PAIRING_REQUEST";//其它设备蓝牙配对请求
TextView connSts;
boolean isDevconn=false;
EditText etHighp;
EditText etLowP;
EditText etPulse;
EditText etCard;
private Handler handler= new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case Constant.HttpOk:
try {
JSONObject jo=new JSONObject((String)msg.obj);
if(jo==null){
AppUtil.showDialog(mContenxt,"提交失败了");
return;
}
if(jo.getInt("ret")==100){
AppUtil.showDialog(mContenxt,"成功提交");
}else {
AppUtil.showDialog(mContenxt,jo.getString("msg"));
}
} catch (JSONException e) {
AppUtil.showDialog(mContenxt,"提交失败了");
}
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_xueya);
mContenxt=this;
etCard=findViewById(R.id.etcard2);
etData=findViewById(R.id.tv_msg);
connSts=findViewById(R.id.connsts);
etHighp=findViewById(R.id.ethp);
etLowP=findViewById(R.id.etlp);
etPulse=findViewById(R.id.etpulse);
hu=new HttpUtil();
mBleController = BleController.getInstance().initble(this,UUID_SERVICE,UUID_NOTIFY,UUID_WRITE);
mBleController.RegistReciveListener(TAG, new OnReceiverCallback() {
@Override
public void onReceiver(byte[] value) {
Log.i(TAG,HexUtil.bytesToHexString(value));
String getv=HexUtil.bytesToHexString(value);
//下面部分是蓝牙设备的数据通讯协议,可以根据你的血压设备的协议来具体调整。
if(getv.startsWith("d0c2")){
String cmd=getv.substring(6,8);
if(cmd.equals("cc")){
int ph=Integer.parseInt(getv.substring(8,10), 16);
int pl=Integer.parseInt(getv.substring(10,12), 16);
int pulse=Integer.parseInt(getv.substring(12,14), 16);
etHighp.setText(String.valueOf(ph));
etLowP.setText(String.valueOf(pl));
etPulse.setText(String.valueOf(pulse));
//etData.setText("高压:"+ph+",低压:"+pl+",心率:"+pulse);
}
}
}
});
initSearchBroadcast();
initData();
getBluetoothMsg();
}
public void btnXySubmit(View view){
String postd="?userid="+baseUserId+"&token="+baseToken+"&cardid="+etCard.getText().toString()+"&lowp="+etLowP.getText().toString()+"&highp="+etHighp.getText().toString()+"&pulse="+etPulse.getText().toString();;
hu.getHtmlByThread(Constant.BloodpUrl+postd,handler,Constant.HttpOk);
}
public void btnClick(View view){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.CAMERA}, 1);
return;
}
}
Intent intent = new Intent(XueyaActivity.this, QRCodeScanActivity.class);
startActivityForResult(intent, 100);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null || data.getExtras() == null || TextUtils.isEmpty(data.getExtras().getString("result"))) {
return;
}
String result = data.getExtras().getString("result");
if (etCard != null) {
etCard.setText(result);
}
}
@Override
protected void onResume() {
super.onResume();
checkGps();
}
public void goBack(View view){
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
hideProgressDialog();
if (bluetoothReceiver != null) {
unregisterReceiver(bluetoothReceiver);
}
mBleController.UnregistReciveListener(TAG);
mBleController.CloseBleConn();
}
public void connDevice(String address){
if (scanStatus) {
mBluetoothAdapter.cancelDiscovery();
Log.i(TAG,"--------取消扫描(已找到设备)---------------");
scanStatus = false;
}
Log.i(TAG,"--------连接到设备:"+address+"---------------");
connSts.setText("正在连接设备...");
mBleController.Connect(address, new ConnectCallback() {
@Override
public void onConnSuccess() {
hideProgressDialog();
isDevconn=true;
connSts.setText("设备连接成功");
//Toast.makeText(XueyaActivity.this, "连接成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onConnFailed() {
isDevconn=false;
connSts.setText("设备连接失败");
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(!scanStatus) {
connSts.setText("重新连接到设备...");
scanBluetooth();
Log.i(TAG, "--------重新连接到设备:" + dvAddr + "---------------");
}
}
});
}
public void Write(String value){
mBleController.WriteBuffer(value, new OnWriteCallback() {
@Override
public void onSuccess() {
Toast.makeText(XueyaActivity.this, "ok", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailed(int state) {
Toast.makeText(XueyaActivity.this, "fail", Toast.LENGTH_SHORT).show();
}
});
}
public void btnSendStart(View view){
Write("BEB001C036");
}
public void btnSendStop(View view){
Write("BEB001C168");
}
private void scanBluetooth() {
Log.i(TAG, "--------设备扫描中---------------");
connSts.setText("设备扫描中....");
mBluetoothAdapter.startDiscovery();
scanStatus = true;
mHandler.sendEmptyMessageDelayed(STOP_SCAN, 1000 * 12);
}
private void initData() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//mBluetoothAdapter.setName("blueTestPhone"); //设置蓝牙名称
if (mBluetoothAdapter == null) {
Toast.makeText(this, "没有检测到蓝牙设备", Toast.LENGTH_LONG).show();
finish();
return;
}
boolean originalBluetooth = (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled());
if (originalBluetooth) {
scanBluetooth();
} else if (originalBluetooth == false) {
mBluetoothAdapter.enable();
}
}
private void getBluetoothMsg() {
try {
StringBuilder sb = new StringBuilder();
//获取本机蓝牙名称
String name = mBluetoothAdapter.getName();
//获取本机蓝牙地址
String address = mBluetoothAdapter.getAddress();
//获取已配对蓝牙设备
Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices();
sb.append("本机名称:" + name).append("\r\n");
sb.append("本机地址:" + address).append("\r\n");
//etData.setText(sb.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case STOP_SCAN:
if (scanStatus) {
mBluetoothAdapter.cancelDiscovery();
scanStatus = false;
hideProgressDialog();
}
break;
}
}
};
private void findDevice(Intent intent) throws Exception{
//获取到设备对象
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String dvname=device.getName()==null?"null":device.getName();
String str =dvname + "|" + device.getAddress();
Log.e(TAG,"扫描到设备:" + str);
if (device.getBondState() == BluetoothDevice.BOND_BONDED) {//判断当前设备地址下的device是否已经配对
Log.e(TAG,dvname+ "已配对");
} else {
if (dvname.equals(TEST_DEVICE_NAME)) {
boolean bondStatus = ClsUtils.createBond(device.getClass(), device);
Log.i(TAG , dvname+" 配对结果:" + bondStatus);
}
}
if (dvname.equals(TEST_DEVICE_NAME)) {
connSts.setText("找到设备:"+TEST_DEVICE_NAME);
dvAddr=device.getAddress();
connDevice(dvAddr);
}
//Log.e("error", "搜索完毕,准备刷新!");
}
private void initSearchBroadcast() {
IntentFilter intentFilter = new IntentFilter();
//发现设备
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
//设备配对状态改变
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//蓝牙设备状态改变
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
//开始扫描
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
//结束扫描
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
//其它设备请求配对
intentFilter.addAction(ACTION_PAIRING_REQUEST);
//intentFilter.addAction(
BluetoothAdapter.CONNECTION_STATE_CHANGED);
registerReceiver(bluetoothReceiver, intentFilter);
}
private BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.e(TAG, "mBluetoothReceiver action =" + action);
try {
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {//开始扫描
setProgressBarIndeterminateVisibility(true);
Log.e(TAG, "开始扫描");
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {//结束扫描
Log.e(TAG, "设备搜索完毕");
setProgressBarIndeterminateVisibility(false);
hideProgressDialog();
if(dvAddr==null || !isDevconn){
if(!scanStatus) {
Log.e(TAG, "--------没有连接到设备,再次连接-------");
Thread.sleep(300);
scanBluetooth();
}
}else{
scanStatus = false;
}
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {//发现设备
findDevice(intent);
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {//蓝牙配对状态的广播
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.e(TAG, device.getName() + "蓝牙配对广播:" + device.getBondState());
switch (device.getBondState()) {
case BluetoothDevice.BOND_BONDING:
Log.e(TAG, device.getName() + "蓝牙配对广播 正在配对......");
break;
case BluetoothDevice.BOND_BONDED:
Log.e(TAG, device.getName() + "蓝牙配对广播 完成配对,本机自动配对");
break;
case BluetoothDevice.BOND_NONE:
Log.e(TAG, device.getName() + "蓝牙配对广播 取消配对");
default:
break;
}
} else if (action.equals(ACTION_PAIRING_REQUEST)) {//其它设备蓝牙配对请求
BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); //当前的配对的状态
try {
String deviceName = btDevice.getName();
Log.e(TAG, "蓝牙 匹配信息:" + deviceName + "," + btDevice.getAddress() + ",state:" + state);
if(deviceName.equals(TEST_DEVICE_NAME)){//TEST_DEVICE_NAME 为被匹配蓝牙设备的名称,自己手动定义
Object object = ClsUtils.setPairingConfirmation(btDevice.getClass(), btDevice, true);
abortBroadcast();
boolean ret = ClsUtils.setPin(btDevice.getClass(), btDevice, PWD);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(mContenxt, "error:" + btDevice + "," + state, Toast.LENGTH_LONG).show();
}
} else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {//蓝牙开关状态
// BluetoothDevice device = intent.getParcelableExtra(
BluetoothDevice.EXTRA_DEVICE);
int statue = mBluetoothAdapter.getState();
switch (statue) {
case BluetoothAdapter.STATE_OFF:
Log.e(TAG,"蓝牙状态:,蓝牙关闭");
ClsUtils.closeDiscoverableTimeout(mBluetoothAdapter);
break;
case BluetoothAdapter.STATE_ON:
Log.e(TAG,"蓝牙状态:,蓝牙打开");
ClsUtils.setDiscoverableTimeout(1000 * 60, mBluetoothAdapter);
scanBluetooth();
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Log.e(TAG,"蓝牙状态:,蓝牙正在关闭");
mBluetoothAdapter.cancelDiscovery();
break;
case BluetoothAdapter.STATE_TURNING_ON:
Log.e(TAG,"蓝牙状态:,蓝牙正在打开");
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
public void showProgressDialog(String title, String message) {
if (progressDialog == null) {
progressDialog = ProgressDialog.show(this, title, message, true, false);
} else if (progressDialog.isShowing()) {
progressDialog.setTitle(title);
progressDialog.setMessage(message);
}
progressDialog.show();
}
public void hideProgressDialog() {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
progressDialog = null;
}
}
/**
* 开启位置权限
*/
private void checkGps() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_ACCESS_COARSE_LOCATION);
}
}
}
@Override
public void
onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super
.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode ==
REQUEST_CODE_ACCESS_COARSE_LOCATION) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//initData();
Toast.makeText(this, "位置权限已开启", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "未开启位置权限", Toast.LENGTH_SHORT).show();
}
} else {
super
.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
最后加了个拍照和扫码的功能,这样可以扫描客户的信息连同血压数据一起上传,这也就实现了健康档案系统中的数据采集的工作了。具体怎么扩展,大家可以自已想象了。