2012-03-31 338 views
28

我試圖通過Android開發人員網站上的Android藍牙聊天示例連接兩個設備。它只是從一個設備連接,當我試圖從其他設備連接它不連接,並彈出一條消息「無法連接:[設備名稱在這裏]」無法連接2設備藍牙android

我想知道如果我使用兩個設備上的代碼相同,爲什麼只有一方連接,而另一方拒絕?

我有2個設備 - 1運行版本2.2和1運行v2.3.3。 我的請求總是從我運行2.3.3的Galaxy Y發送到運行Android 2.2的Galaxy fit-v,但反之亦然。任何一個可以請幫我或給我關根據下面的代碼建議...

@Override 
public void onActivityResult(int requestCode, int resultCode, final Intent data) { 

    switch (requestCode) { 
    case REQUEST_CONNECT_DEVICE: 

     // When DeviceListActivity returns with a device to connect 
     if (resultCode == Activity.RESULT_OK) { 
      FaceCardList.requestConnection = true; 
      FaceCardList.deviceSelected = false; 

      address = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);    

      device = FaceCardList.mBluetoothAdapter.getRemoteDevice(address); 

      // Attempt to connect to the device 
      FaceCardList.mChatService.connect(device); 
      // Get the device MAC address 
     } 
     break; 
    case REQUEST_ENABLE_BT: 
     // When the request to enable Bluetooth returns 
     if (resultCode == Activity.RESULT_OK) { 
      // Bluetooth is now enabled, so set up a chat session 
      setupChat(); 
     } else { 
      // User did not enable Bluetooth or an error occured 
      Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show(); 
      finish(); 
     } 
    } 
} 

和我BluetoothChat服務的代碼是:

public class BluetoothChatService extends Activity { 
    private static final String TAG = "BluetoothChatService"; 
    private static final boolean D = true; 
    // Name for the SDP record when creating server socket 
    private static final String NAME = "BluetoothChat"; 
    // Unique UUID for this application 
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 

    // ("fa87c0d0-afac-11de-8a39-0800200c9a66"); 
    // Member fields 
    private final BluetoothAdapter mAdapter; 
    private final Handler mHandler; 
    private AcceptThread mAcceptThread; 
    private ConnectThread mConnectThread; 
    private ConnectedThread mConnectedThread; 
    private int mState; 
    // Constants that indicate the current connection state 
    public static final int STATE_NONE = 0; // we're doing nothing 
    public static final int STATE_LISTEN = 1; // now listening for incoming connections 
    public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection 
    public static final int STATE_CONNECTED = 3; // now connected to a remote device 

    /** 
    * Constructor. Prepares a new BluetoothChat session. 
    * 
    * @param context 
    *   The UI Activity Context 
    * @param handler 
    *   A Handler to send messages back to the UI Activity 
    */ 
    public BluetoothChatService(Context context, Handler handler) { 
     mAdapter = FaceCardList.mBluetoothAdapter; 
     mState = STATE_NONE; 
     mHandler = handler; 
    } 

    /** 
    * Set the current state of the chat connection 
    * 
    * @param state 
    *   An integer defining the current connection state 
    */ 
    private synchronized void setState(int state) { 
     if (D) { 
      //Log.d(TAG, "setState() " + mState + " -> " + state); 
     } 
     mState = state; 

     // Give the new state to the Handler so the UI Activity can update 
     mHandler.obtainMessage(FaceCardList.MESSAGE_STATE_CHANGE, state, -1) 
       .sendToTarget(); 
    } 

    /** 
    * Return the current connection state. 
    */ 
    public synchronized int getState() { 
     return mState; 
    } 

    /** 
    * Start the chat service. Specifically start AcceptThread to begin a 
    * session in listening (server) mode. Called by the Activity onResume() 
    */ 
    public synchronized void start() { 
     if (D) { 
      Log.d(TAG, "start"); 
     } 

     // Cancel any thread attempting to make a connection 
     if (mConnectThread != null) { 
      mConnectThread.cancel(); 
      mConnectThread = null; 
     } 

     // Cancel any thread currently running a connection 
     if (mConnectedThread != null) { 
      mConnectedThread.cancel(); 
      mConnectedThread = null; 
     } 

     // Start the thread to listen on a BluetoothServerSocket 
     if (mAcceptThread == null) { 
      mAcceptThread = new AcceptThread(); 
      mAcceptThread.start(); 
     } 
     setState(STATE_LISTEN); 
    } 

