转载请表明作者:http://blog.csdn.net/lansefeiyang08/article/details/46482073

昨天写了android L BLE Peripheral的简单使用,今天讲一下BLE Central的更新。

搞过android4.4的人肯定对BluetoothAdapter的startLeScan函数不会陌生,但是在android L已经弃用此接口,但是为了兼容以前的版本,这个接口还是可以使用的。但是谷歌已经单独拿出来android.bluetooth.le类來处理BLE的操作,所以我建议还是用最新的接口开发。如果想要兼容L之前的版本,可以用 android.os.Build.VERSION.SDK_INT或者 android.os.Build.VERSION.RELEA加一个版本判断就可以。下面就來正式认识一下BLE Scanner的更新。

在android L Central一共添加了6个scan的相关类(4个advertise相关类),这6个类把scan相关部分分得很细。按照上一篇Peripheral的思路,我们还是按照启动scan流程來学习这个类。

1、关于判断是否支持蓝牙、支持BLE的代码我就不写了,下面我只贴一下支持BLE centrial的代码:

  1. mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();

这句代码和Peripheral的getBluetoothLeAdvertiser基本类似,一般手机支持BLE都会支持Central,除非是本身就只是外设设备。这个不难,我就不浪费时间了。

2、这里就直接进入scan动作了,新的接口把scan分为了两类,一种为:

  1. /**
  2. * Start Bluetooth LE scan with default parameters and no filters. The scan results will be
  3. * delivered through {@code callback}.
  4. * <p>
  5. * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
  6. *
  7. * @param callback Callback used to deliver scan results.
  8. * @throws IllegalArgumentException If {@code callback} is null.
  9. */
  10. public void startScan(final ScanCallback callback) {
  11. if (callback == null) {
  12. throw new IllegalArgumentException("callback is null");
  13. }
  14. startScan(null, new ScanSettings.Builder().build(), callback);
  15. }

从函数你肯定就懂,这个是直接搜索全部周围peripheral设备,当然这里你要填写callback,具体的我下面会讲。

第二种为:

  1. /**
  2. * Start Bluetooth LE scan. The scan results will be delivered through {@code callback}.
  3. * <p>
  4. * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
  5. *
  6. * @param filters {@link ScanFilter}s for finding exact BLE devices.
  7. * @param settings Settings for the scan.
  8. * @param callback Callback used to deliver scan results.
  9. * @throws IllegalArgumentException If {@code settings} or {@code callback} is null.
  10. */
  11. public void startScan(List<ScanFilter> filters, ScanSettings settings,
  12. final ScanCallback callback) {
  13. startScan(filters, settings, callback, null);
  14. }

这一种明显属于定制化的函数了,因为他需要我们输入过滤条件。这里的ScanFilter和ScanSettings又是两个scan类,当然这两个类的目的主要是为了有些人想单独为某个产品开发应用,把过滤条件加上,比如DeviceName或者某个Service UUID等等,就可以搜索出只针对特定Peripheral特性的设备。

拿着两个条件我们怎么用呢,我给大家写一点,大家可以参考我写的自己添加:

  1. // add a filter to only scan for advertisers with the given service UUID
  2. List<ScanFilter> bleScanFilters = new ArrayList<>();
  3. bleScanFilters.add(
  4. new ScanFilter.Builder().setServiceUuid(SAMPLE_UUID).build()
  5. );
  6. ScanSettings bleScanSettings = mBleScanSettingsBuilder.build();
  7. Log.d(TAG, "Starting scanning with settings:" + bleScanSettings + " and filters:" + bleScanFilters);
  8. // tell the BLE controller to initiate scan
  9. mBluetoothLeScanner.startScan(bleScanFilters, bleScanSettings, mBleScanCallback);

单独看这两个新的接口,可能有些人会迷惑,本来不久应该是这样吗?其实Andoid L之前,scan接口不是这样的,它只有一下两种

  1. @Deprecated
  2. public boolean startLeScan(LeScanCallback callback)
  1. @Deprecated
  2. public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback)

你会发现,原来的scan只能通过service UUID去搜索,其他条件都不行,所以新版本的接口为我们定制应用提供了很大的便利。

3、搜索完了,那就要拿到scan的callback了。在这里,我就拿第一种格式来讲。
ScanCallBack有三个回调,当然callback也单独是一个类,这里我只讲讲对我们有用的 onScanResult(int callbackType, ScanResult result),为了大家理解,我直接给大家看看我搜索出来的结果:

  1. <span style="font-size:14px;">callbackType:1
  2. ScanResult{mDevice=B4:52:7E:9A:41:A8,mScanRecord=ScanRecord [mAdvertiseFlags=6,mServiceUuids=[00001804-0000-1000-8000-00805f9b34fb,
  3. 00001802-0000-1000-8000-00805f9b34fb,00001803-0000-1000-8000-00805f9b34fb,00000200-37cb-11e3-8682-0002a5d5c51b],
  4. mManufacturerSpecificData={}, mServiceData={},mTxPowerLevel=0, mDeviceName=××××],mRssi=-43, mTimestampNanos=352640634804615}</span>

从这个结果可以看出来,现在scan返回的结果明显增加了,其实从结果大家应该也能理解,第二种设置过滤的话会有哪些参数可以让你去设置。

