標簽:阻塞 res his tac 循環讀取 exce 使用 exception socket
爲了讓兩個設備上的兩個應用程序之間建立連接,你必須同時實現服務端和客戶端機制。
經典藍牙連接相當于socket連接,是個非常耗時的操作,所以應該放到子線程中去完成。
// 创建监听线程,准备接受新连接。使用阻塞方式,调用BluetoothServerSocket.accept()
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread(){
BluetoothServerSocket tmp = null;
try{
//MY_UUID用于唯一标识当前的蓝牙服务,在建立连接时会被客户端使用
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME,MY_UUID);
}catch (IOException e){}
mmServerSocket = tmp;
}
public void run(){
BluetoothSocket socket= null;
while(mState != STATE_CONNECTED){
try{
// 保持监听状态,并阻塞线程,当连接建立时返回。
socket = mmServerSocket.accept();
}catch (IOException e) {
break;
}
if(socket != null){
//在单独的线程中对连接进行管理,本线程结束
ConnectedThread mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
try{
mmServerSocket.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}
public void cancel(){
try{
mmServerSocket.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device){
Log.e("ChatTag", " -- ConnectThread -- ");
mmDevice=device;
BluetoothSocket tmp = null;
//获取一个 BluetoothSocket 以连接给定的 BluetoothDevice
try{
// MY_UUID 是应用程序的 UUID 字符串,也由服务器代码使用
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
}catch (IOException e){
e.printStackTrace();
}
mmSocket = tmp;
}
public void run(){
// 取消发现,因为它会减慢连接速度
mAdapter.cancelDiscovery();
try{
// 请求连接,该操作会阻塞线程
// 直到成功或抛出异常
mmSocket.connect();
}catch (IOException e){
e.printStackTrace();
// Unable to connect; close the socket and get out
try{
mmSocket.close();
}catch (IOException e2){}
//ChatService.this.start();
return;
}
synchronized(ChatService.this){
mConnectedThread = null;
}
// 连接已建立,在单独的线程中对连接进行管理
ConnectedThread mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
}
public void cancel(){
/* try{
mmSocket.close();
}catch (IOException e){}*/
}
}
// 双方蓝牙连接后一直运行的线程。构造函数中设置输入输出流
// Run方法中使用阻塞模式的Inputstream.read()循環讀取输入流
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private InputStream mmInStream;
private OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket){
Log.e("ChatTag", " -- ConnectedThread -- ");
mmSocket = socket;
// 使用临时对象获取输入和输出流
try{
mmInStream = mmSocket.getInputStream();
mmOutStream = mmSocket.getOutputStream();
}catch (IOException e){}
}
public void run(){
byte[]buffer=new byte[1024];
int bytes;
//读数据需要不断监听 ,写 不需要
while (true) {
try {
//读取 InputStream 的数据
bytes = mmInStream.read(buffer);
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public void write(byte[]buffer){
try{
mmOutStream.write(buffer);
}catch (IOException e){
e.printStackTrace();
}
}
public void cancel(){
try{
mmSocket.close();
}catch (IOException e){}
}
}
在 主视图 的 onResume () 方法中,调用监听线程,等着被连接。
在蓝牙配对的流程中,在配对后会将配对的蓝牙设备地址 放入 Intent;
在 主视图 的 onActivityResult () 方法中,能从 Intent 中获取蓝牙设备地址
// 获取 蓝牙适配器
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// 通过蓝牙设备地址,获取 蓝牙设备
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// 然后调用连接线程,进行连接
ConnectThread mConnectThread = new ConnectThread(device);
mConnectThread.start();
然後調用連接線程,請求連接服務端
當連接通過後,客戶端和服務端就可以進行通信了。
標簽:阻塞 res his tac 循環讀取 exce 使用 exception socket
原文地址:https://www.cnblogs.com/myswift/p/14887412.html