您的位置:首页 > 移动开发 > Android开发

android 蓝牙ble设备开发

2016-04-14 10:05 891 查看
由于最近项目需要使用了bluetooth ble开发,所以把蓝牙连接ble设备摸索了一遍,希望能帮到各位开发者,有个提示也好。
先说说整体思路
一 打开蓝牙
BluetoothManager bluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
if (bluetoothManager == null || bluetoothManager.getAdapter() == null) {
                    ToastUtil.showToast(mContext, "对不起 ,您的机器不具备蓝牙功能");
 }
 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
//必须是4.3系统以上才支持蓝牙ble设备
                        Toast.makeText(mContext, “不支持ble设备”, Toast.LENGTH_SHORT).show();
 }
bluetoothAdapter = bluetoothManager.getAdapter();
                        if (!bluetoothAdapter.isEnabled()) {
                            // 蓝牙没有打开
                            if (bluetoothAdapter.enable()) {
                                // 蓝牙打开成功
                            } else {
                                Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                                ((Activity) mContext).startActivityForResult(enableIntent, BlueToothUtils.BLUE_OPEN_REQUESTCODE);
                            }
                        } else {
                            // 已经打开蓝牙
                        }

 二 搜索蓝牙设备
//打开蓝牙之后就需要搜索设备了
@SuppressWarnings("deprecation")
    public void scanLeDevice(final boolean enable) {
        if (bluetoothAdapter != null) {
            if (enable) {
//控制搜索蓝牙时间
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (mScanning) {
                            mScanning = false;
                            bluetoothAdapter.stopLeScan(mLeScanCallback);
                            // 发送设备搜索完成
                            mHandler.sendEmptyMessage(BLUETOOTH_SEARCHE_END);
                        }
                    }
                }, 5*1000);
                mScanning = true;
                bluetoothAdapter.startLeScan(mLeScanCallback);
                LogUtils.d("开始搜索设备");
            } else {
                LogUtils.d("关闭搜索设备");
                mScanning = false;
                bluetoothAdapter.stopLeScan(mLeScanCallback);
            }
        }
    }

 三 连接蓝牙服务并且监听蓝牙服务

//连接服务
public void startConnectThread(BluetoothDevice device) {
        cnntThread = new ConnectThread(device, true);
        cnntThread.start();
    }

class ConnectThread extends Thread {

        public ConnectThread(BluetoothDevice device, boolean secure) {
            try {
                if (device != null) {
                    mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback);
                }
            } catch (Exception e) {
                LogUtils.e("error: " + e);
            }
        }

        @Override
        public void run() {
            try {
                if (bluetoothAdapter != null && bluetoothAdapter.isDiscovering()) {
                    bluetoothAdapter.cancelDiscovery();
                }
                if (mBluetoothGatt != null) {
                    boolean isConnect = mBluetoothGatt.connect();
                    LogUtils.d("ConnectThread中run方法mBluetoothGatt的连接状态" + isConnect);
                }
            } catch (Exception e) {
                LogUtils.e(e);
                return;
            }
        }

        public void cancel() {
            if (mBluetoothGatt != null)
                mBluetoothGatt.close();
        }
    }

private final BluetoothGattCallback mGattCallback =
            new BluetoothGattCallback() {

                @Override
                public void onCharacteristicWrite(BluetoothGatt gatt,
                        BluetoothGattCharacteristic characteristic, int status) {
                    LogUtils.d("onCharacteristicWrite;status=" + status);
                }

                @Override
                public void onCharacteristicChanged(BluetoothGatt gatt,
                        BluetoothGattCharacteristic characteristic) {
                    // 获取蓝牙ble设备返回给你的信息
                   
                }

                @Override
                public void onConnectionStateChange(BluetoothGatt gatt, int status,
                        int newState) {
                    // 当连接状态发生改变的时候
                    LogUtils.d("onConnectionStateChange;status=" + newState);
                    if (BluetoothProfile.STATE_CONNECTED == newState) {
                        boolean discoverServicesFlag = mBluetoothGatt.discoverServices();
                        LogUtils.d("发现服务" + discoverServicesFlag);
                    } else if (BluetoothProfile.STATE_DISCONNECTED == newState) {
                        // 连接失败
                        closeBlueTooth();
                        mHandler.sendEmptyMessage(BLUETOOTH_ERROR);
                        LogUtils.d("onConnectionStateChange;连接服务失败" + newState);
                    }
                }

                @Override
                public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                    // 当发现服务的时候
                    LogUtils.d("onServicesDiscovered;status=" + status);
                    // 这里判断服务是否连接成功,然后设置监听是否成功,然后再判断与蓝牙设备是否连接成功
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        boolean openListenServiceFlag = openListenService();
                        if (openListenServiceFlag) {
                            mHandler.sendEmptyMessage(BLUETOOTH_CONNECTED_SUCCESS);
                        } else {
                            closeBlueTooth();
                            mHandler.sendEmptyMessage(BLUETOOTH_ERROR);
                            ToastUtil.showToast(mContext, "监听服务失败,请重试");
                        }
                    } else {
                        closeBlueTooth();
                        mHandler.sendEmptyMessage(BLUETOOTH_ERROR);
                        //ToastUtil.showToast(mContext, "发现服务失败,请重试");
                    }
                }

                @Override
                public void onCharacteristicRead(BluetoothGatt gatt,
                        BluetoothGattCharacteristic characteristic,
                        int status) {
                    LogUtils.d("onCharacteristicRead;status=" + status);
                }
            };

    /***
     * 打开监听服务
     *
     * @return
     */
    private boolean openListenService() {
        try {
            if (mBluetoothGatt != null) {
                String serviceUUID = "0000ffe0-0000-1000-8000-00805f9b34fb";
                String characterUUID = "0000ffe4-0000-1000-8000-00805f9b34fb";
                BluetoothGattService serv = mBluetoothGatt.getService(UUID.fromString(serviceUUID));
                if (serv != null) {
                    BluetoothGattCharacteristic charcter = serv.getCharacteristic(UUID.fromString(characterUUID));
                    // 指定当bluetoothGattCharacteristic发生改变的时候,发出通知
                    boolean isSucess = mBluetoothGatt.setCharacteristicNotification(charcter, true);
                    return isSucess;
                }
            }
        } catch (Exception e) {
            LogUtils.e(e);
        }
        return false;
    }

四 发送指令,获取ble设备返回的指令信息
// 监听server的UUID和character的UUID,这个是需要跟硬件设备开发人员商量的
    private String servUUID = "0000ffe5-0000-1000-8000-00805f9b34fb";
    private String CharacterUUID = "0000ffe9-0000-1000-8000-00805f9b34fb";

//获取指令byte[]
private void sendCommand(){
/**
*这里的byte[]比如
*byte[] bytes = new bytes[]
bytes[0] = (byte) getDecode("0xBB");
*/

byte[] value = BlueToothUtils.entryValue(userPhone);
                runCommandWithUUID(value);
}/***
     * 将字符串转化成16进制
     *
     * @param str
     * @return
     */
    public static int getDecode(String str) {
        return Integer.decode(str);
    }

/***
     * 发送指令
     *
     * @param servUUID
     * @param CharacterUUID
     * @param value
     */
    private boolean runCommandWithUUID(byte[] value) {
        if (mBluetoothGatt != null) {
            BluetoothGattService serv = mBluetoothGatt.getService(UUID.fromString(servUUID));
            BluetoothGattCharacteristic charcter = serv.getCharacteristic(UUID.fromString(CharacterUUID));
            boolean isSetSucess = charcter.setValue(value);
            boolean isWriteSucess = mBluetoothGatt.writeCharacteristic(charcter);
            if (!isWriteSucess) {
                isWriteSucess = mBluetoothGatt.writeCharacteristic(charcter);
            }
            // 发送指令完成
            LogUtils.d("发送指令完成isSetSucess=" + isSetSucess + ";isWriteSucess=" + isWriteSucess);
            if (isWriteSucess) {
                //这里应该反馈给mainActivity中
                mHandler.sendEmptyMessage(BLUETOOTH_SEND_VALUE_SUCCESS);
                return true;
            }
        }
        return false;
    }

 //蓝牙通知广播,仅作参考
IntentFilter bluetoothFilter = new IntentFilter();
bluetoothFilter.addAction(tBluetoothAdapter.ACTION_STATE_CHANGED);// 蓝牙状态改变的广播
bluetoothFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);// 蓝牙扫描模式广播
bluetoothFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);// 蓝牙搜索状态广播
bluetoothFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);// 蓝牙搜索中广播
bluetoothFilter.addAction(BluetoothDevice.ACTION_FOUND);// 蓝牙搜索广播
bluetoothFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);// 蓝牙绑定状态广播
getActivity().registerReceiver(mBluetoothStateReciver, bluetoothFilter);
//广播接受者
private BroadcastReceiver mBluetoothStateReciver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action == BluetoothAdapter.ACTION_STATE_CHANGED) {
int blueToothState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF);
showToastBlueToothState(blueToothState);
} else if (action == BluetoothAdapter.ACTION_DISCOVERY_FINISHED) {
// 表示搜索结束
MyProcessDialog.closeDialog();
}else if(action == BluetoothDevice.ACTION_FOUND){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
System.out.println("搜索到的蓝牙名称是:"+device.getName());
}
}
};

这里说明一下进制转换,因为android发送指令是16进制的byte[],所以字符串转成byte搞得特别头疼,只能怪自己数学没认真学啊。

首先说明几个函数

1 Integer.decode(String str)这个函数是将十进制/十六进制/八进制的字符串转成整型,如果要按照byte发送的话,还需要强转成byte,也就是Integer.decode(String str).byteValue().

2 Integer.toHexString(i)将int转成16进制的字符串

另外在说一说基础,以免忘记,byte表示1个字节,1个字节是8bit,也就是8个二进制数,

低八位和高八位,例如十进制的12345678,1234表示高4位,5678表示低4位,如果一个16进制数,1111000010101010中11110000表示高八位10101010表示低八位

前面如果有0x就表示16进制,&是一个按位与符号,Integer.toHexString(int i)&0xFF解释:"ff”是一个16进制数化成二进制数就是(11111111)
当一个32位二进制数与一个8位二进制数11111111按位与时,这个32位二进制数的高24位都会变成0,低8位会保持原来的数值(因为高24位中的每一位都是与0相与,
当然都是0了,而低8位都是与1相与,所以会保持原值)


计算校验和

private static String getCheckAndStr(byte[] bytes) {

        int value = 0;

        for (int i = 1; i < bytes.length; i++) {

            value += bytes[i];

        }

        //将int转成16进制字符串

        String valueStr = Integer.toHexString(value);

        int vl = valueStr.length();

        // 获取低八位 16进制

        String codeStr = valueStr.substring(vl - 2, vl);

        return codeStr;

    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: