Bluetooth

Using the Bluetooth APIs, an Android application can perform the following:

使用蓝牙APIs,一个Android应用能够进行例如以下操作:

Scan for other Bluetooth devices

扫描其它蓝牙设备

Query the local Bluetooth adapter for paired Bluetooth devices

查找本地已经配对的蓝牙设备

Establish RFCOMM channels

增强RFCOMM通道

Connect to other devices through service discovery

通过服务发现连接其它设备

Transfer data to and from other devices

交换数据和其它设备

Manage multiple connections

管理多个连接

The Basics

This document describes how to use the Android Bluetooth APIs to accomplish the four major tasks necessary to communicate using Bluetooth: setting up Bluetooth, finding devices that are either paired or available in the local area, connecting devices, and transferring
data between devices.

这个文档描写叙述了怎样使用Android Bluetooth APIs去完毕四个主要任务去使用Bluetooth交流:安装Bluetooth,查找配对的设备或者在本地可用的设备,连接设备,在设备间交换数据。

All of the Bluetooth APIs are available in the android.bluetooth package. Here's a summary of the classes and interfaces you will need to create Bluetooth connections:

全部类都在android.bluetooth这个包,这里是类的一个总览:

BluetoothAdapter

Represents the local Bluetooth adapter (Bluetooth radio). The BluetoothAdapter is the entry-point for all Bluetooth interaction. Using this, you can discover other Bluetooth devices, query a list of bonded (paired) devices, instantiate a BluetoothDevice using
a known MAC address, and create a BluetoothServerSocket to listen for communications from other devices.

代表本地蓝牙适配器(蓝牙监听者),BluetoothAdapter是全部使用Bluetooth对话的入口。使用它能够发现其它Bluetooth设备,查找已经配对的设备的列表,初始化一个BluetoothDevice使用一个知道的MAC地址,创建一个BluetoothServerSocket去监听其它设备来进行通信

BluetoothDevice

Represents a remote Bluetooth device. Use this to request a connection with a remote device through a BluetoothSocket or query information about the device such as its name, address, class, and bonding state.

代表了远程的Bluetooth设备。远程设备使用它来通过BluetoothSocket发起一个连接或者或者查询设备的名字,地址 ,类名和配对状态

BluetoothSocket

Represents the interface for a Bluetooth socket (similar to a TCP Socket). This is the connection point that allows an application to exchange data with another Bluetooth device via InputStream and OutputStream.

用来通过InputStream和OutputStream交换数据

BluetoothServerSocket

Represents an open server socket that listens for incoming requests (similar to a TCP ServerSocket). In order to connect two Android devices, one device must open a server socket with this class. When a remote Bluetooth device makes a connection request to
the this device, the BluetoothServerSocket will return a connected BluetoothSocket when the connection is accepted.

用来监听请求,两个设备为了连接,一个设备必须打开一个server socket通过这个类,当远程蓝牙设备发起一个连接来连接这个设备,BluetoothServerSocket会返回一个已经连接的BluetoothSocket当连接接受时

BluetoothClass

Describes the general characteristics and capabilities of a Bluetooth device. This is a read-only set of properties that define the device's major and minor device classes and its services. However, this does not reliably describe all Bluetooth profiles and
services supported by the device, but is useful as a hint to the device type.

描写叙述了一般的蓝牙设备的特征和功能

BluetoothProfile

An interface that represents a Bluetooth profile. A Bluetooth profile is a wireless interface specification for Bluetooth-based communication between devices. An example is the Hands-Free profile. For more discussion of profiles, see Working with Profiles

BluetoothHeadset

Provides support for Bluetooth headsets to be used with mobile phones. This includes both Bluetooth Headset and Hands-Free (v1.5) profiles.

提供了蓝牙耳机支持

Defines how high quality audio can be streamed from one device to another over a Bluetooth connection. "A2DP" stands for Advanced Audio Distribution Profile.

定义了高质量的音频通过一个设备到还有一个设备的流连接

BluetoothHealth

Represents a Health Device Profile proxy that controls the Bluetooth service.

控制蓝牙服务的设备描写叙述文件的代理

BluetoothHealthCallback

An abstract class that you use to implement BluetoothHealth callbacks. You must extend this class and implement the callback methods to receive updates about changes in the application’s registration state and Bluetooth channel
state.

一个回调在收到关于应用的注冊状态和蓝牙的通道状态更新

BluetoothHealthAppConfiguration

Represents an application configuration that the Bluetooth Health third-party application registers to communicate with a remote Bluetooth health device.

BluetoothProfile.ServiceListener

An interface that notifies BluetoothProfile IPC clients when they have been connected to or disconnected from the service (that is, the internal service that runs a particular profile).

Bluetooth Permissions

In order to use Bluetooth features in your application, you must declare the Bluetooth permission BLUETOOTH. You need this permission to perform any Bluetooth communication, such as requesting a connection, accepting a connection,
and transferring data.

全部使用蓝牙的操作都要声明BLUETOOTH权限



If you want your app to initiate device discovery or manipulate Bluetooth settings, you must also declare the BLUETOOTH_ADMIN permission. Most applications need this permission solely for the ability to discover local Bluetooth devices. The other abilities
granted by this permission should not be used, unless the application is a "power manager" that will modify Bluetooth settings upon user request. Note: If you use BLUETOOTH_ADMIN permission, then you must also have the BLUETOOTH permission.

假设希望你的程序初始化设备发现或者很多其它的蓝牙设置,你必须声明BLUETOOTH_ADMIN权限,大部分应用须要 这个权限只有须要发现本地蓝牙设备的能力,授予此权限的其它能力不应该被使用,除非该应用程序是一个“电源管理”,将依据用户请求改动蓝牙设置。



Declare the Bluetooth permission(s) in your application manifest file. For example:

<manifest ... >
<uses-permission android:name="android.permission.BLUETOOTH" />
...
</manifest>

Setting Up Bluetooth

Before your application can communicate over Bluetooth, you need to verify that Bluetooth is supported on the device, and if so, ensure that it is enabled.

在你使用蓝牙通信之前,必须验证你的设备是否支持蓝牙,而且确保它是打开的

If Bluetooth is not supported, then you should gracefully disable any Bluetooth features. If Bluetooth is supported, but disabled, then you can request that the user enable Bluetooth without leaving your application. This setup
is accomplished in two steps, using the BluetoothAdapter.

假设你的蓝牙不支持,你应该优雅地关闭不论什么蓝牙特定,假设你的蓝牙支持的可是关闭了,你应该你应该发起 请求来打开你的蓝牙而没有离开你的应用,这个安装使用BluetoothAdapter两步来完毕

1.Get the BluetoothAdapter

The BluetoothAdapter is required for any and all Bluetooth activity. To get the BluetoothAdapter, call the static getDefaultAdapter() method. This returns a BluetoothAdapter that represents the device's own Bluetooth adapter (the Bluetooth radio). There's one
Bluetooth adapter for the entire system, and your application can interact with it using this object. If getDefaultAdapter() returns null, then the device does not support Bluetooth and your story ends here. For example:

BluetoothAdapter被要求不论什么和全部的Bluetooth activity,使用静态的getDefaultAdapter()方法来获取BluetoothAdapter,返回一个代表自己蓝牙适配器的BluetoothAdapter对象,整个系统仅仅有一个蓝牙设备,你的应用能使用这个对象进行对话,返回getDefaultAdapter()返回null,你的设备是不支持蓝牙的:

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}

2.Enable Bluetooth

Next, you need to ensure that Bluetooth is enabled. Call isEnabled() to check whether Bluetooth is currently enable. If this method returns false, then Bluetooth is disabled. To request that Bluetooth be enabled, call startActivityForResult() with the ACTION_REQUEST_ENABLE
action Intent. This will issue a request to enable Bluetooth through the system settings (without stopping your application). For example:

