常见的UUIDS列表:https://blog.csdn.net/qq_15003505/article/details/75315049


一、蓝牙作为外围设备,让别人扫。

        https://www.jianshu.com/p/ac24239c1daf

        https://www.jianshu.com/p/ffce0bbba84d

        https://blog.csdn.net/a287574014/article/details/80843584

        https://blog.csdn.net/weixin_38032755/article/details/78357035

        

       1)开启广播

            注意网上很多博客,在广播的时候添加了uuid,这是个严重的错误的做法。因为广播的数据本来就很有限,最大31字节(看源码就知道)。

            广播一般设置一下广播的蓝牙的名字,厂商的数据。

        private AdvertiseData buildAdvertiseData(){
        AdvertiseData.Builder dataBuilder=new AdvertiseData.Builder();
        dataBuilder.setIncludeDeviceName(true);
        //广播是否包含发射功率等级
        dataBuilder.setIncludeTxPowerLevel(true);
        //CZFix
//        dataBuilder.setIncludeTxPowerLevel(true);
        //下面是错误的代码,不能在这里添加ServiceUuid
//        dataBuilder.addServiceUuid(ParcelUuid.fromString(BleConnector.UUID_MAIN_SERVER.toString()));
//        dataBuilder.addServiceUuid(ParcelUuid.fromString(BleConnector.UUID_JULI_SERVER.toString()));

        mac = IPTool.getBluetoothMacAddress().replace(":","");
        AndroidConsoleLogPrinter.e(TAG, "mac: " + mac);

        dataBuilder.addManufacturerData(0x56,CodeTool.HexToByteArr(mac));
        return dataBuilder.build();
    }

           
        2)广播成功开启后,添加服务。

    private class SampleAdvertiseCallback extends AdvertiseCallback{
    @Override
    public void onStartFailure(int errorCode){
        super.onStartFailure(errorCode);
        LogUtil.e(TAG,"广播失败 code = " + errorCode);
        sendFailureIntent(errorCode);
        stopSelf();
    }

    @Override
    public void onStartSuccess(AdvertiseSettings settingsInEffect){
        super.onStartSuccess(settingsInEffect);
        LogUtil.e(TAG,"服务端的广播成功开启");
        LogUtil.e(TAG,"BLE服务的广播启动成功后:TxPowerLv="+settingsInEffect.getTxPowerLevel()+";mode="+settingsInEffect.getMode()+";timeout="+settingsInEffect.getTimeout());
        addServices(getContext());//该方法是添加一个服务,在此处调用即将服务广播出去
    }
}

        关于添加服务的操作我就不贴代码了,网上一大堆。我就说说需要注意的地方:

        1)服务添加成功的标志


    1. mBluetoothGattServer=mBluetoothManager.openGattServer(context,bluetoothGattServerCallback);

      打开服务端的gatt有个回调

       @Override
public void onServiceAdded(int status,BluetoothGattService service){
    super.onServiceAdded(status,service);
    AndroidConsoleLogPrinter.e(TAG,"添加服务成功,安卓系统回调该onServiceAdded()方法,uuid = " + service.getUuid() + ",status = " + status);
    //注意要等fee7的服务添加成功之后才能添加下一个服务
    if(service.getUuid().toString().equalsIgnoreCase(BleConnector.UUID_MAIN_SERVER.toString())){
        add180AService();
    }
}

             光

addResult = mBluetoothGattServer.addService(service);

            执行成功是不够的的,一定要以onServiceAdded成功回调为准。

        2)添加多个服务

    mBluetoothGattServer.addService(service);

            注意一点: addService方法不能并列执行,一定要等一个服务的onServiceAdded方法成功回调之后再添加下一个服务,注意根据uuid来判断哪个服务添加成功,不要搞成死循环。

             

            蓝牙的分包发送也应该注意类似的特点:write的时候,一定要以onCharacteristicWrite为标准来判断底层写成功,不能一个劲的给蓝牙发数据,很可能就出现问题。

            

            

二、蓝牙作为客户端,扫描其他设备。         

        1.读取特征值

           读取特征值不是直接通过特征值对象.getValue,通过源码会发现这样返回的肯定是null。

           应该通过

     bluetoothGatt.readCharacteristic(bluetoothGattCharacteristic)

           注意一点:readCharacteristic方法,不能直接在for里循环调用,有的手机可能不会所有特征值的read之后onCharacteristicRead就有回调。一定要要一个特征值,一个特征值的去读,等一个特征值的onCharacteristicRead回调之后再读下一个特征值。

            

            

            然后onCharacteristicRead方法会回调,此时再调用getValue()方法才能返回值。

     private final BluetoothGattCallback blueGattCB = new BluetoothGattCallback() {
    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic
            characteristic, int status) {   
    ...

         

   

https://blog.csdn.net/roshen_android/article/details/76916111 (对BLE系统的介绍,没有之一。)


微信蓝牙BLE接入调试指引 硬件篇

https://blog.csdn.net/skdev/article/details/50974343




相关资源

 谷歌官方文档,但是遗憾的是没有写操作。这个我可是研究了好几天,哎。。。

 https://developer.android.com/guide/topics/connectivity/bluetooth-le.html#setup

 谷歌官方的demo:https://github.com/googlesamples/android-BluetoothLeGatt

 

 http://blog.csdn.net/chenliqiang12345678/article/details/50504406 (******)



 坑总结:http://blog.csdn.net/qingtiantianqing/article/details/52459629?locationNum=13

 

 适配6.0手机:http://blog.csdn.net/u010134293/article/details/52808832

 

 http://blog.csdn.net/kjunchen/article/details/50339549

 http://blog.csdn.net/qq_23383563/article/details/52470368?locationNum=11&fps=1


 http://www.360doc.com/content/17/0420/17/21535613_647149510.shtml


 Android 蓝牙BLE 4.0 属性

  http://blog.csdn.net/chenxh515/article/details/45723299

 http://blog.csdn.net/luochoudan/article/details/44944213

 http://blog.csdn.net/jinhui157/article/details/58590019



关于适配的一些问题

1)对于“BluetoothDevice.java”这个类的方法,

 public BluetoothGatt connectGatt(Context context, boolean autoConnect,
                                     BluetoothGattCallback callback) {
         return (connectGatt(context, autoConnect,callback, TRANSPORT_AUTO));
 }

   对于 autoConnect这个参数,如果为true,某些手机在连接完蓝牙之后会自动断开连接,如联想K50T3S。

2) BluetoothGatt getService() 为空(null) onServicesDiscovered 没有调用

    https://blog.csdn.net/qq_30596077/article/details/88708661



 




关于Wifi的一些坑:

1)mWifiManager.setWifiEnabled(true);

     虽然是一个同步的方法,但是真正wifi开启并具备探索外部wifi列表的条件,还需要一定的时间。所以mWifiManager.getScanResults()这个方法需要延时执行。

2)mWifiManager.getScanResults()搜索不到wifi

     刚开始以为是6.0系统权限的问题,后来发现系统已经给了我所有的权限。用系统自带的wifi查看列表,发现有时候系统也搜索不到wifi,需要关闭再开启一下wifi。