Android5.0(Lollipop) BLE蓝牙4.0+浅析code(二)
链接:https://zhuanlan.zhihu.com/p/23347612
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Android5.0(Lollipop) BLE蓝牙4.0+浅析code说明(二)
Android4.4 启用蓝牙相关的操作方法主要是,BluetoothAdapter.startleScan();方法,最新的Android 5.0已经弃用了改方法,谷歌官方已经改用了android.bluetooth.le类來处理BLE的操作,所以我建议还是用最新的接口开发。但是为了兼容以前的版本改方法还是可以使用,上篇日志已经提到我们可以加一个SDK版本的判断,这里不过多说明,
这次更新总共在le下面添加了6个scan的相关类(4个advertise相关类),下面开始介绍这个类的作用。
1.BLE centrial的代码
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
利用adapter来得到一个scanner对象,这句代码和Peripheral的getBluetoothLeAdvertiser基本类似,一般手机支持BLE都会支持Central,除非是本身就只是外设设备。
advertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
如果是Peripheral 得到advertiser对象,那么我们可以广播设置一些参数,数据,加一个CallBack,如下:
advertiser.startAdvertising(settings, data, mAdvertiseCallback);
这里面的三个参数,不再本文导论范围,但是可以看一下
// TODO Auto-generated method stub
AdvertiseSettings settings = new AdvertiseSettings.Builder()
.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
.setConnectable(false).build();
ParcelUuid pUuid = new ParcelUuid(UUID.fromString("00001000-0000-1000-8000-00805f9b34fb"));
AdvertiseData data = new AdvertiseData.Builder()
.setIncludeDeviceName(true)
.addServiceUuid(pUuid)
.addServiceData(pUuid,
"Data".getBytes(Charset.forName("UTF-8"))).build();
final AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
super.onStartSuccess(settingsInEffect);
if (settingsInEffect != null) {
Log.d(TAG, "onStartSuccess TxPowerLv=" + settingsInEffect.getTxPowerLevel() + " mode=" + settingsInEffect.getMode()
+ " timeout=" + settingsInEffect.getTimeout());
} else {
Log.e(TAG, "onStartSuccess, settingInEffect is null");
}
Log.e(TAG, "onStartSuccess settingsInEffect" + settingsInEffect);
}
@Override
public void onStartFailure(int errorCode) {
super.onStartFailure(errorCode);
if (errorCode == ADVERTISE_FAILED_DATA_TOO_LARGE) {
Toast.makeText(mContext, "Operation failed due to an internal error", Toast.LENGTH_LONG).show();
Log.e(TAG, "Failed to start advertising as the advertise data to be broadcasted is larger than 31 bytes.");
} else if (errorCode == ADVERTISE_FAILED_TOO_MANY_ADVERTISERS) {
Toast.makeText(mContext, "Operation failed due to an internal error", Toast.LENGTH_LONG).show();
Log.e(TAG, "Failed to start advertising because no advertising instance is available.");
} else if (errorCode == ADVERTISE_FAILED_ALREADY_STARTED) {
Toast.makeText(mContext, "Operation failed due to an internal error", Toast.LENGTH_LONG).show();
Log.e(TAG, "Failed to start advertising as the advertising is already started");
} else if (errorCode == ADVERTISE_FAILED_INTERNAL_ERROR) {
Toast.makeText(mContext, "Operation failed due to an internal error", Toast.LENGTH_LONG).show();
Log.e(TAG, "Operation failed due to an internal error");
} else if (errorCode == ADVERTISE_FAILED_FEATURE_UNSUPPORTED) {
Toast.makeText(mContext, "This feature is not supported on this platform", Toast.LENGTH_LONG).show();
Log.e(TAG, "This feature is not supported on this platform");
} else {
Toast.makeText(mContext, "onStartFailure errorCode", Toast.LENGTH_LONG).show();
Log.e(TAG, "onStartFailure errorCode" + errorCode);
}
}
};
它主要的作用就是,假如说你有一个嵌入式的外设,蓝牙设备名字CTH-1001,这个蓝牙设备你可以通过设置这些参数去过滤你想要的蓝牙设备,如果周围还有其他的蓝牙外设你的手机可能就搜索不到,这也是在Android 后来新加入的功能,为了方便开发者使用。
2,接下来就是Scan的动作了,Scan新的接口动作把Scan分为了两类,
第一类:直接给一个callback
public void startScan(java.util.List<android.bluetooth.le.ScanFilter> filters, android.bluetooth.le.ScanSettings settings, android.bluetooth.le.ScanCallback callback)
/**
* Start Bluetooth LE scan with default parameters and no filters. The scan results will be
* delivered through {@code callback}.
* <p>
* Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
*
* @param callback Callback used to deliver scan results.
* @throws IllegalArgumentException If {@code callback} is null.
*/
public void startScan(final ScanCallback callback) {
if (callback == null) {
throw new IllegalArgumentException("callback is null");
}
startScan(null, new ScanSettings.Builder().build(), callback);
}
直接搜索全部周围peripheral设备,当然这里你要填写callback,
第二类为这里加入了新的过滤条件。可以看到ScanFilter:
/**
* Start Bluetooth LE scan. The scan results will be delivered through {@code callback}.
* <p>
* Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
*
* @param filters {@link ScanFilter}s for finding exact BLE devices.
* @param settings Settings for the scan.
* @param callback Callback used to deliver scan results.
* @throws IllegalArgumentException If {@code settings} or {@code callback} is null.
*/
public void startScan(List<ScanFilter> filters, ScanSettings settings,
final ScanCallback callback) {
startScan(filters, settings, callback, null);
}
这一种明显属于定制化的函数了,因为他需要我们输入过滤条件。这里的ScanFilter和ScanSettings又是两个scan类,当然这两个类的目的主要是为了有些人想单独为某个产品开发应用,把过滤条件加上,比如DeviceName或者某个Service UUID等等,就可以搜索出只针对特定Peripheral特性的设备,就像我们公司的CTH-1001类型的设备。
单独看这两个新的接口,可能有些人会迷惑,本来不久应该是这样吗?其实Andoid L之前,scan接口不是这样的,就只有上面两种中的一种方法,suo'y。
3,OKay ,讲解了scanLeDevice,这里看一下回调mScanCallBack具体怎么实现的,其实在上篇文章已经贴出来了,
private ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
if (result == null || result.getDevice() == null
|| TextUtils.isEmpty(result.getDevice().getName())) {
mText.setText("没有搜索到蓝牙设备");
// return;
}
//如果是外设则可能存在没有ServiceUuids
// builder.append("/n").append(
// new String(result.getScanRecord().getServiceData(
// result.getScanRecord().getServiceUuids().get(0)),
// Charset.forName("UTF-8")));
BluetoothDevice device = result.getDevice();
Log.d(TAG, "Device name: " + device.getName());
Log.d(TAG, "Device address: " + device.getAddress());
Log.d(TAG, "Device service UUIDs: " + device.getUuids());
if (builder.toString().contains(device.getName())) {
} else {
builder.append("\n" + device.getName() + "&" + device.getAddress() + "\n");
}
ScanRecord record = result.getScanRecord();
Log.d(TAG, "Record advertise flags: 0x" + Integer.toHexString(record.getAdvertiseFlags()));
Log.d(TAG, "Record Tx power level: " + record.getTxPowerLevel());
Log.d(TAG, "Record device name: " + record.getDeviceName());
Log.d(TAG, "Record service UUIDs: " + record.getServiceUuids());
Log.d(TAG, "Record service data: " + record.getServiceData());
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
mText.setText("搜索结果,builder:" + builder.toString());
}
看到没有,这里包含result就是onScanResult(int callbackType, ScanResult result)的返回值,而且对于如何解析的代码我也贴出来了,是不是应该感动一下。
最后,所有的操作完了,不要忘记stop一下,我们可以在OnDestory方法中停止,当然加一个postdelay,这里操作我写了一个方法直接在需要的地方调用。
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
stopScanning();
}
}, DEFAULT_SCAN_PERIOD);
停止方法,
private void stopScanning() {
if (mBluetoothLeScanner != null) {
Log.d(TAG, "Stop scanning.");
mBluetoothLeScanner.stopScan(mBleScanCallback);
}
}
剩下的就是connectGatt了,下篇文章我会重点介绍,蓝牙之间如何连接,如果传递数据,可能会结合我们公司的项目来讲解,
对了,我猜大家肯定需要源码,等公司项目完了,就上传一个修改后的demo给大家,欢迎大家关注。
Android5.0(Lollipop) BLE蓝牙4.0+浅析code(二)的更多相关文章
- Android5.0(Lollipop) BLE蓝牙4.0+浅析demo连接(三)
作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23363591来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...
- Android5.0(Lollipop) BLE蓝牙4.0+浅析概念(四)
作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23679793来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 置顶:此文转载CSDN博 ...
- android5.0 BLE 蓝牙4.0+浅析demo搜索(一)
作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23341414来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者:Bgwan 莳萝花 ...
- Android ble 蓝牙4.0 总结
本文介绍Android ble 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用,如果手机系统版本API level < 18,也是用不了蓝牙4.0的哦 ...
- Android ble 蓝牙4.0 总结一
本文介绍Android ble 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用,如果手机系统版本API level < 18,也是用不了蓝牙4.0的哦 ...
- IOS BLE蓝牙4.0
前言: 自己做的项目里面有这么一个功能,总结归纳一下. 先导入必要的框架 CoreBluetooth.framework 在要用到蓝牙的文件里面导入以下头文件 #import <CoreBlu ...
- android5.0(Lollipop) BLE Peripheral牛刀小试
转载请表明作者:http://blog.csdn.net/lansefeiyang08/article/details/46468743 知道Android L对蓝牙对了一些改进.包含加入A2dp s ...
- android5.0(Lollipop) BLE Central牛刀小试
转载请表明作者:http://blog.csdn.net/lansefeiyang08/article/details/46482073 昨天写了android L BLE Peripheral的简单 ...
- android5.0(Lollipop) BLE Peripheral深入理解系统篇之提高篇
上一篇文章讲到了广播之前系统需要进行的准备工作,那接下来我们就来真正的启动广播. 首先还是先看一下上一篇文章结束的地方: @Override public void onClientRegistere ...
随机推荐
- 具有可视化的功能的一款开源软件Gource
今天为大家介绍一个非常有趣儿的开源软件,Gource可以将代码版本控制系统里面的日志全部可视化,也就是说可以看见每个成员在系统里面提交代码的行为,Gource目前支持git,hg,svn. 650) ...
- 【IOS学习】1.第一个IOS程序
1.执行原理 a.首先执行main函数 调用UIApplicationMain方法 return UIApplicationMain(argc, argv, nil, NSStringFromClas ...
- mac: brew的删除
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)" ...
- Linux运维命令总结
.什么是运维?什么是游戏运维? 1)运维是指大型组织已经建立好的网络软硬件的维护,就是要保证业务的上线与运作的正常, 在他运转的过程中,对他进行维护,他集合了网络.系统.数据库.开发.安全.监控于一身 ...
- NO.1 You must restart adb and Eclipse多种情形分析与解决方式
一:错误提示 The connection to adb is down, and a severe error has occured. You must restart adb and Eclip ...
- org.omg.CORBA.MARSHAL: vmcid: SUN minor code: 211 completed: Maybe
用weblogic 12c 测试 ejb3 import javax.naming.InitialContext; import javax.naming.NamingException; impor ...
- DG Cascade Standby
SUMMARY 1. logical standby不支持cascading standby 2. 11.2.0.2之前版本cascading standby不支持RAC 3. 11.2.0.3之前版 ...
- Vue简介以及基本使用
Vue 是一套构建用户界面的渐进式 框架 框架和库? 框架(基于自身的特点向用户提供一套完整的解决方案,控制权在框架本身,需要使用者按照框架所规定的某种规范进行开发) Vue Angular Reac ...
- 高中生活-第9篇-开学之初的“失足”囧事,"刻舟求剑"导致腿折了
时间过得好快啊,上次发表"高中生活-第8篇:夏天的空调,冬天的味道"是2014年9月30日,一转眼,就是一年啊. 我自己以为,很多人可能都以为,我又半途而废了,实则不是哦~ 行百里 ...
- 【Codeforces Round #429 (Div. 2) A】Generous Kefa
[Link]:http://codeforces.com/contest/841/problem/A [Description] [Solution] 模拟,贪心,每个朋友尽量地多给气球. [Numb ...