你看到这些结果你肯定晕了,这要怎么拿出来,这就用到了Scan相关类的最后两个类ScanResult和ScanRecord。这两个类主要是用来解析你scan后数据的,我这里也贴一点代码,大家如果是需要其他结果,可以参考一下:

  1. BluetoothDevice device = result.getDevice();
  2. Log.d(TAG, "Device name: " + device.getName());
  3. Log.d(TAG, "Device address: " + device.getAddress());
  4. Log.d(TAG, "Device service UUIDs: " + device.getUuids());
  5. ScanRecord record = result.getScanRecord();
  6. Log.d(TAG, "Record advertise flags: 0x" + Integer.toHexString(record.getAdvertiseFlags()));
  7. Log.d(TAG, "Record Tx power level: " + record.getTxPowerLevel());
  8. Log.d(TAG, "Record device name: " + record.getDeviceName());
  9. Log.d(TAG, "Record service UUIDs: " + record.getServiceUuids());
  10. Log.d(TAG, "Record service data: " + record.getServiceData());

这里的result就是onScanResult(int callbackType, ScanResult result)的返回值。

4、最后一步就是stop,这个大家应该很熟了,用一个postdelay如下:

  1. // post a future task to stop scanning after (default:25s)
  2. mHandler.postDelayed(new Runnable() {
  3. @Override
  4. public void run() {
  5. stopScanning();
  6. }
  7. }, DEFAULT_SCAN_PERIOD);

或者直接调用stop,这里的stopScanning实现如下:

  1. private void stopScanning() {
  2. if (mBluetoothLeScanner != null) {
  3. Log.d(TAG, "Stop scanning.");
  4. mBluetoothLeScanner.stopScan(mBleScanCallback);
  5. }
  6. }

剩下的就是connectGatt了。这个和以前还是一样的,目前没有变化。

ok,对于google新添加的android.bluetooth.le这个package算是解析完了,接下来几天就要看看android L系统里是怎么实现的了。

android5.0(Lollipop) BLE Central牛刀小试的更多相关文章

  1. android5.0(Lollipop) BLE Peripheral牛刀小试

    转载请表明作者:http://blog.csdn.net/lansefeiyang08/article/details/46468743 知道Android L对蓝牙对了一些改进.包含加入A2dp s ...

  2. Android5.0(Lollipop) BLE蓝牙4.0+浅析code(二)

    作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23347612来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...

  3. Android5.0(Lollipop) BLE蓝牙4.0+浅析demo连接(三)

    作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23363591来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...

  4. Android5.0(Lollipop) BLE蓝牙4.0+浅析概念(四)

    作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23679793来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 置顶:此文转载CSDN博 ...

  5. android5.0(Lollipop) BLE Peripheral深入理解系统篇之提高篇

    上一篇文章讲到了广播之前系统需要进行的准备工作,那接下来我们就来真正的启动广播. 首先还是先看一下上一篇文章结束的地方: @Override public void onClientRegistere ...

  6. Android5.0(lollipop)新特性介绍(一)

    今年6月的Google I/O大会上.Android L的初次见面我相信让会让非常多android粉丝有些小激动和小期待.当然作为开发人员的我来说,激动不言而喻,毕竟这是自08年以来改变最大的一个版本 ...

  7. android5.0 BLE 蓝牙4.0+浅析demo搜索(一)

    作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23341414来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者:Bgwan 莳萝花 ...

  8. 解决Android5.0以下Dialog引起的内存泄漏

    最近项目开发中,开发人员和测试人员均反应在android5.0以下手机上LeakCanary频繁监控到内存泄漏,如下图所示,但凡用到Dialog或DialogFragment地方均出现了内存泄漏. 如 ...

  9. JobService和JobScheduler机制在Android5.0以上保活

    JobService和JobScheduler机制在Android5.0以上保活 我们知道在Android5.0之前,Android源代码还是有不小漏洞的,导致非常多不光明的手段来进行++保活++.但 ...

随机推荐

  1. java学习之线程池的实现

    package com.gh.threadpoor; import java.util.concurrent.ExecutorService; import java.util.concurrent. ...

  2. 解题报告 HDU1176 免费馅饼

    免费馅饼 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  3. Python基础 3----文件和网络

    1 Python文件IO 1 标转的输入和输出 print 方法:输出数据到标准的输出 raw_input 方法:标准的输入 2 file文件类 读文件 f = file(文件名, 模式) 有5种模式 ...

  4. 【OpenCV】OpenCV2.4.6 与Visiual Studio 2008,Python2.7.5配置和图像载入显示

    自从OpenCV2.2开始,OpenCV 库便分成几个模块并位于lib文件中,本节介绍从OpenCV2.4.6与VS2008 .Python2.7.5如何配置环境,如何外部文件载 入图像.在窗口中显示 ...

  5. BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )

    做一次MST, 枚举不在最小生成树上的每一条边(u,v), 然后加上这条边, 删掉(u,v)上的最大边(或严格次大边), 更新答案. 树链剖分然后ST维护最大值和严格次大值..倍增也是可以的... - ...

  6. Week12(11月25日)

    Part I:提问 =========================== 1.如何删除一条记录? Part II:理论学习 =========================== 到目前为止,我们考 ...

  7. Jekyll学习:基本使用方法

    Jekyll是一个简单的博客.静态网站生成工具.利用它可以快速的搭建一个网站.并且完全免费的在 GitHub 上发布网站 — 自定义域名. 一.环境搭建 apt-get install jekyll ...

  8. Observer设计模式【利用商品概念解释】

    每个人都想过着富有的生活,这是很正常的. 这里以开店进货为例. 在讲之前解释英语单词: Observer:查看:遵守 Observable:可见的,公开的. 从单词可以知道:商品用来卖,所以公开,继承 ...

  9. mysql 创建临时节点

    use ZooKeeper; use AnyEvent; use AE; use Data::Dumper; use IO::Socket; my $zk = ZooKeeper->new(ho ...

  10. From Ontology to Semantic Web

    Ontology(本体论)用于描述事物的本质(Gruber,1995).这个词在人工智能.计算机语言以及数据库理论中扮演者越来越重要的作用.在实现上,本体论是概念化的详细说明,一个ontology往往 ...