Android Developer -- Bluetooth篇 开发实例之二 连接设备
连接设备
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.
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.
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,那么另一端就必须初始化一个连接(通过使用server device's MAC地址来初始化连接)。当服务端和客户端彼此连接的时候,他们会在同一个RFCOMM通道上,各自拥有一个连接着的 BluetoothSocket 。每台设备都包含输入输出流,用来数据交换,详细内容详见Managing a Connection章节。本章节讨论的是怎么在两台设备中初始化连接。
服务器装置和客户端装置各获得所需的BluetoothSocket的方式不同。当接收连接被接受时,服务器将接收它。当,它打开一个RFCOMM通道到服务器,客户将接收它。
一种实现技术是每台设备都作为server,这样就可以拥有一个server socket来监听连接。当其他设备初始化连接的时候,就变成了客户端。另外,当设备显性的变成“host”时候,会打开一个server socket,其他设备就能简单的连接了。
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 框架,会在连接过程中,自动的显示一个配对请求通知,或者dialog。因此,当尝试连接设备时,您的应用程序不需要关注设备是否配对。你的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.
当你想要连接两台设备的时候,一端必须工作在server状态下,并且要拥有一个打开的BluetoothServerSocket。目的是为了监听外来的连接请求,一旦请求接受,那么就提供一个 BluetoothSocket.当 BluetoothSocket从BluetoothServerSocket获取的时候,BluetoothServerSocket可以(应该)被舍弃,除非你想要更多的连接。
Here's the basic procedure to set up a server socket and accept a connection:
- Get a
BluetoothServerSocketby calling thelistenUsingRfcommWithServiceRecord(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).
- Start listening for connection requests by calling
accept().This is a blocking call. It will return when either a connection has been accepted 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 connectedBluetoothSocket. - Unless you want to accept additional connections, call
close().This releases the server socket and all its resources, but does not close the connected
BluetoothSocketthat's been returned byaccept(). Unlike TCP/IP, RFCOMM only allows one connected client per channel at a time, so in most cases it makes sense to callclose()on theBluetoothServerSocketimmediately after accepting a connected socket.
这里是显示如何设置一个server socket和接受一个连接的基本过程:
步骤:
第一步:
1.通过调用listenUsingRfcommWithServiceRecord(String, UUID).来获取 BluetoothServerSocket。参数String是你服务的名称,系统会自动的写入一个新的 new Service Discovery Protocol (SDP) database entry(该名字可以是任意的,简单写应用程序名就行。) UUID也包括在SDP entry并将成为客户设备的连接协议的基础。它将携带一个UUID用来唯一标识它要连接的服务。这些UUID必须匹配,为了连接能被接受(下一步)。
第二步:
2.调用 accept().方法,开始监听连接请求。
这是一个阻塞的方法,当连接被接受或者异常发生时,它将返回。远程设备需要携带UUID来连接server socket。如果成功,将返回一个 connected BluetoothSocket.
第三步:
3.除非你想要接受更多的连接,那么要调用close().方法
这个方法会释放server socket和它所占的所有资源,但它不会关闭已经连接的BluetoothSocket。不同于TCP/IP, RFCOMM只允许每个信道在一个时刻内存在一个连接的客户端,所以在大多情况下,在接受一个连接的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 aBluetoothServerSocket or BluetoothSocket are thread-safe.
accept() 方法不应该在主线程中调用,因为它是一个阻塞的方法。所以需要另开线程来处理BluetoothServerSocket or BluetoothSocket。
Example
Here's a simplified thread for the server component that accepts incoming connections:
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) { }
}
}
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.
注意:在连接设备的时候,需要调用cancelDiscovery()方法。当你连接的时候,你总是要这样做。而且,这个方法是安全的,无论它是否在运行(如果需要确认,调用isDiscovering()方法)。
manageConnectedSocket() 是一个虚构的方法,用来初始化交换数据的线程,详细描述在Managing a Connection.章节。
当你使用BluetoothSocket,完成事情的时候,总是要调用close()来清理。这样做将立即关闭连接的套接字和清理所有内部资源。
Android Developer -- Bluetooth篇 开发实例之二 连接设备的更多相关文章
- Android Developer -- Bluetooth篇 开发实例之四 API详解
http://www.open-open.com/lib/view/open1390879771695.html 这篇文章将会详细解析BluetoothAdapter的详细api, 包括隐藏方法, 每 ...
- Android Developer -- Bluetooth篇 开发实例之一 扫描设备
第一步:声明Bluetooth Permissions <!-- 设置蓝牙访问权限 --> <uses-permission android:name="android.p ...
- Android Developer -- Bluetooth篇 开发实例之三 管理连接
Managing a Connection When you have successfully connected two (or more) devices, each one will have ...
- Bluetooth篇 开发实例之九 和蓝牙模块通信
首先,我们要去连接蓝牙模块,那么,我们只要写客户端的程序就好了,蓝牙模块就相当于服务端. 连接就需要UUID. #蓝牙串口服务SerialPortServiceClass_UUID = ‘{00001 ...
- Bluetooth篇 开发实例之八 匹配
自己写的App匹配蓝牙设备,不需要通过系统设置去连接. 匹配和通信是两回事. 用过Android系统设置(Setting)的人都知道蓝牙搜索之后可以建立配对和解除配对,但是这两项功能的函数没有在SDK ...
- Bluetooth篇 开发实例之七 匹配&UUID
匹配和通信是两回事. 1.用过Android系统设置(Setting)的人都知道蓝牙搜索之后可以建立配对和解除配对,但是这两项功能的函数没有在SDK中给出.但是可以通过反射来获取. 知道这两个API的 ...
- Bluetooth篇 开发实例之十 官网的Bluetooth Chat sample app.
运行的时候,会报错: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.Action ...
- Android Developer -- Bluetooth篇 概述
Bluetooth 安卓平台支持蓝牙网络协议栈,它允许设备与其他蓝牙设备进行无线交换数据.应用程序框架通过安卓蓝牙APIs提供访问蓝牙功能.这些APIs使应用程序通过无线连接到其他蓝牙设备,使点对点和 ...
- Bluetooth篇 开发实例之十一 官网的Bluetooth Chat sample的bug
当没有匹配的设备和没有找到可用设备的时候. // If there are paired devices, add each one to the ArrayAdapter if (pairedDev ...
随机推荐
- pytorch下对简单的数据进行分类(classification)
看了Movan大佬的文字教程让我对pytorch的基本使用有了一定的了解,下面简单介绍一下二分类用pytorch的基本实现! 希望详细的注释能够对像我一样刚入门的新手来说有点帮助! import to ...
- Struts2 学习笔记
1)Strust2是以WebWork为核心,采用拦截器的机制对用户请求进行处理. 2)Struts2框架结构: 3)简单来看整个Struts2的处理过程可以简单的理解为 用户的请求发送给对应的Acti ...
- iOS如何隐藏状态栏,包括网络标志、时间标志、电池标志等
我们在开发App的时候,在遇到有状态栏时,NavigationBar上面的按钮,是极难点击的,所以这个时候,最好我们能够人为的隐藏掉状态栏. 如果一直需要隐藏的话,直接在info.plist里面,添加 ...
- nyoj 题目49 开心的小明
开心的小明 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 小明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天 ...
- String中的“equal方法”和“==”
二话不说,先来说下重写的事情: 在Java中,String .Math.还有Integer.Double....等这些封装类重写了Object中的equals()方法,让它不再比较其对象在内存中的地址 ...
- python使用openpyxl操作excel
def initExcel(): file_path = "test.xlsx" file = load_workbook(file_path) table = file[&quo ...
- shell脚本——项目2
案例名称:发送告警邮件 背景: 外部邮箱的服务器(163等) 安装mailx(yum) 配置邮箱信息 vim /etc/mail.rc #配置自己的邮箱信息 set from=18906534060@ ...
- windows 安装 mysql5.7
1. 搜索“Mysql download”进入官网 或者点击链接 https://dev.mysql.com/downloads/ 进入官网,如下: 2. 下载对应的 MySQL 版本,如下: 点击 ...
- [ CodeVS冲杯之路 ] P1048
不充钱,你怎么AC? 题目:http://codevs.cn/problem/1048/ 区间DP题,设 f[i][j] 为在区间 [i,j] 中合并的最小代价 目标状态是 f[1][n],末尾的求和 ...
- MFC中GetParent()的作用(转)
原文转自 https://bbs.csdn.net/topics/390540690 1.假如创建一个非模态的窗口,在如下两种做法里任选一种.(1) chatting.m_lpDlg = new CC ...