    /** 
    * Start the ConnectThread to initiate a connection to a remote device. 
    * 
    * @param device 
    *   The BluetoothDevice to connect 
    */ 
    public synchronized void connect(BluetoothDevice device) { 
     if (D) { 
      Log.d(TAG, "connect to: " + device);   
     } 

     // Cancel any thread attempting to make a connection 
     if (mState == STATE_CONNECTING) { 
      if (mConnectThread != null) { 
       mConnectThread.cancel(); 
       mConnectThread = null; 
      } 
     } 

     // Cancel any thread currently running a connection 
     if (mConnectedThread != null) { 
      mConnectedThread.cancel(); 
      mConnectedThread = null; 
     } 

     // Start the thread to connect with the given device 
     mConnectThread = new ConnectThread(device); 
     mConnectThread.start(); 
     setState(STATE_CONNECTING); 
    } 

    /** 
    * Start the ConnectedThread to begin managing a Bluetooth connection 
    * 
    * @param socket 
    *   The BluetoothSocket on which the connection was made 
    * @param device 
    *   The BluetoothDevice that has been connected 
    */ 
    public synchronized void connected(BluetoothSocket socket, 
      BluetoothDevice device) { 
     if (D) { 
      Log.d(TAG, "######connected"); 
     } 

     // Cancel the thread that completed the connection 
     if (mConnectThread != null) { 
      mConnectThread.cancel(); 
      mConnectThread = null; 
     } 

     // Cancel any thread currently running a connection 
     if (mConnectedThread != null) { 
      mConnectedThread.cancel(); 
      mConnectedThread = null; 
     } 

     // Cancel the accept thread because we only want to connect to one 
     // device 
     if (mAcceptThread != null) { 
      mAcceptThread.cancel(); 
      mAcceptThread = null; 
     } 

     // Start the thread to manage the connection and perform transmissions 
     mConnectedThread = new ConnectedThread(socket); 
     mConnectedThread.start(); 

     // Send the name of the connected device back to the UI Activity 
     Message msg = mHandler.obtainMessage(FaceCardList.MESSAGE_DEVICE_NAME); 

     Bundle bundle = new Bundle(); 
     bundle.putString(FaceCardList.DEVICE_NAME, device.getName()); 
     msg.setData(bundle); 
     mHandler.sendMessage(msg); 

     setState(STATE_CONNECTED); 
    } 

    /** 
    * Stop all threads 
    */ 
    public synchronized void stop() { 
     if (D) { 
      Log.d(TAG, "stop"); 
     } 
     if (mConnectThread != null) { 
     mConnectThread.cancel(); 
     mConnectThread = null; 
     } 
     if (mConnectedThread != null) { 
      mConnectedThread.cancel(); 
      mConnectedThread = null; 
     } 
     if (mAcceptThread != null) { 
      mAcceptThread.cancel(); 
      mAcceptThread = null; 
     } 
     setState(STATE_NONE); 
    } 

