我正在尝试制作一个与附近设备通信的应用程序。 我的应用程序由要求启用蓝牙并设置可发现模式的主要活动组成,因此它等待建立连接。
第二项活动是寻找附近的设备并进行配对。 配对之后,交换一些配置消息,然后两者都启动处理两个设备之间通信的ThirdActivity。
我可以成功交换这些消息,但是问题是我需要将BluetoothService对象(保留通信信息)传递给Third Activity。
由于我认为我无法实现可拆分的,因此我只是在不消除配对的情况下关闭了连接,然后通过创建一个新的BluetoothService对象但始终传递相同的BluetoothDevice来在thirdActivity中重新创建AcceptThread和ConnectThread。
从各种日志中可以看到,AcceptThread等待accept(),而ConnectThread使connect()无法报告此错误。
W/System.err: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:762)
at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:776)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:399)
at com.crossthebox.progetto.BluetoothService$ConnectThread.run(BluetoothService.java:118)
我该怎么办?
这是BluetoothService类
public class BluetoothService {
private UUID myid = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
private static final String appName = "myapp";
private static final int STATE_NONE = 0; // we're doing nothing
private static final int STATE_LISTEN = 1; // now listening for incoming connections
private static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
private static final int STATE_CONNECTED = 3;
private static final int STATE_BUFFER_NOT_EMPTY = 4;
private String message ="";
private int mState;
private final BluetoothAdapter mBluetoothAdapter;
Context mContext;
private AcceptThread mAcceptThread;
private ConnectThread mConnectThread;
private BluetoothDevice mDevice;
private UUID deviceUUID;
private ConnectedThread mConnectedThread;
public BluetoothService(Context context) {
mContext = context;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
}
private class AcceptThread extends Thread {
private final BluetoothServerSocket bluetoothServerSocket;
public AcceptThread(){
BluetoothServerSocket tmp = null;
try{
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(appName, myid);
}catch (IOException e){
}
bluetoothServerSocket = tmp;
mState = STATE_LISTEN;
}
public void run() {
BluetoothSocket socket = null;
try {
socket = bluetoothServerSocket.accept();
} catch (IOException e) {
}
if (socket != null) {
mState = STATE_CONNECTING;
connected(socket);
}
}
public void cancel() {
try {
bluetoothServerSocket.close();
} catch (IOException e) {
}
}
}
private class ConnectThread extends Thread {
private BluetoothSocket mSocket;
public ConnectThread(BluetoothDevice device, UUID uuid) {
mDevice = device;
deviceUUID = uuid;
}
public void run(){
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = mDevice.createRfcommSocketToServiceRecord(deviceUUID);
} catch (IOException e) {
}
mSocket = tmp;
mBluetoothAdapter.cancelDiscovery();
try {
mSocket.connect(); //this throws exception for socket close ( but only the second time)
} catch (IOException e) {
// Close the socket
try {
mSocket.close();
} catch (IOException e1) {
}
e.printStackTrace();
}
connected(mSocket);
}
public void cancel() {
try {
mSocket.close();
} catch (IOException e) {
}
}
}
public synchronized void start() {
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mAcceptThread == null) {
mAcceptThread = new AcceptThread();
mAcceptThread.start();
}
}
public void startClient(BluetoothDevice device,UUID uuid){
mConnectThread = new ConnectThread(device, uuid);
mConnectThread.start();
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mSocket;
private final InputStream mInStream;
private final OutputStream mOutStream;
public ConnectedThread(BluetoothSocket socket) {
mSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = mSocket.getInputStream();
tmpOut = mSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mInStream = tmpIn;
mOutStream = tmpOut;
}
public void run(){
byte[] buffer = new byte[1024];
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
// Read from the InputStream
try {
bytes = mInStream.read(buffer);
if(bytes != 0) {
String incomingMessage = new String(buffer, 0, bytes);
message = incomingMessage;
System.out.println("HO LETTO " + message);
mState = STATE_BUFFER_NOT_EMPTY;
}
} catch (IOException e) {
break;
}
}
}
//Call this from the main activity to send data to the remote device
public void write(byte[] bytes) {
try {
mOutStream.write(bytes);
} catch (IOException e) {
}
}
//termina la connessione
public void cancel() {
try {
mSocket.close();
} catch (IOException e) { }
}
}
private void connected(BluetoothSocket mSocket) {
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(mSocket);
mConnectedThread.start();
mState = STATE_CONNECTED;
}
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) {
return;}
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
public int getState(){
return mState;
}
public String getMessage(){
String tmp = null;
if(!message.equals("")){
tmp = message;
message = "";
}
mState = STATE_CONNECTED;
return tmp;
}
public void setState(int state){
this.mState = state;
}
public void cancel(){
if(mAcceptThread != null) {
mAcceptThread.cancel();
mAcceptThread = null;
}
if(mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if(mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transition);
/* * */
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
/* * */
if(requestCode == DISCOVER_REQUEST){
if(resultCode == 120){
bluetoothService = new BluetoothService(this);
bluetoothService.start();
//after receiving some message correctly
Intent thirdActivity = new Intent(this, com.project.ThirdActivity.class);
bluetoothService.cancel();
this.startActivity(thirdActivity);
finish();
}
if(resultCode == RESULT_CANCELED){
finish();
}
}
}
}
SecondActivity我取消连接的方式与MainActivity几乎相同。我在收到一些消息后关闭了套接字,然后启动ThirdActivity
ThirdActivity
if(mode == CLIENT){
BluetoothDEvice bluetoothDevice = getIntent().getExtras().getParcelable("btdevice");
bluetoothService.startClient(bluetoothDevice,myid);
}else //SERVER
bluetoothService.start();
答案 0 :(得分:0)
可能的解决方案:
以下链接是一个出色的例子: