我正在製作一個Android應用程序(EDIT1:在Nexusus S上的4.0.3上開發),它通過藍牙共享數據P2P,並且已經遇到了令人討厭的障礙兩個設備連接。我們的應用程序使用NFC將一個設備的MAC地址傳遞給另一個設備。然後發件人創建一個BlueToothServer套接字實例並調用accept,而接收方使用它接收到的MAC地址創建一個BluetoothDevice實例並嘗試連接。BluetoothServerSocket.accept()返回未連接的問題BluetoothSocket
我們遇到的問題是從accept()返回的BluetoothSocket。它的文檔明確指出它應該返回一個連接的套接字,但是它會返回一個斷開連接的套接字,即使通過調用connect()也不能連接。我檢查了套接字所具有的MAC地址並將其清除,僅返回accept()就意味着已成功連接足夠長的時間來創建套接字,所以我不知道該嘗試什麼。
還值得一提的是,接收方的BluetoothSocket在此期間聲稱它實際上已連接。顯然,它只是簡單地等待數據永遠不會來自另一臺設備,而是在多個地方使用檢查點,我們知道直到那個時候它總是聲稱被連接。
任何幫助或建議,將不勝感激。
其他相關信息:
的發送者和接收者是相同的應用程序,但代表了不同的活動。這款應用程序是一款遊戲,其中加入遊戲需要有人將遊戲提供給其他人,這是由NFC發起的(最終假設通過藍牙發送的數據是加入遊戲所需的數據)。發送者擁有遊戲並且處於一個活動中,而接收者正在接收活動,然後進入贈送活動,讓他們將其傳遞給其他人。爲了清楚地說明這一點,儘管我們現在可以合併這兩項活動,但我們稍後將使用相同的技術作爲實際遊戲的一部分,因爲它不可能確保兩者都處於開啓狀態同樣的活動,所以我們需要克服不同的活動問題。
我們也確定UUID匹配正確。我們有一個全局類,它帶有一個我們剛剛在某個點生成並使用的常量UUID。根據你的目的,UUID在某些情況下需要是特定的東西,但是我也理解它,因爲這種特殊用途,我們假設要產生我們自己的。
BluetoothServerSocket創建並接受()作爲NdefPushbackComplete的回調的一部分調用,因此另一部手機在發件人開始設置其服務器套接字之前肯定具有Ndef消息。
客戶端或服務器的藍牙代碼都不在線上運行,因爲我們希望交換完全發生在任何一方都可以做任何事情之前。
如果我忽略提及任何重要的東西,我會很樂意提供它。最後,這裏是客戶端和服務器端代碼。它的這個版本使用了一個不安全的套接字,但是我已經嘗試了這兩種方法,並且用於測試的手機已經配對。
客戶:
String s = new String(msg.getRecords()[0].getPayload());
otherBluetoothMACAddress = s;
Log.d(DEV, "WaitingToGetGame: Other BT Address... "
+ otherBluetoothMACAddress);
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
Log.d(DEV, "WaitingToGetGame: Getting remote device");
BluetoothDevice bluetoothDevice = bluetoothAdapter
.getRemoteDevice(otherBluetoothMACAddress);
ObjectInputStream objectInputStream;
ObjectOutputStream objectOutputStream;
try
{
Log.d(DEV, "WaitingToGetGame: Getting BluetoothSocket");
bluetoothSocket = bluetoothDevice
.createInsecureRfcommSocketToServiceRecord(SDP_UUID);
Log.d(DEV, "WaitingToGetGame: Connecting...");
bluetoothSocket.connect();
Log.d(DEV,
"WaitingToGetGame: Bluetooth "
+ ((bluetoothSocket.isConnected()) ? ("is ") : ("is NOT "))
+ "Connected.");
Log.d(DEV, "WaitingToGetGame: Getting input stream");
bluetoothInputStream = bluetoothSocket.getInputStream();
Log.d(DEV,
"WaitingToGetGame: Bluetooth "
+ ((bluetoothSocket.isConnected()) ? ("is ") : ("is NOT "))
+ "Connected.");
Log.d(DEV, "WaitingToGetGame: Getting output stream");
bluetoothOutputStream = bluetoothSocket.getOutputStream();
Log.d(DEV,
"WaitingToGetGame: Bluetooth "
+ ((bluetoothSocket.isConnected()) ? ("is ") : ("is NOT "))
+ "Connected.");
objectInputStream = new ObjectInputStream(bluetoothInputStream);
objectOutputStream = new ObjectOutputStream(bluetoothOutputStream);
Log.d(DEV, this.getClass().getSimpleName() + ": Receiving game data");
game = (Game) objectInputStream.readObject();
Log.d(DEV, this.getClass().getSimpleName() + ": Sending acknowledgment.");
objectOutputStream.writeObject(new Boolean(true));
objectInputStream.close();
objectOutputStream.close();
bluetoothInputStream.close();
bluetoothOutputStream.close();
bluetoothInputStream = null; // GC
bluetoothOutputStream = null; // GC
bluetoothSocket.close();
bluetoothSocket = null;
服務器:
BluetoothServerSocket bluetoothServerSocket = null;
ObjectInputStream objectInputStream;
ObjectOutputStream objectOutputStream;
try
{
Log.d(DEV, this.getClass().getSimpleName()
+ ": Getting BluetoothServerSocket");
// bluetoothServerSocket = bluetoothAdapter
// .listenUsingRfcommWithServiceRecord(user.getName(), SDP_UUID);
bluetoothServerSocket = bluetoothAdapter
.listenUsingInsecureRfcommWithServiceRecord(user.getName(), SDP_UUID);
Log.d(DEV, this.getClass().getSimpleName() + ": Waiting for connection.");
bluetoothSocket = bluetoothServerSocket.accept();
bluetoothServerSocket.close();
BluetoothDevice dev = bluetoothSocket.getRemoteDevice();
Log.d(DEV, dev.getAddress());
Log.d(DEV, this.getClass().getSimpleName() + ": Bluetooth "
+ ((bluetoothSocket.isConnected()) ? ("is ") : ("is NOT "))
+ "Connected.");
// At this point bluetoothSocket should be ready to use.
Log.d(DEV, this.getClass().getSimpleName() + ": Getting input stream");
bluetoothInputStream = bluetoothSocket.getInputStream();
Log.d(DEV, this.getClass().getSimpleName() + ": Bluetooth "
+ ((bluetoothSocket.isConnected()) ? ("is ") : ("is NOT "))
+ "Connected.");
Log.d(DEV, this.getClass().getSimpleName() + ": Getting output stream");
bluetoothOutputStream = bluetoothSocket.getOutputStream();
// Log.d(DEV, this.getClass().getSimpleName()
// + ": Attempting direct connect()");
// bluetoothSocket.connect();
objectInputStream = new ObjectInputStream(bluetoothInputStream);
objectOutputStream = new ObjectOutputStream(bluetoothOutputStream);
Log.d(DEV, this.getClass().getSimpleName() + ": Sending game data.");
objectOutputStream.writeObject(game);
Log.d(DEV, this.getClass().getSimpleName() + ": Waiting for response.");
Boolean response = (Boolean) objectInputStream.readObject();
objectInputStream.close();
objectOutputStream.close();
bluetoothInputStream.close();
bluetoothOutputStream.close();
bluetoothInputStream = null; // GC
bluetoothOutputStream = null; // GC
bluetoothSocket.close();
bluetoothSocket = null;
}// try
catch(IOException e)
{
Log.d(
DEV,
this.getClass().getSimpleName() + ": "
+ java.util.Arrays.toString(e.getStackTrace()));
e.printStackTrace();
return;
}
catch(ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
歡迎來到StackOverflow!寫得很好的問題。您正在測試什麼類型的手機(製造商,型號,Android版本等)? – Jack
好,謝謝!我們正在使用Nexus S上運行的Android 4.0.3。我將編輯它。 –
嘗試連接(在兩個設備上)時,您是否在BondState更改過程中查看過LogCat?它會給出錯誤嗎? – Jack