android蓝⽛⾕歌官⽅⼿册
蓝⽛
本⽂内容
基础知识
蓝⽛权限
设置蓝⽛
查设备
查询配对的设备
发现设备
连接设备
连接为服务器
连接为客户端
管理连接
使⽤配置⽂件
供应商特定的 AT 命令
健康设备配置⽂件
关键类
BluetoothAdapter
BluetoothDevice
BluetoothSocket
BluetoothServerSocket
相关⽰例
蓝⽛聊天
蓝⽛ HDP(健康设备配置⽂件)
Android 平台包含蓝⽛⽹络堆栈⽀持,凭借此项⽀持,设备能以⽆线⽅式与其他蓝⽛设备交换数据。应⽤框架提供了通过 Android Bluetooth API 访问蓝⽛功能的途径。 这些 API 允许应⽤以⽆线⽅式连接到其他蓝⽛设备,从⽽实现点到点和多点⽆线功能。
使⽤ Bluetooth API,Android 应⽤可执⾏以下操作:
扫描其他蓝⽛设备
查询本地蓝⽛适配器的配对蓝⽛设备
建⽴ RFCOMM 通道
通过服务发现连接到其他设备
与其他设备进⾏双向数据传输
管理多个连接
本⽂将介绍如何使⽤传统蓝⽛。传统蓝⽛适⽤于电池使⽤强度较⼤的操作,例如 Android 设备之间的流式传输和通信等。 针对具有低功耗要求的蓝⽛设备,Android 4.3(API 级别 18)中引⼊了⾯向低功耗蓝⽛的 API ⽀持。 如需了解更多信息,请参阅低功耗蓝⽛。
基础知识
本⽂将介绍如何使⽤ Android Bluetooth API 来完成使⽤蓝⽛进⾏通信的四项主要任务:设置蓝⽛、查局部区域内的配对设备或可⽤设备、连接设备,以及在设备之间传输数据。
android.bluetooth 包中提供了所有 Bluetooth API。 下⾯概要列出了创建蓝⽛连接所需的类和接⼝:
BluetoothAdapter
表⽰本地蓝⽛适配器(蓝⽛⽆线装置)。 BluetoothAdapter 是所有蓝⽛交互的⼊⼝点。 利⽤它可以发现其他蓝⽛设备,查询绑定(配对)设备的列表,使⽤已知的 MAC 地址实例化 BluetoothDevice,以及创建 BluetoothServerSocket 以侦听来⾃其他设备的通信。 BluetoothDevice
表⽰远程蓝⽛设备。利⽤它可以通过 BluetoothSocket 请求与某个远程设备建⽴连接,或查询有关该设备的信息,例如设备的名称、地址、类和绑定状态等。
BluetoothSocket
表⽰蓝⽛套接字接⼝(与 TCP Socket 相似)。这是允许应⽤通过 InputStream 和 OutputStream 与其他蓝⽛设备交换数据的连接点。 BluetoothServerSocket
表⽰⽤于侦听传⼊请求的开放服务器套接字(类似于 TCP ServerSocket)。 要连接两台 Android 设备,其中⼀台设备必须使⽤此类开放⼀个服务器套接字。 当⼀台远程蓝⽛设备向此设备发出连接请求时, BluetoothServerSocket 将会在接受连接后返回已连接的BluetoothSocket。
BluetoothClass
描述蓝⽛设备的⼀般特征和功能。 这是⼀组只读属性,⽤于定义设备的主要和次要设备类及其服务。 不过,它不能可靠地描述设备⽀持的所有蓝⽛配置⽂件和服务,⽽是适合作为设备类型提⽰。
BluetoothProfile
表⽰蓝⽛配置⽂件的接⼝。 蓝⽛配置⽂件是适⽤于设备间蓝⽛通信的⽆线接⼝规范。 免提配置⽂件便是⼀个⽰例。 如需了解有关配置⽂件的详细讨论,请参阅使⽤配置⽂件
BluetoothHeadset
提供蓝⽛⽿机⽀持,以便与⼿机配合使⽤。 其中包括蓝⽛⽿机和免提(1.5 版)配置⽂件。
BluetoothA2dp
定义⾼质量⾳频如何通过蓝⽛连接和流式传输,从⼀台设备传输到另⼀台设备。“A2DP”代表⾼级⾳频分发配置⽂件。
BluetoothHealth
表⽰⽤于控制蓝⽛服务的健康设备配置⽂件代理。
BluetoothHealthCallback
⽤于实现 BluetoothHealth 回调的抽象类。您必须扩展此类并实现回调⽅法,以接收关于应⽤注册状态和蓝⽛通道状态变化的更新内容。 BluetoothHealthAppConfiguration
表⽰第三⽅蓝⽛健康应⽤注册的应⽤配置,以便与远程蓝⽛健康设备通信。
BluetoothProfile.ServiceListener
在 BluetoothProfile IPC 客户端连接到服务(即,运⾏特定配置⽂件的内部服务)或断开服务连接时向其发送通知的接⼝。
蓝⽛权限
要在应⽤中使⽤蓝⽛功能,必须声明蓝⽛权限 BLUETOOTH。您需要此权限才能执⾏任何蓝⽛通信,例如请求连接、接受连接和传输数据等。
如果您希望您的应⽤启动设备发现或操作蓝⽛设置,则还必须声明 BLUETOOTH_ADMIN 权限。 ⼤多数应⽤需要此权限仅仅为了能够发现本地蓝⽛设备。 除⾮该应⽤是将要应⽤户请求修改蓝⽛设置的“超级管理员”,否则不应使⽤此权限所授予的其他能⼒。 注:如果要使⽤BLUETOOTH_ADMIN 权限,则还必须拥有 BLUETOOTH 权限。
在您的应⽤清单⽂件中声明蓝⽛权限。例如:
<manifest ... >
安卓intent用法<uses-permission android:name="android.permission.BLUETOOTH" />
...
</manifest>
如需了解有关声明应⽤权限的更多信息,请参阅 参考资料。
设置蓝⽛
您需要验证设备⽀持蓝⽛,并且如果⽀持确保将其启⽤,然后您的应⽤才能通过蓝⽛进⾏通信。
如果不⽀持蓝⽛,则应正常停⽤任何蓝⽛功能。 如果⽀持蓝⽛但已停⽤此功能,则可以请求⽤户在不离开应⽤的同时启⽤蓝⽛。 可使⽤BluetoothAdapter,分两步完成此设置:
1.获取 BluetoothAdapter
所有蓝⽛ Activity 都需要 BluetoothAdapter。要获取 BluetoothAdapter,请调⽤静态 getDefaultAdapter() ⽅法。这将返回⼀个表⽰设备⾃⾝的蓝⽛适配器(蓝⽛⽆线装置)的 BluetoothAdapter。整个系统有⼀个蓝⽛适配器,并且您的应⽤可使⽤此对象与之交互。如果 getDefaultAdapter() 返回 null,则该设备不⽀持蓝⽛,您的操作到此为⽌。例如:
BluetoothAdapter mBluetoothAdapter = DefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}
2.启⽤蓝⽛
下⼀步,您需要确保已启⽤蓝⽛。调⽤ isEnabled() 以检查当前是否已启⽤蓝⽛。如果此⽅法返回 false,则表⽰蓝⽛处于停⽤状态。要请求启⽤蓝⽛,请使⽤ACTION_REQUEST_ENABLE 操作 Intent 调⽤ startActivityForResult()。这将通过系统设置发出启⽤蓝⽛的请求(⽆需停⽌您的应⽤)。例如:
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
如图 1 所⽰,将显⽰对话框,请求⽤户允许启⽤蓝⽛。如果⽤户响应“Yes”,系统将开始启⽤蓝⽛,并在该进程完成(或失败)后将焦点返回到您的应⽤。
传递给 startActivityForResult() 的 REQUEST_ENABLE_BT 常量是在局部定义的整型(必须⼤于 0),系统会将其作为 requestCode 参数传递回您的 onActivit yResult() 实现。
如果成功启⽤蓝⽛,您的 Activity 将会在 onActivityResult() 回调中收到 RESULT_OK 结果代码。如果由于某个错误(或⽤户响应“No”)⽽没有启⽤蓝⽛,则结果代码为 RESULT_CANCELED。
您的应⽤还可以选择侦听 ACTION_STATE_CHANGED ⼴播 Intent,每当蓝⽛状态发⽣变化时,系统都会⼴播此 Intent。 此⼴播包含额外字段 EXTRA_STATE 和 EXTRA_PREVIOUS_STATE,⼆者分别包含新的和旧的蓝⽛状态。 这些额外字段可能的值包括
STATE_TURNING_ON、STATE_ON、STATE_TURNING_OFF 和 STATE_OFF。侦听此⼴播适⽤于检测在您的应⽤运⾏期间对蓝⽛状态所做的更改。
提⽰:启⽤可检测性将会⾃动启⽤蓝⽛。 如果您计划在执⾏蓝⽛ Activity 之前⼀直启⽤设备的可检测性,则可以跳过上述步骤 2。 阅读下⾯的启⽤可检测性。
查设备
使⽤ BluetoothAdapter,您可以通过设备发现或通过查询配对(绑定)设备的列表来查远程蓝⽛设备。
设备发现是⼀个扫描过程,它会搜索局部区域内已启⽤蓝⽛功能的设备,然后请求⼀些关于各台设备的信息(有时也被称为“发现”、“查询”或“扫描”)。但局部区域内的蓝⽛设备仅在其当前已启⽤可检测
性时才会响应发现请求。 如果设备可检测到,它将通过共享⼀些信息(例如设备名称、类及其唯⼀ MAC 地址)来响应发现请求。 利⽤此信息,执⾏发现的设备可以选择发起到被发现设备的连接。
在⾸次与远程设备建⽴连接后,将会⾃动向⽤户显⽰配对请求。 设备完成配对后,将会保存关于该设备的基本信息(例如设备名称、类和MAC 地址),并且可使⽤ Bluetooth API 读取这些信息。 利⽤远程设备的已知 MAC 地址可随时向其发起连接,⽽⽆需执⾏发现操作(假定该设备处于有效范围内)。
请记住,被配对与被连接之间存在差别。被配对意味着两台设备知晓彼此的存在,具有可⽤于⾝份验证的共享链路密钥,并且能够与彼此建⽴加密连接。 被连接意味着设备当前共享⼀个 RFCOMM 通道,并且能够向彼此传输数据。 当前的 Android Bluetooth API 要求对设备进⾏配对,然后才能建⽴ RFCOMM 连接。 (在使⽤ Bluetooth API 发起加密连接时,会⾃动执⾏配对)。
以下⼏节介绍如何查已配对的设备,或使⽤设备发现来发现新设备。
注:Android 设备默认处于不可检测到状态。 ⽤户可通过系统设置将设备设为在有限的时间内处于可检测到状态,或者,应⽤可请求⽤户在不离开应⽤的同时启⽤可检测性。 下⾯讨论如何启⽤可检测性。
查询配对的设备
在执⾏设备发现之前,有必要查询已配对的设备集,以了解所需的设备是否处于已知状态。 为此,请调⽤ getBondedDevices()。 这将返回表⽰已配对设备的⼀组 BluetoothDevice。 例如,您可以查询所有已配对设备,然后使⽤ ArrayAdapter 向⽤户显⽰每台设备的名称:
Set<BluetoothDevice> pairedDevices = BondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.Name() + "\n" + Address());
}
}
要发起连接,BluetoothDevice 对象仅仅需要提供 MAC 地址。 在此⽰例中,它将保存为显⽰给⽤户的 ArrayAdapter 的⼀部分。 之后可提取该 MAC 地址,以便发起连接。 您可以在有关连接设备的部分详细了解如何创建连接。
发现设备
要开始发现设备,只需调⽤ startDiscovery()。该进程为异步进程,并且该⽅法会⽴即返回⼀个布尔值,指⽰是否已成功启动发现操作。发现进程通常包含约 12 秒钟的查询扫描,之后对每台发现的设备进⾏页⾯扫描,以检索其蓝⽛名称。
您的应⽤必须针对 ACTION_FOUND Intent 注册⼀个 BroadcastReceiver,以便接收每台发现的设备的相关信息。 针对每台设备,系统将会⼴播 ACTION_FOUND Intent。此 Intent 将携带额外字段 EXTRA_DEVICE 和 EXTRA_CLASS,⼆者分别包含 BluetoothDevice 和 BluetoothClass。 例如,下⾯说明了在发现设备时如何注册以处理⼴播。
// Create a BroadcastReceiver for ACTION_FOUND
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = Action();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = ParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.Name() + "\n" + Address());
}
}
};
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
要发起连接,BluetoothDevice 对象仅仅需要提供 MAC 地址。 在此⽰例中,它将保存为显⽰给⽤户的 ArrayAdapter 的⼀部分。 之后可提取该 MAC 地址,以便发起连接。 您可以在有关连接设备的部分详细了解如何创建连接。
注意:执⾏设备发现对于蓝⽛适配器⽽⾔是⼀个⾮常繁重的操作过程,并且会消耗⼤量资源。 在到要连接的设备后,确保始终使⽤cancelDiscovery() 停⽌发现,然后再尝试连接。 此外,如果您已经保持与某台设备的连接,那么执⾏发现操作可能会⼤幅减少可⽤于该连接的带宽,因此不应该在处于连接状态时执⾏发现操作。
启⽤可检测性
如果您希望将本地设备设为可被其他设备检测到,请使⽤ ACTION_REQUEST_DISCOVERABLE 操作 Intent 调⽤startActivityForResult(Intent, int)。 这将通过系统设置发出启⽤可检测到模式的请求(⽆需停⽌您的应⽤)。 默认情况下,设备将变为可检测到并持续 120 秒钟。 您可以通过添加 EXTRA_DISCOVERABLE_DURATION Intent Extra 来定义不同的持续时间。 应⽤可以设置的最⼤持
续时间为 3600 秒,值为 0 则表⽰设备始终可检测到。 任何⼩于 0 或⼤于 3600 的值都会⾃动设为 120 秒。 例如,以下⽚段会将持续时间设为 300 秒:
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
将显⽰对话框,请求⽤户允许将设备设为可检测到。如果⽤户响应“Yes”,则设备将变为可检测到并持续指定的时间量。 然后,您的Activity 将会收到对 onActivityResult()) 回调的调⽤,其结果代码等于设备可检测到的持续时间。 如果⽤户响应“No”或出现错误,结果代码将为 RESULT_CANCELED。
注:如果尚未在设备上启⽤蓝⽛,则启⽤设备可检测性将会⾃动启⽤蓝⽛。
设备将在分配的时间内以静默⽅式保持可检测到模式。如果您希望在可检测到模式发⽣变化时收到通知,您可以针对
ACTION_SCAN_MODE_CHANGED Intent 注册 BroadcastReceiver。 它将包含额外字段 EXTRA_SCAN_MODE 和
EXTRA_PREVIOUS_SCAN_MODE,⼆者分别告知您新的和旧的扫描模式。 每个字段可能的值包括
SCAN_MODE_CONNECTABLE_DISCOVERABLE、 SCAN_MODE_CONNECTABLE 或 SCAN_MODE_NONE,这些值分别指⽰设备处于可检测到模式、未处于可检测到模式但仍能接收连接,或未处于可检测到模式并且⽆法接收连接。
如果您将要发起到远程设备的连接,则⽆需启⽤设备可检测性。 仅当您希望您的应⽤托管将⽤于接受传⼊连接的服务器套接字时,才有必要启⽤可检测性,因为远程设备必须能够发现该设备,然后才能发起连接。
连接设备
要在两台设备上的应⽤之间创建连接,必须同时实现服务器端和客户端机制,因为其中⼀台设备必须开放服务器套接字,⽽另⼀台设备必须发起连接(使⽤服务器设备的 MAC 地址发起连接)。 当服务器和客户端在同⼀ RFCOMM 通道上分别拥有已连接的 BluetoothSocket 时,⼆者将被视为彼此连接。 这种情况下,每台设备都能获得输⼊和输出流式传输,并且可以开始传输数据,在有关管理连接的部分将会讨论这⼀主题。 本部分介绍如何在两台设备之间发起连接。
服务器设备和客户端设备分别以不同的⽅法获得需要的 BluetoothSocket。服务器将在传⼊连接被接受时收到套接字。 客户端将在其打开到服务器的 RFCOMM 通道时收到该套接字。
图 3:蓝⽛配对对话框。
⼀种实现技术是⾃动将每台设备准备为⼀个服务器,从⽽使每台设备开放⼀个服务器套接字并侦听连接。然后任⼀设备可以发起与另⼀台设备的连接,并成为客户端。 或者,其中⼀台设备可显式“托管”连接并按需开放⼀个服务器套接字,⽽另⼀台设备则直接发起连接。
注:如果两台设备之前尚未配对,则在连接过程中,Android 框架会⾃动向⽤户显⽰配对请求通知或对话框(如图 3 所⽰)。因此,在尝试连接设备时,您的应⽤⽆需担⼼设备是否已配对。 您的 RFCOMM 连接尝试将被阻塞,直⾄⽤户成功完成配对或配对失败(包括⽤户拒绝配对、配对失败或超时)。
连接为服务器
当您需要连接两台设备时,其中⼀台设备必须通过保持开放的 BluetoothServerSocket 来充当服务器。 服务器套接字的⽤途是侦听传⼊的连接请求,并在接受⼀个请求后提供已连接的 BluetoothSocket。 从 BluetoothServerSocket 获取 BluetoothSocket 后,可以(并且应该)舍弃 BluetoothServerSocket,除⾮您需要接受更多连接。
关于 UUID
通⽤唯⼀标识符 (UUID) 是⽤于唯⼀标识信息的字符串 ID 的 128 位标准化格式。 UUID 的特点是其⾜够庞⼤,因此您可以选择任意随机值⽽不会发⽣冲突。 在此⽰例中,它被⽤于唯⼀标识应⽤的蓝⽛服务。 要获取 UUID 以⽤于您的应⽤,您可以使⽤⽹络上的众多随机UUID ⽣成器之⼀,然后使⽤ fromString(String) 初始化⼀个 UUID。
以下是设置服务器套接字并接受连接的基本过程:
1.通过调⽤ listenUsingRfcommWithServiceRecord(String, UUID) 获取 BluetoothServerSocket。
该字符串是您的服务的可识别名称,系统会⾃动将其写⼊到设备上的新服务发现协议 (SDP) 数据库条⽬(可使⽤任意名称,也可直接使⽤您的应⽤名称)。 UU ID 也包含在 SDP 条⽬中,并且将作为与客户端设备的连接协议的基础。也就是说,当客户端尝试连接此设备时,它会携带能够唯⼀标识其想要连接的服务的UUID。两个 UUID 必须匹配,在下⼀步中,连接才会被接受。
2.通过调⽤ accept() 开始侦听连接请求。
这是⼀个阻塞调⽤。它将在连接被接受或发⽣异常时返回。仅当远程设备发送的连接请求中所包含的 UUID 与向此侦听服务器套接字注册的 UUID 相匹配时,连接才会被接受。操作成功后,accept() 将会
返回已连接的 BluetoothSocket。
3.除⾮您想要接受更多连接,否则请调⽤ close()。
这将释放服务器套接字及其所有资源,但不会关闭 accept() 所返回的已连接的 BluetoothSocket。与 TCP/IP 不同,RFCOMM ⼀次只允许每个通道有⼀个已连接的客户端,因此⼤多数情况下,在接受已连接的套接字后⽴即在 BluetoothServerSocket 上调⽤ close() 是⾏得通的。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论