下一步,你须要确保你的蓝牙是打开的,调用isEnabled()检查你的蓝牙当前是否是打开的,假设这种方法返回false,代表蓝牙是关闭的,为了请求打开蓝牙,调用startActivityForResult()伴随一个ACTION_REQUEST_ENABLE 的action的intent,这将会发起一个打开系统蓝牙设置的请求(而没有停止你的应用)

if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}

A dialog will appear requesting user permission to enable Bluetooth, as shown in Figure 1. If the user responds "Yes," the system will begin to enable Bluetooth and focus will return to your application once the
process completes (or fails).

一个对话框会跳出让用户打开蓝牙的权限,如图一所看到的,

If enabling Bluetooth succeeds, your activity receives the RESULT_OK result code in the onActivityResult() callback. If Bluetooth was not enabled due to an error (or the user responded "No") then the result code is RESULT_CANCELED.

假设打开蓝牙成功的,你的Activity会收到RESULT_OK结果码在 onActivityResult()回调中,假设用户选择No则结果码是RESULT_CANCELED

Optionally, your application can also listen for the ACTION_STATE_CHANGED broadcast Intent, which the system will broadcast whenever the Bluetooth state has changed. This broadcast contains the extra fields EXTRA_STATE and EXTRA_PREVIOUS_STATE,
containing the new and old Bluetooth states, respectively. Possible values for these extra fields are STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF, and STATE_OFF. Listening for this broadcast can be useful to detect changes made to the Bluetooth state while
your app is running.

可选的,你的应用可以监听ACTION_STATE_CHANGED广播intent,当系统蓝牙状态改变将会发起这个广播,这个广播包括了EXTRA_STATE和EXTRA_PREVIOUS_STATE额外的字段,包括了新的和旧的蓝牙状态分别的,可能 有STATE_TURNING_ON,STATE_ON,STATE_TURNING_OFF和STATE_OFF可能的值,监听广播可以 对于检測蓝牙状态改变是实用的。

Finding Devices(发现设备)

Using the BluetoothAdapter, you can find remote Bluetooth devices either through device discovery or by querying the list of paired (bonded) devices.

使用BluetoothAdapter,你可以打开可见性的设备和已经配对的的设备列表。

Device discovery is a scanning procedure that searches the local area for Bluetooth enabled devices and then requesting some information about each one (this is sometimes referred to as "discovering," "inquiring" or "scanning").
However, a Bluetooth device within the local area will respond to a discovery request only if it is currently enabled to be discoverable. If a device is discoverable, it will respond to the discovery request by sharing some information, such as the device
name, class, and its unique MAC address. Using this information, the device performing discovery can then choose to initiate a connection to the discovered device.

设备可见性对于一个扫描程序查找本地打开蓝牙的设备然后请求关于不论什么一方的某些信息,然而,一个蓝牙设备在本地将会响应一个可见请求仅仅有在当前打开了可见性,假设设备打开可见性的,它将响应可见请求通过分享某些信息,比方设备的名字,类,和它的独一无二的MAC地址,使用这个信息,设备可以操作可见性设备来初始化一个连接

Once a connection is made with a remote device for the first time, a pairing request is automatically presented to the user. When a device is paired, the basic information about that device (such as the device name, class, and
MAC address) is saved and can be read using the Bluetooth APIs. Using the known MAC address for a remote device, a connection can be initiated with it at any time without performing discovery (assuming the device is within range).

一旦远程设备第一次被连接,一个配对的请求代表用户,当一个设备被配对的,关于设备的基本信息被保存然后可以使用BluetoothAPI去读取,使用一个MAC地址对于一个远程设备,一个连接可以被初始化在不论什么在可见范围内。

Remember there is a difference between being paired and being connected. To be paired means that two devices are aware of each other's existence, have a shared link-key that can be used for authentication, and are capable of
establishing an encrypted connection with each other. To be connected means that the devices currently share an RFCOMM channel and are able to transmit data with each other. The current Android Bluetooth API's require devices to be paired before an RFCOMM
connection can be established. (Pairing is automatically performed when you initiate an encrypted connection with the Bluetooth APIs.)

