您好,欢迎来到源码搜藏!分享精神,快乐你我!提示:担心找不到本站?在百度搜索“源码搜藏”,网址永远不丢失!
  • 首 页
  • 在线工具
  • jquery手册
  • android实现基于多级安全机制的蓝牙智能门锁源码

    时间:2017-10-12 08:50 来源:互联网 作者:源码搜藏 浏览:收藏 挑错 推荐 打印

    项目介绍
     
    基于多级安全机制的蓝牙智能门锁Android客户端实现。
     
    项目客户端基于 Android 平台,通过 CC2541 蓝牙芯片和底层进行通信,门锁部分以 HT32F1656 单片机为控制核心,基于蓝牙技术、生物传感技术,RFID 技术等,实现智能记忆门锁功能。 利用生物传感技术、RFID技术实现多种识别验证机制。通过 APP 选择系统工作模式,以适应不同的工作环境。同时通过备用复位系统,解决失效死机问题,通过备用电池电源供电系统,防止主电源断电的续航工作。
     
    关于 Android-BLE
     
    BLE:全称 Bluetooth Low Energy ,又叫做蓝牙4.0,主推就是低功耗,所以BLE技术更多的存在于只能穿戴设备和智能家居上,也正因如此,我们小组成员才会选择BLE的芯片和技术来进行开发。
     
    关键概念
     
    Generic Attribute Profile(GATT) –GATT 配置文件是一个通用的规范,用于在 BLE 链路上收发数据块。BLE应用开发也是基于 GATT。
    Attribute Protocol(ATT)—GATT 在ATT协议基础上建立,也被称为GATT/ATT。ATT 对在 BLE 设备上运行进行了优化,为此,它使用了尽可能少的字节。每个属性通过一个唯一的的统一标识符(UUID)来标识,每个 String 类型UUID使用128 bit标准格式。属性通过ATT被格式化为 characteristics和services。
    Characteristic 一个 characteristic 包括一个单一变量和0-n个用来描述 characteristic 变量的 descriptor,characteristic 可以被认为是一个类型,类似于类。
    Service service 是 characteristic 的集合。
    Service、Characteristic、Descriptor,这三部分都由UUID作为唯一标示符。一个蓝牙4.0的终端可以包含多个 Service,一个 Service 可以包含多个 Characteristic,一个 Characteristic 包含一个 Value 和多个 Descriptor,一个 Descriptor 包含一个 Value。一般来说,Characteristic 是手机与 BLE 终端交换数据的关键,Characteristic有较多的跟权限相关的字段,例如 PERMISSION 和 PROPERTY。Characteristic 的 PROPERTY 可以通过位运算符组合来设置读写属性,例如 READ|WRITE、READ|WRITE_NO_RESPONSE|NOTIFY,因此读取 PROPERTY 后要分解成所用的组合)。
     
    权限
     
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    声明APP只为具有BLE的设备提供
     
    1
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
     
     
    可以根据需要设置 required 的值为 false。
     
    BLE 具体设置
     
    当然,在进行设置之前要先检查设备是否支持 BLE,现在主流机型都是完美支持 BLE 的,在检查过后,可以直接启动蓝牙:
     
    获取 BluetoothAdapter 需要注意的是,在 Android 中,只有一个蓝牙适配器,APP要使用它和系统进行交互。在这里我们使用 getSystemSrvice() 返回 BluetoothManager。
     
    //蓝牙相关
    final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = bluetoothManager.getAdapter();
    Log.i(TAG, "mBluetoothAdapter = " + mBluetoothAdapter);
    开启蓝牙
     
    //打开蓝牙并获取蓝牙地址
    mBluetoothAdapter.enable();
    mActionbar.setSubtitle("蓝牙已打开");
    myBleAddress = mBluetoothAdapter.getAddress();
    搜索设备
     
    1
    mBluetoothAdapter.startLeScan(mLeScanCallback);
    处理搜索结果
     
    // 设备搜索结果
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
     
    @Override
    public void onLeScan(final BluetoothDevice device, int rssi,
    byte[] scanRecord) {
     
    runOnUiThread(new Runnable() {
    @Override
    public void run() {
    //5F:52:CC:7F:86:55
    //20:91:48:50:5C:8E
    //D4:F5:13:78:E9:63
    //20:91:48:50:58:DE 这里的为测试CC2541蓝牙mac地址
    if (device.getAddress().equals("20:91:48:50:58:DE")) {
    scanLeDevice(false);
    Log.e(TAG, device.getAddress());
    Log.e(TAG, device.getName());
    boolean bRet = mBLE.connect(device.getAddress());
    try {
    //这里与硬件交互的时候,有时候不稳定,故2s等待,保证链接稳定
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    if (bRet) {
    mActionbar.setSubtitle("已连接,请登录");
    Log.e(TAG, "connect+++++success");
    Log.e(TAG, Constant.HEAD_CHAR + "0B" + Constant.SEND_ADDRESS + Constant.SEVER_BLUETOOTH + myBleAddress + Constant.END_CHAR);
    }
     
    }
     
    }
    });
    // rssi
    Log.i(TAG, "rssi = " + rssi);
    Log.i(TAG, "mac = " + device.getAddress());
    Log.i(TAG, "scanRecord.length = " + scanRecord.length);
    }
     
    };
    进行实时通信
     
    通过 writeCharacteristic 方法进行数据的写入操作:
     
    public static void writeChar(byte[] bytes) {
    Log.i(TAG, "Message = " + bytes);
    if (gattCharacteristic_char != null) {
    gattCharacteristic_char.setValue(bytes);
    mBLE.writeCharacteristic(gattCharacteristic_char);
    }
    }
    通过 onCharacteristicWrite 方法来读取蓝牙方法所过来的数据:
     
    private BluetoothLeClass.OnDataAvailableListener mOnDataAvailable = new BluetoothLeClass.OnDataAvailableListener() {
    /**
    * BLE终端数据被读的事件
    */
    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    Log.e(TAG,
    "onCharRead " + gatt.getDevice().getName() + " read "
    + characteristic.getUuid().toString() + " -> "
    + Utils.bytesToHexString(characteristic.getValue()));
    }
     
    /**
    * 收到BLE终端写入数据回调
    */
    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
    // Log.e(TAG, "onCharWrite " + gatt.getDevice().getName() + " write "
    // + characteristic.getUuid().toString() + " -> "
    // + new String(characteristic.getValue()));
    String str = Utils.bytesToHexString(characteristic.getValue());
    Log.e(TAG, "+++++++++++++++++++++" + str);
    //这里处理蓝牙方发送过来的数据。。。。
     
    }
    };
     
    问题总结
     
    连接调试
     
    首先在客户端开发中,并不需要在程序中设置波特率,因为这并不是串口开发,而 BLE 在 Android 中高度集成,只需要满足上述的条件即可进行通信,而 BLE 设备开发是需要设置的,这个可以根据自己的需要进行设计,同时在客户端进行自己开发调试的时候,串口助手中一定要设置波特兰,当然,这个数值来自我们硬件开发的同学。
     
    数据传输
     
    开发中发现硬件对数据的解析是处于对 byte 流的解析,而最初客户端发送的数据位 String 类型的,这时候在串口调试中串口助手是可以显示客户端发送的数据,而 BLE 芯片却无法收到,解决方法是将 String 转化成 byte 流进行传输。
     
    //字符串转byte
    public static byte[] hexStringToBytes(String hexString) {
    if (hexString == null || hexString.equals("")) {
    return null;
    }
    hexString = hexString.toUpperCase();
    int length = hexString.length() / 2;
    char[] hexChars = hexString.toCharArray();
    byte[] d = new byte[length];
    for (int i = 0; i < length; i++) {
    int pos = i * 2;
    d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
    }
    return d;
    }
    协议商定
     
    在与硬件交互的开发中,我们不能像开发应用一样通过 JOSN 或者 XML 等类似的数据进行数据通信,要采用基于十六进制硬件底层的通信协议,协议截图(图片无法加载可以移步 这里 ):
     
    协议截图
     
    因此我们要对所传和所解析的数据进行十六进制的相互转换:
     
    // 转化字符串为十六进制编码
    public static String toHexString(String s) {
    String str = "";
    for (int i = 0; i < s.length(); i++) {
    int ch = (int) s.charAt(i);
    String s4 = Integer.toHexString(ch);
    str = str + s4;
    }
    return str;
    }
    // 转化十六进制编码为字符串
     
    android实现基于多级安全机制的蓝牙智能门锁源码转载请注明出处http://www.codesocang.com/gn-xiangmu/36662.html 源码搜藏网所有源码来自用户上传分享,版权问题及牵扯到商业纠纷均与源码搜藏网无关
    标签: