Android 的蓝牙简介

本文主要是翻译了 Google 的官方文档

简介

Android 提供默认的蓝牙协议栈是 BlueDroid,分为两层:蓝牙嵌入式系统(BTE)和蓝牙应用层(BTA),BTE 层主要实现蓝牙的核心功能,BTA 层则主要负责和 Anroid 框架通信。

Android 4.2 之前,Google 一直应用的是 Linux 官方蓝牙协议栈,即知名老牌开源
项目 BlueZ。BlueZ 实际上是由高通公司在 2001 年 5 月基于 GPL 协议 release 的一个开源项目,该项目仅 release 一个月后就被 Linux 之父 Linux Torvalds 纳入了 Linux 内核,并做为 Linux 2.4.6 内核的官方蓝牙协议栈。随着 Android 设备的流行,BlueZ 也得到了极大的完善和扩展。例如 Android 4.1 中 BlueZ 的版本升级为 4.93,它支持蓝牙核心规范4.0,并实现了绝大部分的 Profiles。但是从 Android 4.2 即 Jelly Bean 开始,Google 便在 Android 源码中推出了它和博通公司一起开发的 BlueDroid 以替代 BlueZ。虽然因为时间及成熟度的原因,大部分手机厂商在 Android 4.2 中仍继续应用 BlueZ。但是 BlueZ 的创始者,高通公司也将在基于其芯片的 Android 参考设计中去除 BlueZ,并仅支持 BlueDroid。BlueZ 的未来如何笔者姑且不论。不过,能让高通改弦易辙,BlueDroid 自有其合理之处。相比 BlueZ,BlueDroid 最值得称道的地方就是其框架结构变得更为简洁和清晰。另外,借助 HAL(Hardware Abstraction Layer,硬件抽象层),BlueDroid 终于不再和 dbus 有任何瓜葛。(引用)

架构

蓝牙系统服务通过 JNI 来与蓝牙协议栈交互,通过 Binder IPC 来与应用层交互。系统服务给开发者提供各种蓝牙Profile的访问。Android 中的蓝牙总体架构如下图所示:

ape_fwk_bluetooth.png
  • 应用框架层 Application framework在应用框架层是具体的蓝牙相关应用的代码,这里使用 andorid.bluetooth 相关的 API 来和蓝牙硬件交互。其内部的实现,是通过 Binder IPC 机制来调用 Bluetooth 进程的;
  • 蓝牙系统服务 Bluetooth system service蓝牙系统服务位于 packages/apps/Bluetooth,被作为一个 Android 的系统 App。它在 Android 框架层实现了蓝牙的 ServiceProfile,并通过 JNI 调用到 HAL 层。编译的到系统中就是 /system/app/Bluetooth.apk
  • JNIandorid.bluetooth 对应的 JNI 代码位于 packages/apps/Bluetooth/jniJNI 层代码调用到 HAL 层,并当发生某些蓝牙动作(例如发现了设备)的时候,接受来自 HAL 层的回调。
  • 硬件抽闲层 HAL硬件抽闲层(Hardware Abstraction Layer)定义了 andorid.bluetooth API 和蓝牙进程需要用到的标准接口,你必须实现这些接口来确保你的蓝牙硬件正常工作。蓝牙 HAL 相关的头文件位于 hardware/libhardware/include/hardware/bluetooth.hhardware/libhardware/include/hardware/bt_*.h
  • 蓝牙协议栈 Bluetooth Stack Android 提供的默认蓝牙协议栈位于 external/bluetooth/bluedroid。这个协议栈实现了通用的蓝牙 HAL 接口,并且可以通过扩展(Extentions)和配置(Configuration)来自定义。编译到系统中就是 /system/lib/hw/bluetooth.default.so
  • 供应商扩展 Vendor extentions供应商也可以通过创建 libbt-vendor 并指定这些模块,来添加自己定义扩展和 HCI 层跟踪。

各层之间的交互实例可以参考这篇转载文章,很抱歉原文链接也没有找到。

HAL 的实现

蓝牙的 HAL 相关文件在 hardware/libhardware/include/hardware/,包括但不局限于以下的文件:

  • bluetooth.h:这里包含蓝牙硬件的接口定义;
  • bt_gatt.h, bt_gatt_client.h, 和 bt_gatt_server.h:这里包含 GATT profile 相关的接口定义;
  • bt_hf.h:HFP profile 相关接口的定义;
  • bt_hh.h:HID host profile 相关接口的定义;
  • bt_hl.h:HDP profile 相关接口的定义;
  • bt_mce.h:MAP profile 相关接口的定义;
  • bt_pan.h:PAN profile 相关接口的定义;
  • bt_rc.h:AVRCP profile 相关接口的定义;
  • bt_sock.h:RFCOMM profile 相关接口的定义;