    /** 
    * Write to the ConnectedThread in an unsynchronized manner 
    * 
    * @param out 
    *   The bytes to write 
    * @see ConnectedThread#write(byte[]) 
    */ 
    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); 

    } 

    /** 
    * Indicate that the connection attempt failed and notify the UI Activity. 
    */ 
    private void connectionFailed() { 
     setState(STATE_LISTEN); 

     // Send a failure message back to the Activity 
     Message msg = mHandler.obtainMessage(FaceCardList.MESSAGE_TOAST); 
     Bundle bundle = new Bundle(); 
     bundle.putString(FaceCardList.TOAST, "Unable to connect device"); 
     msg.setData(bundle); 
     mHandler.sendMessage(msg); 
    } 

    /** 
    * Indicate that the connection was lost and notify the UI Activity. 
    */ 
    private void connectionLost() { 
     setState(STATE_LISTEN); 
     // Send a failure message back to the Activity 
     Message msg = mHandler.obtainMessage(FaceCardList.MESSAGE_TOAST); 
     Bundle bundle = new Bundle(); 
     bundle.putString(FaceCardList.TOAST, "Device connection was lost"); 
     msg.setData(bundle); 
     mHandler.sendMessage(msg); 
    } 

    /** 
    * This thread runs while listening for incoming connections. It behaves 
    * like a server-side client. It runs until a connection is accepted (or 
    * until cancelled). 
    */ 
    private class AcceptThread extends Thread { 
     // The local server socket 
     private final BluetoothServerSocket mmServerSocket; 

     public AcceptThread() { 
      BluetoothServerSocket tmp = null; 

      // Create a new listening server socket 
      try { 

       tmp = mAdapter 
         .listenUsingRfcommWithServiceRecord(NAME, MY_UUID); 
//    if(!tmp.toString().equalsIgnoreCase(null)){ 

    //    
     //   } 
      } catch (IOException e) { 
       //Log.e(TAG, "listen() failed", e); 
      } 
      mmServerSocket = tmp; 
     } 

     @Override 
     public void run() { 
      if (D) { 
       Log.d(TAG, "BEGIN mAcceptThread" + this); 
      } 

      setName("AcceptThread"); 
      BluetoothSocket socket = null; 

      // Listen to the server socket if we're not connected 
      while (mState != STATE_CONNECTED) { 


        try { 
         socket = mmServerSocket.accept(); 
        } catch (IOException e1) { 
         // TODO Auto-generated catch block 
         //e1.printStackTrace(); 
        } 


       // If a connection was accepted 
       if (socket != null) { 
        synchronized (BluetoothChatService.this) { 
         switch (mState) { 
         case STATE_LISTEN: 
         case STATE_CONNECTING: 
          // Situation normal. Start the connected thread. 
          connected(socket, socket.getRemoteDevice()); 
          break; 
         case STATE_NONE: 
         case STATE_CONNECTED: 
          // Either not ready or already connected. Terminate 
          // new socket. 
          //Log.e("STATE_CONNECTED: service","STATE_CONNECTED: service"); 

          try { 
           socket.close(); 
          } catch (IOException e) { 
           //Log.e(TAG,"Could not close unwanted socket",            e); 
          } 
          break; 
         } 
        } 
       } 
      } 
      if (D) { 
       //Log.i(TAG, "END mAcceptThread"); 
      } 
     } 

     public void cancel() { 
      if (D) { 
       //Log.d(TAG, "cancel " + this); 
      } 
      try { 
       mmServerSocket.close(); 
      } catch (IOException e) { 
       //Log.e(TAG, "close() of server failed", e); 
      } 
     } 
    } 

    /** 
    * This thread runs while attempting to make an outgoing connection with a 
    * device. It runs straight through; the connection either succeeds or 
    * fails. 
    */ 
     private class ConnectThread extends Thread { 
     private BluetoothSocket mmSocket= null; 

     private final BluetoothDevice mmDevice; 

     public ConnectThread(BluetoothDevice device) { 
      mmDevice = device; 
      BluetoothSocket tmp = null; 

      System.out.println("my uuid :-"+MY_UUID); 
      try { 
       try { 
        //tmp = device.createRfcommSocketToServiceRecord(MY_UUID); 

        mmSocket = device.createRfcommSocketToServiceRecord(MY_UUID); 

        System.out.println("mm socket value :-"+mmSocket); 

       } catch (IOException e) { 
        e.printStackTrace(); 
        System.out.println("error in connecting :-"+e.getMessage()); 
        //Log.e(TAG, "create() failed", e); 

        // TODO Auto-generated catch block 
        //e.printStackTrace(); 
       } 



      } catch (SecurityException e) { 
       // TODO Auto-generated catch block 
       //e.printStackTrace(); 
      } 



     // mmSocket = tmp; 
      System.out.println("mm socket value as temp :-----------------"); 
     } 





      @Override 
      public void run() { 
      //Log.i(TAG, "BEGIN mConnectThread"); 
      setName("ConnectThread"); 

      // Always cancel discovery because it will slow down a connection 
      mAdapter.cancelDiscovery(); 

      // Make a connection to the BluetoothSocket 
      try { 
       // This is a blocking call and will only return on a 
       // successful connection or an exception 
       System.out.println("before connection"); 

       mmSocket.connect(); 
       System.out.println("after connection "); 

      } catch (Exception e) { 
       System.out.println("in connection failed :-"+e.getMessage()); 
       connectionFailed(); 
       // Close the socket 
       try { 
        mmSocket.close(); 
       } catch (IOException e2) { 
        //Log.e(TAG,"unable to close() socket during connection failure",         e2); 
       } 
       // Start the service over to restart listening mode 

       try { 
        BluetoothChatService.this.start(); 
       } catch (Exception e2) { 
        // TODO: handle exception 
        e2.printStackTrace(); 
        System.out.println("in connection failed start bluetooth chat service :-"+e2.getMessage()); 
       } 

       return; 
      } 

      // Reset the ConnectThread because we're done 
      synchronized (BluetoothChatService.this) { 
       mConnectThread = null; 
      } 

      // Start the connected thread 
      connected(mmSocket, mmDevice); 
     } 

     public void cancel() { 
      try { 
       mmSocket.close(); 
      } catch (IOException e) { 
       //Log.e(TAG, "close() of connect socket failed", e); 
      } 
     } 
    } 

    /** 
    * This thread runs during a connection with a remote device. It handles all 
    * incoming and outgoing transmissions. 
    */ 
    private class ConnectedThread extends Thread { 
     private final BluetoothSocket mmSocket; 

     private final InputStream mmInStream; 

     private final OutputStream mmOutStream; 

     public ConnectedThread(BluetoothSocket socket) { 
      //Log.d(TAG, "create ConnectedThread"); 
      mmSocket = socket; 
      InputStream tmpIn = null; 
      OutputStream tmpOut = null; 

      // Get the BluetoothSocket input and output streams 
      try { 
       tmpIn = socket.getInputStream(); 
       tmpOut = socket.getOutputStream(); 
      } catch (IOException e) { 
       //Log.e(TAG, "temp sockets not created", e); 
      } 

      mmInStream = tmpIn; 
      mmOutStream = tmpOut; 
     } 

     @Override 
     public void run() { 
      //Log.i(TAG, "BEGIN mConnectedThread"); 
      byte[] buffer = new byte[1024]; 
      int bytes; 

      // Keep listening to the InputStream while connected                                               
      while (true) { 
       try { 
        // Read from the InputStream\ 


        bytes = mmInStream.read(buffer); 

        // Send the obtained bytes to the UI Activity 

        // XXX !!! 
        String buffer2 = new String(buffer); 
        buffer2= buffer2.substring(0, buffer2.length()-3)+"\n"; 

        mHandler.obtainMessage(FaceCardList.MESSAGE_READ, bytes, -1, buffer2.getBytes()).sendToTarget(); 

       } catch (IOException e) { 
        //Log.e(TAG, "disconnected", e); 
        connectionLost(); 
        break; 
       } 
      } 
     } 

     /** 
     * Write to the connected OutStream. 
     * 
     * @param buffer 
     *   The bytes to write 
     */ 
     public void write(byte[] buffer) { 
      try { 
       mmOutStream.write(buffer); 
       // Share the sent message back to the UI Activity 

       // XXX !!! 
       String buffer2 = new String(buffer); 
       buffer2= buffer2.substring(0, buffer2.length()-2); 
       mHandler.obtainMessage(FaceCardList.MESSAGE_WRITE, -1, -1, 
         buffer2.getBytes()).sendToTarget(); 

      } catch (IOException e) { 
       //Log.e(TAG, "Exception during write", e); 
      } 
     } 

     public void cancel() { 
      try { 
       mmSocket.close(); 
      } catch (IOException e) { 
       //Log.e(TAG, "close() of connect socket failed", e); 
      } 
     } 
    } 
} 

