Android蓝牙4.0开发及发送指令到蓝牙硬件设备,简单好用,方法已写好直接可用

标签: Android 蓝牙4.0
18人阅读 评论(0) 收藏 举报
分类:

近日,接到需要用到蓝牙解锁硬件设备的新需求,开发过程中呢也遇到许多硬件的坑,开发协议文档较简单,几句话就完了,第一次搞得我自己一脸懵逼,本来一两个小时就能写完并测试完成的过程用了两三天。哎!默默地回到这里疯狂输出,记录下一些不必要的坑。下面开始我的蓝牙开发吧!走了以前的老路,就是拿到蓝牙需求就叫我先根据设计好的密钥配对连接,花了点时间,然后靠广播接收回调各种信息。setPin()方法也一直不成功。但是时间实在是有点紧了,耗不住了,果断放弃老方法了,开始尝试ble 4.0的方式方法。几步就ok了;

第一部,初始化蓝牙

BluetoothAdapter mBluetoothAdapter;
private void getBlueToothAdapter() {
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (mBluetoothAdapter == null) {
        MyToast.showShort(this, "设备不支持蓝牙,已为您切换到网络模式");
        operationType = 2;
        rightTxt.setText("蓝牙模式");
        return;
    }
    if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
        MyToast.showShort(this, "设备不支持蓝牙4.0");
        return;
    }
    openBlueTooth();
}

第二步,开启蓝牙

public static int BL_REQUESTCODE = 1;
private void openBlueTooth() {
    if (mBluetoothAdapter.isEnabled()) {
        MyToast.showShort(this, "蓝牙已打开");
        scanBlueTooth();
    } else {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);//这里是打开有提示是否开启蓝牙的方式
        startActivityForResult(enableBtIntent, BL_REQUESTCODE);
    }
}
//关闭蓝牙
private void closeBlueTooth() {
    mBluetoothAdapter.disable();
}

第三步,蓝牙扫描搜索

private void scanBlueTooth() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        //扫描需要一个回调。
        mBluetoothAdapter.startLeScan(scanCallBack);
    }
    //搜索后15秒关闭蓝牙扫描
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                mBluetoothAdapter.stopLeScan(scanCallBack);//停止扫描
            }
        }
    }, 15000);
}
//蓝牙扫描搜索回调
public BluetoothAdapter.LeScanCallback scanCallBack = new BluetoothAdapter.LeScanCallback() {
    @Override
    public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
        if (device.getName().equals("蓝牙的名字")) {//这里是根据蓝牙的名字筛选出想要连接的蓝牙,根据mac地址亦可以
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                //停止搜索蓝牙并连接蓝牙
                mBluetoothAdapter.stopLeScan(scanCallBack);
                connectBlueTooth(device);//连接设备
            }
        }
    }
};

第四步,连接蓝牙设备

BluetoothGattCharacteristic writeBluetoothCharacteristic;
BluetoothGatt writeBluetoothGatt;

private void connectBlueTooth(BluetoothDevice device) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        //参数1:上下文。//参数2:是否自动连接(当设备可以用时)//参数3:连接回调。
        mBluetoothAdapter.stopLeScan(scanCallBack);
        device.connectGatt(this, true, mGattCallback);
    }
}
 //蓝牙连接回调
    private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                //连接成功
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                    //开始发现设备的服务
                    gatt.discoverServices();
                }
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                //连接断开
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            boolean success = false;
            //当服务发现之后回调这里
            if (status == BluetoothGatt.GATT_SUCCESS) {
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
                    //根据服务UUID连接服务
                    BluetoothGattService service = gatt.getService(UUID.fromString("00001000-0000-1000-8000-00805f9b34fb"));
                    //根据特征UUID注册特征
                    BluetoothGattCharacteristic characteristic_write = findNotifyCharacteristic(service, UUID.fromString("00001001-0000-1000-8000-00805f9b34fb"));
                    BluetoothGattCharacteristic characteristic_notifi = findNotifyCharacteristic(service, UUID.fromString("00001002-0000-1000-8000-00805f9b34fb"));
                    if (characteristic_notifi != null) {
                        success = gatt.setCharacteristicNotification(characteristic_notifi, true);
                        if (success) {
                            characteristic_write.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
                            for (BluetoothGattDescriptor dp : characteristic_write.getDescriptors()) {
                                if (dp != null) {
                                    if ((characteristic_write.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
                                        dp.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                                    } else if ((characteristic_write.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) {
                                        dp.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
                                    }
                                    gatt.writeDescriptor(dp);//这里触发发送指令的回调
                                }
                            }
                        }
                    }
                }
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            //调用读取READ通道后返回的数据回调
            if (status == BluetoothGatt.GATT_SUCCESS) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
//                    Log.e("读取蓝牙数据", "" + BlueToothUtils.bytesToHexFun2(BlueToothUtils.JM3(characteristic.getValue())));
                }
            }
        }
    
        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);            
            if (status == BluetoothGatt.GATT_SUCCESS) {//写入成功
               
            } else if (status == BluetoothGatt.GATT_FAILURE) {//写入失败
              
            } else if (status == BluetoothGatt.GATT_WRITE_NOT_PERMITTED) {//没权限
                
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            //蓝牙推送过来的数据
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
//                Log.e("蓝牙推送过来的数据", "" + BlueToothUtils.bytesToHexFun2(BlueToothUtils.JM3(characteristic.getValue())));
            }
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(gatt, descriptor, status);
            writeBluetoothGatt = gatt;
            BluetoothGattService writeService = null;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
                writeService = gatt.getService(UUID.fromString("00001000-0000-1000-8000-00805f9b34fb"));
                if (writeService == null) {
                    return;
                }
                writeBluetoothCharacteristic = writeService.getCharacteristic(UUID.fromString("00001001-0000-1000-8000-00805f9b34fb"));
                if (writeBluetoothCharacteristic == null) {
                    return;
                }
                bluetooth_sendMessage(pwd, false);
            }
        }
    };
private BluetoothGattCharacteristic findNotifyCharacteristic(BluetoothGattService service, UUID characteristicUUID) {//此方法是在没有收到蓝牙的通知回调加的,最后才确定了是硬件那边本来就没给我回调信息,当然加入此方法也不会有问题
    BluetoothGattCharacteristic characteristic = null;
    List<BluetoothGattCharacteristic> characteristics = null;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
        characteristics = service.getCharacteristics();
        for (BluetoothGattCharacteristic c : characteristics) {
            if ((c.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0
                    && characteristicUUID.equals(c.getUuid())) {
                characteristic = c;
                break;
            }
        }
        if (characteristic != null)
            return characteristic;
        for (BluetoothGattCharacteristic c : characteristics) {
            if ((c.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0
                    && characteristicUUID.equals(c.getUuid())) {
                characteristic = c;
                break;
            }
        }
    }
    return characteristic;
}

//蓝牙发送指令
private void bluetooth_sendMessage(byte[] message, boolean flag) {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
        if (writeBluetoothCharacteristic == null) {
            return;
        }
        if (flag) {
            message = BlueToothUtils.Agreement_Encryption(message, message.length);
        }
        writeBluetoothCharacteristic.setValue(message);
        //上面的buffer数组中装的就是指令,多长? 每一位上面的数字代表什么意思在协议中查看!
        writeBluetoothGatt.writeCharacteristic(writeBluetoothCharacteristic);//向设备写入指令。
    }
}

最后加上权限。这里需要自己去动态申请6.0的定位权限

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>




查看评论

Android Ble 4.0 蓝牙开发交互

产品需求:1、app通过蓝牙连接到板子设备                    2、以发报文的形式与板子设备通讯                    3、当设备接受到正确的报文指令后,会将检测...
  • Lucy__
  • Lucy__
  • 2017-03-20 12:07:40
  • 5185

基于 Android蓝牙4.0开发详细讲解,与硬件通信 史上最牛逼,最详细

1.如果你准备搞蓝牙开发了,那么Android的基本常识你也应该很熟悉,比如说:Service 。你还需要一个支持蓝牙4.0的手机,不然神马都白瞎! 首先,几乎所有的蓝牙开发都是基于服务的,那么你需要...
  • chmod_R_755
  • chmod_R_755
  • 2015-09-13 01:44:11
  • 3638

向蓝牙设备发送命令

参考链接:http://blog.csdn.net/csu_yang/article/details/5912659 http://blog.csdn.net/lailzhihou/articl...
  • liuxd3000
  • liuxd3000
  • 2014-04-02 18:42:03
  • 5324

Android BLE蓝牙4.0开发详解

蓝牙我们应该很早就听过,最常见的就是原来我们偶尔通过手机上的蓝牙来传输文件。貌似在蓝牙4.0系列出现之前,蓝牙我们使用的并不多,蓝牙的产品貌似也不是很多。2010年6月30号蓝牙技术联盟推出了蓝牙4....
  • chenliqiang12345678
  • chenliqiang12345678
  • 2016-01-12 15:16:58
  • 36195

Android蓝牙4.0Ble开发

现在随着智能化潮流的到来,智能设备越来越多,而其中很多都使用的ble技术进行通讯,很多android开发人员会接触到ble开发。我是去年开始接触ble开发的,那时候百度基本没什么资料,苦逼的我只能上谷...
  • a287574014
  • a287574014
  • 2017-05-25 12:14:31
  • 1581

android Bluetooth常用AT 命令

一、 一般命令  1、 AT+CGMI 给出模块厂商的标识。  2、 AT+CGMM 获得模块标识。这个命令用来得到支持的频带(GSM 900,DCS 1800 或PCS 1900)。当模块有多频带时...
  • sunshine_mj
  • sunshine_mj
  • 2016-04-25 16:55:47
  • 2026

Android 蓝牙4.0 BLE 开发之请求同步实现篇 完全解析

开发过Android 蓝牙4.0 BLE的同学都知道,Android的蓝牙开发有非常多的坑,具体坑的集合可见我的前面一篇博客,《Android蓝牙4.0 BLE开发坑总结》,其中不同机型之间的兼容性就...
  • qingtiantianqing
  • qingtiantianqing
  • 2016-09-10 15:56:25
  • 3787

Android 蓝牙4.0BLE开发实现对蓝牙的写入数据和读取数据

Android 蓝牙4.0BLE开发实现对蓝牙的写入数据和读取数据 代码基本上都是官方的demo,只是通过修改获得自己想要的结果,下面就简单介绍一下自己的理解。 一、扫描BLE设...
  • cwcwj3069
  • cwcwj3069
  • 2016-04-14 17:31:59
  • 24561

BLE4.0蓝牙开发的必经之路

最近,翔飞人退役了。始终振翅的飞人最后还是落了地。伤病无情,英雄迟暮。祝福他换片天空再次起航ing。前一阵子,被老板叫去搞项目。说是要用到蓝牙,一琢磨,网上不多的是,下了一个蓝牙聊天的demo,翻来覆...
  • luochoudan
  • luochoudan
  • 2015-04-08 17:49:29
  • 9073

PHP连接设备,实现通讯和发送命令

开发的BS架构的软件(PHP),需要跟设备进行通讯和
  • u012217667
  • u012217667
  • 2014-08-11 15:20:21
  • 1120
    个人资料
    等级:
    访问量: 2812
    积分: 89
    排名: 142万+
    文章分类
    文章存档