常见的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)服务添加成功的标志
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系统的介绍,没有之一。)
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。