值得注意的是,Android 中蓝牙并不局限于 HAL 中暴露的这些特性和 Profile。BlueDroid 是是蓝牙协议栈的默认是实现,它实现了默认的 HAL 以及额外的自定义特性。BlueDroid 的代码在 external/bluetooth/bluedroid 目录。

自定义蓝牙协议栈

如果使用了默认的 BlueDroid 协议栈,但是想加入一些自定义功能,可以这样做:

  • 自定义蓝牙 Profile -- 如果你想要添加一个在 Android 的 HAL 中未定义的蓝牙 Profile,你必须提供一个额外的 SDK 供开发者下载,并且确保 API 在蓝牙系统进程的应用中可用(packages/apps/Bluetooth),并添加 Profile 的实现到 BlueDroid 中(external/bluetooth/bluedroid);
  • 自定义供应商扩展和配置修改 -- 你可以通过创建 libbt-vendor 模块来添加例如额外的 AT 命令或者设备特定的配置。可以参考 vendor/broadcom/libbt-vendor 目录的例子;
  • Host Controller Interface (HCI) -- 你可以通过添加 libbt-hci 模块来提供你自己的 HCI 接口(主要用来做调试跟踪)。参考 external/bluetooth/hci 目录的例子。

Read more

Android 上的低功耗蓝牙实践

这是我在 Droidcon Beijing 2016 和 GDG Devfest 2016 上做的分享,以下是正文: Slide 01 我今天分享的主题是 Android 上低功耗蓝牙的实践。这个主题比较小众。我在过去的一年多的时间里,主要是在做低功耗蓝牙相关的开发。接触过程中发现,BLE 的开发和通常的 Android APP 的开发有点不一样,这里需要访问硬件资源,而且涉及到一些协议相关的内容,而且这方面的资料也比较少。今天我从 Android 开发者的角度,来分享一下低功耗蓝牙开发实践。 Slide 02 今天分享的内容,主要包含如下几个部分:首先对蓝牙和低功耗蓝牙做一个简单的介绍;然后介绍 Android 上对低功耗蓝牙的支持;再介绍一下在 Android 平台上可以开发哪些低功耗蓝牙应用;然后是,开发过程中,可以帮助我们调试的工具;最后,总结一下所谓的 “最佳实践”,低功耗蓝牙开发的一些小经验。 Slide

By Race604

React Native 触摸事件处理详解

触控是移动设备的核心功能,也移动应用交互的基础,Android 和 iOS 各自都有完善的触摸事件处理机制。React Native(以下简称 RN)提供了一套统一的处理方式,能够方便的处理界面中组件的触摸事件、用户手势等。本文尝试介绍 RN 中触摸事件处理。 1. RN 基本触摸组件 RN 的组件除了 Text,其他组件默认是不支持点击事件,也不能响应基本触摸事件,所以 RN 中提供了几个直接处理响应事件的组件,基本上能够满大部分的点击处理需求TouchableHighlight, TouchableNativeFeedback, TouchableOpacity 和 TouchableWithoutFeedback。因为这几个组件的功能和使用方法基本类似,只是 Touch 的反馈效果不一样,所以一般我们用 Touchable** 代替。Touchable** 有如下几个回调方法: * onPressIn:点击开始; * onPressOut:点击结束或者离开; * onPress:单击事件回调; * onLongPress:长按事件回调。 它们的基本使用方法如下,

By Race604

React Native 中 ScrollView 性能探究

1 基本使用 ScrollView 是 React Native(后面简称:RN) 中最常见的组件之一。理解 ScrollView 的原理,有利于写出高性能的 RN 应用。 ScrollView 的基本使用也非常简单,如下: <ScrollView> <Child1 /> <Child2 /> ... </ScrollView> 它和 View 组件一样,可以包含一个或者多个子组件。对子组件的布局可以是垂直或者水平的,通过属性 horizontal=true/false 来控制。甚至还默认支持“下拉”刷新操作。另外还有一个特别赞的特性,超出屏幕的 View 会自动被移除,从而节省资源和提高绘制效率。我们来看如下一个例子: class

By Race604

30 天入门 Android 开发, Google 与你一起圆梦

经常会有朋友让我推荐 Android 开发入门的教程或者视频,我一直是推荐看官方的教程。大部分人或者觉得比较迷茫,或者觉得坚持不下去。这次推荐这个《30 天入门 Android 开发》是 Google 亲自发起的免费教学,以学习小组方式,大家可以一起学习和交流。一个好的开始,是成功的一半。让 Google 工程师带领你一起进入多彩的 Android 开发大门。点击这里 报名。 Android 设备已经随处可见,你想尝试一下在 Android 设备上的开发和创新吗?快来跟随 Google 的步伐,一起学习 Android 入门课吧! Google Study Jams 活动介绍 Study Jams 是一个学习 Google 在线课程的活动。该活动由学员自主发起课程学习小组,带领小组成员入门 Android 开发,最终将

By Race604