记住配对和连接之间的差别,已经配对的意味着两个设备是互相认识对方的存在,已经有了一个用来认证的共享的key,然后可以被捕捉对于建立一个可信的连接互相。已经连接意味着设备当前分享一个RFCOMM通道and可以交换数据互相的。当前的Android Bluetooth API要求设备被配对的在一个RFCOMM连接被建立之前。

The following sections describe how to find devices that have been paired, or discover new devices using device discovery.

例如以下部分描写叙述了怎样发现已经配对的设备,或者发现使用设备可见性发现一个新设备。

Querying paired devices(查询已经配对的设备)

Before performing device discovery, its worth querying the set of paired devices to see if the desired device is already known. To do so, call getBondedDevices(). This will return a Set of BluetoothDevices representing paired
devices. For example, you can query all paired devices and then show the name of each device to the user, using an ArrayAdapter:

在操作一个可见的设备之前,查询已经配对设备的集合来选择你渴望的设备是值得的,使用getBondedDevices()来调用。这将会返回一个已经配对的设备的集合,比如:你能够查询全部已经配对的设备然后显示给用户他们的名字使用一个ArrayAdapter。

Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// 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.add(device.getName() + "\n" + device.getAddress());
}
}

All that's needed from the BluetoothDevice object in order to initiate a connection is the MAC address. In this example, it's saved as a part of an ArrayAdapter that's shown to the user. The MAC address can later
be extracted in order to initiate the connection. You can learn more about creating a connection in the section about Connecting Devices.

全部事情须要一个MAC地址来来初始化一个BluetoothDevice对象为了初始化一个连接。在这个样例中,它作为ArrayAdapter的一部分来展示给用户。MAC地址可以后来被提取到来初始化连接,你可以学习很多其它关于创建连接在Connecting Devices这部分

Discovering devices

To start discovering devices, simply call startDiscovery(). The process is asynchronous and the method will immediately return with a boolean indicating whether discovery has successfully started. The discovery process usually
involves an inquiry scan of about 12 seconds, followed by a page scan of each found device to retrieve its Bluetooth name.

为了开启示现设备,简单地调用startDiscovery()。这个进程是同步的,这种方法将会直接返回一个boolean表明查找是否成功被开启的。发现进程通常牵涉一个12秒的查询扫描,紧接着通过一个页面显示由搜索到的发现的设备检索到的Bluetooth名字。

Your application must register a BroadcastReceiver for the ACTION_FOUND Intent in order to receive information about each device discovered. For each device, the system will broadcast the ACTION_FOUND Intent. This Intent carries
the extra fields EXTRA_DEVICE and EXTRA_CLASS, containing a BluetoothDevice and a BluetoothClass, respectively. For example, here's how you can register to handle the broadcast when devices are discovered:

你的应用必须注冊一个BroadcastReceiver对于一个ACTION_FOUND的intent来接受关于每个已经发现的设备。对于每个设备,系统将会广播发起

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 = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy

All that's needed from the BluetoothDevice object in order to initiate a connection is the MAC address. In this example, it's saved as a part of an ArrayAdapter that's shown to the user. The MAC address can later be extracted
in order to initiate the connection. You can learn more about creating a connection in the section about Connecting Devices.

全部的操作须要一个MAC地址为了初始化一个连接从BluetoothDevice对象。在这个样例,保存到ArrayAdapter的一部分显示给用户。MAC地址可以可以稍后被解析用来初始化一个连接。你可以创建一个连接在Connecting Devices部分。

Caution: Performing device discovery is a heavy procedure for the Bluetooth adapter and will consume a lot of its resources. Once you have found a device to connect, be certain that you always stop discovery with cancelDiscovery()
before attempting a connection. Also, if you already hold a connection with a device, then performing discovery can significantly reduce the bandwidth available for the connection, so you should not perform discovery while connected.

小心:操作设备可见是一个重量的进程对于Bluetooth 适配器,将会消耗非常多资源。一旦你找到了连接的设备,在企图连接之前用cancelDiscovery()总应该停止可见。假设你已经持有一个设备的连接,操作可见性将显著降低带宽。因此你不应该在连接后操作可见性。

Enabling discoverability

If you would like to make the local device discoverable to other devices, call startActivityForResult(Intent, int) with the ACTION_REQUEST_DISCOVERABLE action Intent. This will issue a request to enable discoverable mode through
the system settings (without stopping your application). By default, the device will become discoverable for 120 seconds. You can define a different duration by adding the EXTRA_DISCOVERABLE_DURATION Intent extra. The maximum duration an app can set is 3600
seconds, and a value of 0 means the device is always discoverable. Any value below 0 or above 3600 is automatically set to 120 secs). For example, this snippet sets the duration to 300:

假设你想使本地设备让其它设备可见的,调用startActivityForResult(Intent, int)伴随ACTION_REQUEST_DISCOVERABLE的action的intent。这将会发起一个请求通过系统设置(而没有停止你的设备)来打开可见性。默认的,设备变成可见120秒。你能够通过添加一个EXTRA_DISCOVERABLE_DURATION的额外字段的intent来定义一个周期时间。一个应用最大周期能够设置3600秒,假设设置为0意味着设备总是可见的。不论什么小于0或者大于3600的值将自己主动设置到120秒。比如,这个片段设置300秒:

Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);

A dialog will be displayed, requesting user permission to make the device discoverable, as shown in Figure 2. If the user responds
"Yes," then the device will become discoverable for the specified amount of time. Your activity will then receive a call to the onActivityResult()) callback, with the result code equal to the duration that the device is discoverable. If the user responded
"No" or if an error occurred, the result code will be RESULT_CANCELED.

一个对话框显示来请求用户的权限来打开设备的可见性,如图二所看到的。假设用户回复YES,设备将会变成指定时间的可见的。你的应用将会收到一个回调在onActivityResult(),伴随一个和周期等值的结果码代表设备是可见的。假设用户回复NO或发生error,结果码将是RESULT_CANCELED。

Note: If Bluetooth has not been enabled on the device, then enabling device discoverability will automatically enable Bluetooth.

假设设备没有打开Bluetooth,打开可见性将会自己主动打开蓝牙。

The device will silently remain in discoverable mode for the allotted time. If you would like to be notified when the discoverable mode has changed, you can register a
BroadcastReceiver for the ACTION_SCAN_MODE_CHANGED Intent. This will contain the extra fields EXTRA_SCAN_MODE and EXTRA_PREVIOUS_SCAN_MODE, which tell you the new and old scan mode, respectively. Possible values for each are SCAN_MODE_CONNECTABLE_DISCOVERABLE,
SCAN_MODE_CONNECTABLE, or SCAN_MODE_NONE, which indicate that the device is either in discoverable mode, not in discoverable mode but still able to receive connections, or not in discoverable mode and unable to receive connections, respectively.

设备将会静静地在指定时间停留在可见模式。假设你想要发起一个通知在可见性改变 了,你可以注冊一个得到ACTION_SCAN_MODE_CHANGED的intent的BroadcastReceiver。这将会包括EXTRA_SCAN_MODE和EXTRA_PREVIOUS_SCAN_MODE字段指明新的和原来的模式分别。每一个字段都会有SCAN_MODE_CONNECTABLE_DISCOVERABLE,SCAN_MODE_CONNECTABLE或SCAN_MODE_NONE可能的值,分别指明,设备在可见模式,不在可见模式可是仍然可以收到一个连接,或者不再可见模式也不能收到一个连接。

You
do not need to enable device discoverability if you will be initiating the connection to a remote device. Enabling discoverability is only necessary when you want your application to host a server socket that will accept incoming connections, because the remote
devices must be able to discover the device before it can initiate the connection.

你不须要
打开可见性假设你将要初始化一个远程设备的连接。打开可见性仅仅有当你的应用作为一个服务socket来接受请求的连接时必要的,由于远程设备在初始化连接之前必须发现这个设备。

Connecting
Devices

In
order to create a connection between your application on two devices, you must implement both the server-side and client-side mechanisms, because one device must open a server socket and the other one must initiate the connection (using the server device's
MAC address to initiate a connection). The server and client are considered connected to each other when they each have a connected BluetoothSocket on the same RFCOMM channel. At this point, each device can obtain input and output streams and data transfer
can begin, which is discussed in the section about Managing a Connection. This section describes how to initiate the connection between two devices.

为了在两个设备之间创建一个连接,你必须在你的服务端和client实现结构,一个设备必须打开服务socket,其它设备必须初始化连接(使用服务设备的MAC地址来初始化连接)。服务和客户被觉得连接到对方当连接BluetoothSocket在同样的RFCOMM通道。在这点上,每一个设备必须获取输入和输出流,数据转换開始,这部分将在Managing
a Connection被讨论。这部分将描写叙述怎样在两个设备之间初始化连接。

The server device and the client device each obtain the required BluetoothSocket in different ways. The server will receive it when an incoming connection is accepted. The client will receive it when it opens an RFCOMM channel
to the server.

server设备和服务设备必须用不同的方式获取必要的BluetoothSocket。服务端当收入一个连接将会开启。可会端当打开到服务端的一个RFCOMM通道将会被开启。

One implementation technique is to automatically prepare each device as a server, so that each one has a server socket open and listening for connections. Then either
device can initiate a connection with the other and become the client. Alternatively, one device can explicitly "host" the connection and open a server socket on demand and the other device can simply initiate the connection.

一个实现技术是自己主动给每个设备设置为服务端,以至于每个设备都有一个server socket打开和监听连接。不论什么一个设备可以初始化一个连接到还有一个设备而变成client。

Note: If the two devices have not been previously paired, then the Android framework will automatically show a pairing request notification or dialog to the user during
the connection procedure, as shown in Figure 3. So when attempting to connect devices, your application does not need to be concerned about whether or not the devices are paired. Your RFCOMM connection attempt will block until the user has successfully paired,
or will fail if the user rejects pairing, or if pairing fails or times out.

注意:假设两个设备先前没有配对,Android框架将会自己主动展示一个配对请求通知,展示给用户连接进程的对话框,如图3。企图连接设备,你的应用不须要关心设备是否配对的。你的RFCOMM连接企图将会堵塞知道用户成功配对,将会失败当用户拒绝配对,或者配对超时。

Connecting as a server

When you want to connect two devices, one must act as a server by holding an open BluetoothServerSocket. The purpose of the server socket is to listen for incoming connection requests and when one is accepted, provide a connected
BluetoothSocket. When the BluetoothSocket is acquired from the BluetoothServerSocket, the BluetoothServerSocket can (and should) be discarded, unless you want to accept more connections.

当你想要连接两个设备,一个必须作为服务端持有一个BluetoothServerSocket。

Here's the basic procedure to set up a server socket and accept a connection:

这里是主要的步骤来安装一个server套接字,然后接受一个连接:

1.Get a BluetoothServerSocket by calling the listenUsingRfcommWithServiceRecord(String, UUID).

The string is an identifiable name of your service, which the system will automatically write to a new Service Discovery Protocol (SDP) database entry on the device (the name is arbitrary and can simply be your application name). The UUID is also included in
the SDP entry and will be the basis for the connection agreement with the client device. That is, when the client attempts to connect with this device, it will carry a UUID that uniquely identifies the service with which it wants to connect. These UUIDs must
match in order for the connection to be accepted (in the next step).

通过调用listenUsingRfcommWithServiceRecord(String, UUID)获取一个BluetoothServerSocket。

2.Start listening for connection requests by calling accept().

This is a blocking call. has been ac It will return when either a connectioncepted or an exception has occurred. A connection is
accepted only when a remote device has sent a connection request with a UUID matching the one registered with this listening server socket. When successful, accept() will return a connected BluetoothSocket.

通过调用accept()来监听连接请求。

3.Unless you want to accept additional connections, call close().

This releases the server socket and all its resources, but does not close the connected BluetoothSocket that's been returned by accept(). Unlike TCP/IP, RFCOMM only allows one connected client per channel at a time, so in most cases it makes sense to call close()
on the BluetoothServerSocket immediately after accepting a connected socket.

调用 close()释放资源。

The accept() call should not be executed in the main activity UI thread because it is a blocking call and will prevent any other interaction with the application. It usually makes sense to do all
work with a BluetoothServerSocket or BluetoothSocket in a new thread managed by your application. To abort a blocked call such as accept(), call close() on the BluetoothServerSocket (or BluetoothSocket) from another thread and the blocked call will immediately
return. Note that all methods on a BluetoothServerSocket or BluetoothSocket are thread-safe.

Example



Here's a simplified thread for the server component that accepts incoming connections:

private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket; public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) { }
mmServerSocket = tmp;
} public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(socket);
mmServerSocket.close();
break;
}
}
} /** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
}

Connecting as a client



In order to initiate a connection with a remote device (a device holding an open server socket), you must first obtain a BluetoothDevice object that represents the remote device. (Getting a BluetoothDevice is covered in the above section about Finding Devices.)
You must then use the BluetoothDevice to acquire a BluetoothSocket and initiate the connection.

Here's the basic procedure:

1.Using the BluetoothDevice, get a BluetoothSocket by calling createRfcommSocketToServiceRecord(UUID).

This initializes a BluetoothSocket that will connect to the BluetoothDevice. The UUID passed here must match the UUID used by the server device when it opened its BluetoothServerSocket (with listenUsingRfcommWithServiceRecord(String, UUID)). Using the same
UUID is simply a matter of hard-coding the UUID string into your application and then referencing it from both the server and client code.

2.Initiate the connection by calling connect().

Upon this call, the system will perform an SDP lookup on the remote device in order to match the UUID. If the lookup is successful and the remote device accepts the connection, it will share the RFCOMM channel to use during the connection and connect() will
return. This method is a blocking call. If, for any reason, the connection fails or the connect() method times out (after about 12 seconds), then it will throw an exception.

Because connect() is a blocking call, this connection procedure should always be performed in a thread separate from the main activity thread.

Example



Here is a basic example of a thread that initiates a Bluetooth connection:

private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice; public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device; // Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
} public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery(); try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
} // Do work to manage the connection (in a separate thread)
manageConnectedSocket(mmSocket);
} /** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}

Managing a Connection

When you have successfully connected two (or more) devices, each one will have a connected BluetoothSocket. This is where the fun begins because you can share data between devices. Using the BluetoothSocket, the general procedure
to transfer arbitrary data is simple:

1.Get the InputStream and OutputStream that handle transmissions through the socket, via getInputStream()and getOutputStream(), respectively.

Read and write data to the streams with read(byte[]) and write(byte[]).

2.Get the InputStream and OutputStream that handle transmissions through the socket, via getInputStream() and getOutputStream(), respectively.

Read and write data to the streams with read(byte[]) and write(byte[]).

Example



Here's an example of how this might look:

private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream; public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null; // Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { } mmInStream = tmpIn;
mmOutStream = tmpOut;
} public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read() // Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
} /* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
} /* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}

android Bluetooth(官方翻译)的更多相关文章

  1. 【转】Android bluetooth介绍(二): android blueZ蓝牙代码架构及其uart 到rfcomm流程

    原文网址:http://blog.sina.com.cn/s/blog_602c72c50102uzoj.html 关键词:蓝牙blueZ  UART  HCI_UART H4  HCI  L2CAP ...

  2. Android Bluetooth开发

    原文地址:http://developer.android.com/guide/topics/wireless/bluetooth.html 翻译:jykenan 更新:2012.06.19 Andr ...

  3. Netty5.x 和3.x、4.x的区别及注意事项(官方翻译)

    Netty5.x 和3.x.4.x的区别及注意事项 (官方翻译) 本文档列出了Netty5新版本中值得注意变化和新特性列表.帮助你的应用更好的适应新的版本.   不像Netty3.x和4.x之间的变化 ...

  4. Android Bluetooth模块学习笔记

    一.蓝牙基础知识 1.蓝牙( Bluetooth )是一种无线技术标准,可实现固定设备.移动设备和楼宇个人域网之间的短距离数据交换.蓝牙基于设备低成本的收发器芯片,传输距离近.低功耗. 2.微波频段: ...

  5. Android Bluetooth 总结

    一.Android Bluetooth现状 (1)Android2.2版 支持的蓝牙核心版本是Bluetooth 2.0 + EDR. (2)Android 的蓝牙 使用了BlueZ协议栈,但只实现了 ...

  6. Android bluetooth介绍(两): android 蓝牙源架构和uart 至rfcomm过程

    关键词:蓝牙blueZ  UART  HCI_UART H4  HCI  L2CAP RFCOMM  版本号:基于android4.2先前版本 bluez内核:linux/linux3.08系统:an ...

  7. 【转】Android bluetooth介绍(三): 蓝牙扫描(scan)设备分析

    原文网址:http://blog.csdn.net/xubin341719/article/details/38584469 关键词:蓝牙blueZ  A2DP.SINK.sink_connect.s ...

  8. ST官方翻译的中文应用笔记汇总

    ST官方翻译的中文应用笔记汇总 http://www.51hei.com/stm32/3382.html 官方中文AN:AN3116:STM32? 的 ADC 模式及其应用AN1015:用于提高微控制 ...

  9. Android bluetooth介绍(四): a2dp connect流程分析

    关键词:蓝牙blueZ  A2DP.SINK.sink_connect.sink_disconnect.sink_suspend.sink_resume.sink_is_connected.sink_ ...

随机推荐

  1. CTE的使用

    CTE在SQL2005后的版本提供,丰富了查询的表现形式,下面我们慢慢来看下CTE都能干什么 1.自我递归 ;WITH myaa AS ( SELECT num=1 UNION ALL SELECT ...

  2. iOS应用架构谈 开篇 (转)

    iOS应用架构谈 开篇  iOS应用架构谈 view层的组织和调用方案 iOS应用架构谈 网络层设计方案 iOS应用架构谈 动态部署方案 iOS应用架构谈 本地持久化方案 缘由 之前安居客iOS ap ...

  3. hibernate_validator_02

    三种不通的注解 1. 字段级(field level) 约束 package com.mycompany; import javax.validation.constraints.NotNull; p ...

  4. Specified VM install not found: type Standard VM, name jdk1.6.0_05

    重装系统换了jdk,之前jdk用的1.6,现在改成1.7了.但是更新之后发现ant打包用不了了,报错 Specified VM install not found: type Standard VM, ...

  5. JS类型判定方法(不包括自定义类型)

    //判定数据类型 function isType(obj, type) { return toString.call(obj).indexOf('[object ' + type) == 0; } / ...

  6. php图片上传

    //处理图片 private function imageDeal($param){ $arrType=array('image/jpg','image/bmp','image/png','image ...

  7. git stash 保存修改现场

    用途:当你正在分支上做一个项目的时候,突然必须停下来去做别的事情,但因为没有此项目还没改好,所以不想commit 就可以保留现场,等忙完后再回复现场继续修改. bug处理保存开发现场$ git sta ...

  8. jquery如何判断滚动条滚到页面底部并执行事件

    首先理解三个dom元素,分别是:clientHeight.offsetHeight.scrollTop. clientHeight:这个元素的高度,占用整个空间的高度,所以,如果一个div有滚动条,那 ...

  9. sql server 调优----索引未使用

    SELECT TOP 1000o.name AS 表名, i.name AS 索引名, i.index_id AS 索引id, dm_ius.user_seeks AS 搜索次数, dm_ius.us ...

  10. 用Javascript的for循环输出质数

    <body> <script type="text/javascript"> for(i=2;i<=300;i++){ var prime = tru ...