有关蓝牙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
原创粉丝点击