1 .使用蓝牙的响应权限
2 .配置本地蓝牙模块
在这里,我们首先了解蓝牙适配器,它是蓝牙操作的核心类
蓝牙适配器=蓝牙适配器. getdefaultadapter (;
//直接打开系统蓝牙设置面板
intent intent=new intent (蓝牙适配器. action _ request _ enable );
startactivityforresult(intent,0x1);
//直接打开蓝牙
adapter.enable (;
//关闭蓝牙
adapter.disable (;
//打开本机蓝牙检测功能(默认情况下打开120秒,最多可以将时间延长到300秒)。
intentdiscoveryintent=new intent (蓝牙适配器. action _ request _ discoverable );
discoverable intent.put extra (蓝牙适配器. extra _ discoverable _ duration,300 ); //设定时间(最多300秒) ) ) ) ) ) ) ) )。
3 .蓝牙设备搜索
使用蓝牙适配器的startDiscovery ()方法查找蓝牙设备
startDiscovery ()方法是异步方法,调用后会立即返回。 此方法将搜索其他蓝牙设备,该过程持续12秒钟。 调用方法时,搜索过程实际上在System Service中运行,因此可以调用cancelDiscovery )方法停止搜索。 可以在发现请求未运行时调用此方法。
请求发现后,系统将开始搜索蓝牙设备,并在此过程中发送以下三个广播:
ACTION_DISCOVERY_START :开始搜索
ACTION_DISCOVERY_FINISHED :搜索结束
ACTION_FOUND :找到设备。 此Intent包含两个extra fields:extra _ device和EXTRA_CLASS,分别包含蓝牙类和蓝牙类。
我们可以自己注册相应的BroadcastReceiver以接收响应广播,从而实现一些功能
创建接收ACTION_FOUND广播的broadcast接收程序
私密性broadcastreceivermreceiver=newbroadcastreceiver (
公共void onreceive (上下文上下文,Intent intent ) )
String action=intent.getAction (;
//找到设备
if (蓝牙设备. action _ found.equals (action ) ) }
//从互联网获取设备对象
蓝牙设备设备=intent.getparcelableextra (蓝牙设备. extra _ device );
将设备名称和地址放入阵列适配器中,如ListView所示
marray adapter.add (device.getname ((n ' device.get address ) );
}
}
(;
注册BroadcastReceiver
intentfilterfilter=newintentfilter (蓝牙设备. action _ found;
注册接收器(接收器,过滤器); //别忘了解除绑定
4 .蓝牙套接字通信
如果推荐两个蓝牙设备之间的连接,则必须实现服务端和客户端机制。 如果两个设备在同一RFCOMM channel下分别有一个连接的蓝牙套接字,则可以说这两个设备已经建立了连接。
服务器设备和客户端设备获取蓝牙套接字的方式不同。 服务器设备通过accepted incoming connection获取,客户端设备通过打开到服务器的RFCOMM channel获取。
服务器端实施
调用蓝牙适配器的listenusingrfcommwithservicerecord (string,UUID )方法以获取蓝牙服务器套接字(bluetoothserversocket ) UUID。 UUID用于客户端和服务器端配对。
调用蓝牙服务器套接字的accept ()方法来接收连接
请求,如果收到请求,则返回一个BluetoothSocket实例(此方法为block方法,应置于新线程中)如果不想在accept其他的连接,则调用BluetoothServerSocket的close()方法释放资源(调用该方法后,之前获得的BluetoothSocket实例并没有close。但由于RFCOMM一个时刻只允许在一条channel中有一个连接,则一般在accept一个连接后,便close掉BluetoothServerSocket)
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) { }
}
}
客户端的实现通过搜索得到服务器端的BluetoothService
调用BluetoothService的listenUsingRfcommWithServiceRecord(String, UUID)方法获取BluetoothSocket(该UUID应该同于服务器端的UUID)
调用BluetoothSocket的connect()方法(该方法为block方法),如果UUID同服务器端的UUID匹配,并且连接被服务器端accept,则connect()方法返回
注意:在调用connect()方法之前,应当确定当前没有搜索设备,否则连接会变得非常慢并且容易失败
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) { }
}
}
连接管理(数据通信)
分别通过BluetoothSocket的getInputStream()和getOutputStream()方法获取InputStream和OutputStream
使用read(bytes[])和write(bytes[])方法分别进行读写操作
注意:read(bytes[])方法会一直block,知道从流中读取到信息,而write(bytes[])方法并不是经常的block(比如在另一设备没有及时read或者中间缓冲区已满的情况下,write方法会block)
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官方SDK、《Android/OPhone完全开发讲义》