我卡住了。爲什麼連接總是從較高版本變爲較低版本,而不是從較低版本變爲較高版本?

+1

你得到解決? – Venkat 2012-04-03 03:29:32

+0

nops?.......... :( – SRam 2012-04-05 09:11:29

+2

我剛剛提供了一個關於這個問題的賞金,因爲我在過去遇到過藍牙問題,似乎很多麻煩來自於硬件,UUID的選擇等等,而不是實際的代碼,並且在StackOverflow上沒有太多的答案能幫助我。如果你不介意清理你的代碼(正確地縮進它等等,那會是很棒(如果你的代碼是可讀的,它會吸引更多的人) – 2012-05-22 13:55:19

回答

1

我不確定是否直接複製代碼並嘗試運行它,如果是的話,請記住android.app.ActionBar;需要3.0版本。此外,藍牙通信並不完全是點對點的主從。

1

我也認爲你的問題不在你的代碼中。

兩年前,我修改了BluetoothChat示例應用程序。你可以在這裏找到修改後的項目 - Bluetooth Chat和這裏的二進制文件:Bluetooth Chat

如果這兩個設備之間的工作更好,它可能會有所幫助。

我剛剛在Android版本2.3.3(Nexus One)和版本4.0.4(Galaxy Nexus)上測試了它。

5

我已經這樣做了,而且我認爲當設備發現更改時會丟失連接。請檢查兩種設備均可發現,您可以通過代碼啓用設備。

Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); 
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,0); 
startActivity(discoverableIntent); 
2

SAURABH,使這一變化,請和觀看它的工作:

   if (Build.VERSION.SDK_INT < 9) { // VK: Build.Version_Codes.GINGERBREAD is not accessible yet so using raw int value 
       // VK: 9 is the API Level integer value for Gingerbread 
       try { 
        tmp = device.createRfcommSocketToServiceRecord(MY_UUID); 
       } catch (IOException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 
      } else { 
       Method m = null; 
       try { 
        m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class }); 
       } catch (NoSuchMethodException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       try { 
        tmp = (BluetoothSocket) m.invoke(device, (UUID) MY_UUID); 
       } catch (IllegalAccessException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (InvocationTargetException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }