android蓝牙开发——连接设备

为了在两台设备上创建一个连接,你必须在软件上实现服务器端和客户端的机制,因为一个设备必须必须打开一个server socket,而另一个必须初始化这个连接(使用服务器端设备的MAC地址进行初始化)。

当服务器端和客户端在同一个RFCOMM信道上都有一个BluetoothSocket时,就可以认为它们之间建立了一个连接。在这个时刻,每个设备能获得一个输出流和一个输入流,也能够开始数据传输。本节介绍如何在两个设备之间初始化一个连接。

服务器端和客户端获得BluetoothSocket的方法是不同的,服务器端是当一个进入的连接被接受时才产生一个BluetoothSocket,客户端是在打开一个到服务器端的RFCOMM信道时获得BluetoothSocket的。

远程设备请求配对

  Figure 3: The Bluetooth pairing dialog.

 

 一种实现技术是,每一个设备都自动作为一个服务器,所以每个设备都有一个server socket并监听连接。然后每个设备都能作为客户端建立一个到另一台设备的连接。另外一种代替方法是,一个设备按需打开一个server socket,另外一个设备仅初始化一个到这个设备的连接。

 

Note: 如果两个设备在建立连接之前并没有配对,那么在建立连接的过程中,Android框架将自动显示一个配对请求的notification或者一个对话框,如Figure 3所示。所以,在尝试连接设备时,你的应用程序无需确保设备之间已经进行了配对。你的RFCOMM连接将会在用户确认配对之后继续进行,或者用户拒绝或者超时之后失败。

作为一个服务器进行连接

当你想要连接两个设备时,其中一个必须保持一个打开的BluetoothServerSocket,作为服务器。服务器socket将监听进入的连接请求,一旦连接被接受,将产生一个BluetoothSocket。

  1. 调用listenUsingRfcommWithServiceRecord(String, UUID)获得一个BluetoothServerSocket

    字符串参数是你的服务的标识名,系统将自动将这个标识名写到设备上一个新的Service Discovery Protocol(SDP)数据库条目中(这个标识名可以简单地作为你的程序的名字,也就是说可以把你的程序的名字作为命名)。UUID也会被包含在这个新的SDP条目中,并作为与客户端设备建立连接的基础。 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).

  2. 调用accept()开始监听连接请求

    这是一个阻塞调用。当一个连接被接受或者发生异常时将返回。一个连接,仅当一个远程设备发出的请求包含UUID匹配正在监听的server socket所注册的UUID时被接受。成功的时候,accept()将返回一个连接的BluetoothSocket。

  3. 除非你要接受另外一个连接,否则调用close,关闭server socket。

    这将释放server socket和它占用的所有资源,但不要用来关闭accept返回的已连接的BluetoothSocket。不像TCP/IP,RFCOMM仅允许一个信道在某一时刻有一个连接的客户端。所以,创建了一个连接的socket之后立即调用close()来关闭BluetoothServerSocket。

accept()方法不应该在主Activity UI线程中执行,因为它是一个阻塞调用,如果在主Activity UI线程中条也能够将会阻止与用户的交互。一般使用BluetoothServerSocket或者BluetoothSocket进行相关工作时都是在一个新的线程中。为了避免调用诸如accept()这样的阻塞调用,针对来自其他线程的BluetoothServerSocket或者BluetoothSocket调用close()将会使阻塞调用立即返回。注意,针对BluetoothServerSocket或者BluetoothSocket调用的方法都是线程安全的,也就是说可以在多个线程中使用。

示例

 

 

manageConnectedSocket() 这个方法能初始化用于传输数据的线程。

 

感觉这些英语基本上都能看懂,就不翻译了...

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.

    Note: You should always ensure that the device is not performing device discovery when you call connect(). If discovery is in progress, then the connection attempt will be significantly slowed and is more likely to fail.

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
        mAdapter
.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) { }
   
}
}

Notice that cancelDiscovery() is called before the connection is made. You should always do this before connecting and it is safe to call without actually checking whether it is running or not (but if you do want to check, call isDiscovering()).

manageConnectedSocket() is a fictional method in the application that will initiate the thread for transferring data, which is discussed in the section about Managing a Connection.

When you're done with your BluetoothSocket, always call close() to clean up. Doing so will immediately close the connected socket and clean up all internal resources.

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值