2013-10-06 241 views
22

我想創建一個遊戲,您必須通過藍牙將多個設備(4+)連接到主設備(例如平板電腦)。將會有兩個應用程序,一個主要的應用程序,所有數據將從手機發送到手機。 這甚至可能嗎?通過藍牙將多個設備連接到一個設備

+0

您是否能夠正常工作? – Jake

+0

是的這是可能的,這個庫:https://github.com/arissa34/Android-Multi-Bluetooth-Library – Rami

回答

-1

這是部分可能的(對於最多2個設備),因爲設備只能同時連接到另一個設備。在你的情況下更好的解決方案將創建一個TCP服務器,它將信息發送到其他設備 - 但這當然需要互聯網連接。另請參閱三星Chord API - 它提供了您需要的功能,但是每個設備都必須連接到同一個Wi-Fi網絡

15

是的,這是可能的。在最低級別,藍牙允許您將最多7個設備連接到一個主設備。我已經做到了這一點,它對我來說效果很好,但是隻在其他平臺(linux)上有很多手動控制 - 我從來沒有在Android上嘗試過,並且有一些可能的複雜因素,所以您需要進行一些測試待確認。

其中一個問題是,你需要平板電腦的主人,Android不給你任何明確的控制。這很可能不會成爲問題,因爲 *平板電腦將在您嘗試連接第二臺設備時自動成爲主設備,或者您可以通過設置方式控制主/從角色你的套接字連接

雖然大多數在移動設備上使用藍牙的應用都不會嘗試多次同時連接,並且藍牙可能有點脆弱,例如如果兩個設備已經爲其他應用程序建立了藍牙連接,那麼該怎麼影響角色呢?

-1

我不認爲這是可能的藍牙,但你可以嘗試尋找WiFi Peer-to-Peer,
它允許一對多的連接。

+0

它不需要路由器會在附近,對不對?有足夠的Android設備? –

+0

AFAIK你不需要路由器。我認爲它會將其中一個設備變成一個熱點(沒有互聯網訪問,當然),並讓其他設備連接到它。 – Andreas

+0

爲什麼它會禁用正常的WiFi? –

5

藍牙4.0允許你在一個藍牙微微網中,一個主站可以傳送多達7個活動的從站,可以有一些其他設備多達248個設備正在休眠。

此外,您可以使用一些奴隸作爲橋樑參與更多的設備。

2

是的,你可以這樣做,我創建了a library爲相同。
這允許您將最多四個設備連接到主服務器設備,爲每個客戶端創建不同的通道並在不同線程上運行交互。
要使用此庫,請簡單地在您的build.gradl e的依賴部分中添加編譯com.mdg.androble:library:0.1.2

0

這是建立連接並收到消息的類。 確保在運行應用程序之前配對設備。 如果您想要有一個從站/主站連接,其中每個從站只能將消息發送給主站,並且主站可以將消息廣播到所有從站。 您應該只將主機與每個從機配對,但不應將從機配對在一起。

package com.example.gaby.coordinatorv1; 
    import java.io.DataInputStream; 
    import java.io.IOException; 
    import java.io.InputStream; 
    import java.io.OutputStream; 
    import java.util.ArrayList; 
    import java.util.HashMap; 
    import java.util.Set; 
    import java.util.UUID; 
    import android.bluetooth.BluetoothAdapter; 
    import android.bluetooth.BluetoothDevice; 
    import android.bluetooth.BluetoothServerSocket; 
    import android.bluetooth.BluetoothSocket; 
    import android.content.Context; 
    import android.os.Bundle; 
    import android.os.Handler; 
    import android.os.Message; 
    import android.util.Log; 
    import android.widget.Toast; 

    public class Piconet { 


     private final static String TAG = Piconet.class.getSimpleName(); 

     // Name for the SDP record when creating server socket 
     private static final String PICONET = "ANDROID_PICONET_BLUETOOTH"; 

     private final BluetoothAdapter mBluetoothAdapter; 

     // String: device address 
     // BluetoothSocket: socket that represent a bluetooth connection 
     private HashMap<String, BluetoothSocket> mBtSockets; 

     // String: device address 
     // Thread: thread for connection 
     private HashMap<String, Thread> mBtConnectionThreads; 

     private ArrayList<UUID> mUuidList; 

     private ArrayList<String> mBtDeviceAddresses; 

     private Context context; 


     private Handler handler = new Handler() { 
      public void handleMessage(Message msg) { 
       switch (msg.what) { 
        case 1: 
         Toast.makeText(context, msg.getData().getString("msg"), Toast.LENGTH_SHORT).show(); 
         break; 
        default: 
         break; 
       } 
      }; 
     }; 

     public Piconet(Context context) { 
      this.context = context; 

      mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 

      mBtSockets = new HashMap<String, BluetoothSocket>(); 
      mBtConnectionThreads = new HashMap<String, Thread>(); 
      mUuidList = new ArrayList<UUID>(); 
      mBtDeviceAddresses = new ArrayList<String>(); 

      // Allow up to 7 devices to connect to the server 
      mUuidList.add(UUID.fromString("a60f35f0-b93a-11de-8a39-08002009c666")); 
      mUuidList.add(UUID.fromString("54d1cc90-1169-11e2-892e-0800200c9a66")); 
      mUuidList.add(UUID.fromString("6acffcb0-1169-11e2-892e-0800200c9a66")); 
      mUuidList.add(UUID.fromString("7b977d20-1169-11e2-892e-0800200c9a66")); 
      mUuidList.add(UUID.fromString("815473d0-1169-11e2-892e-0800200c9a66")); 
      mUuidList.add(UUID.fromString("503c7434-bc23-11de-8a39-0800200c9a66")); 
      mUuidList.add(UUID.fromString("503c7435-bc23-11de-8a39-0800200c9a66")); 

      Thread connectionProvider = new Thread(new ConnectionProvider()); 
      connectionProvider.start(); 

     } 



     public void startPiconet() { 
      Log.d(TAG, " -- Looking devices -- "); 
      // The devices must be already paired 
      Set<BluetoothDevice> pairedDevices = mBluetoothAdapter 
        .getBondedDevices(); 
      if (pairedDevices.size() > 0) { 
       for (BluetoothDevice device : pairedDevices) { 
        // X , Y and Z are the Bluetooth name (ID) for each device you want to connect to 
        if (device != null && (device.getName().equalsIgnoreCase("X") || device.getName().equalsIgnoreCase("Y") 
          || device.getName().equalsIgnoreCase("Z") || device.getName().equalsIgnoreCase("M"))) { 
         Log.d(TAG, " -- Device " + device.getName() + " found --"); 
         BluetoothDevice remoteDevice = mBluetoothAdapter 
           .getRemoteDevice(device.getAddress()); 
         connect(remoteDevice); 
        } 
       } 
      } else { 
       Toast.makeText(context, "No paired devices", Toast.LENGTH_SHORT).show(); 
      } 
     } 

     private class ConnectionProvider implements Runnable { 
      @Override 
      public void run() { 
       try { 
        for (int i=0; i<mUuidList.size(); i++) { 
         BluetoothServerSocket myServerSocket = mBluetoothAdapter 
           .listenUsingRfcommWithServiceRecord(PICONET, mUuidList.get(i)); 
         Log.d(TAG, " ** Opened connection for uuid " + i + " ** "); 

         // This is a blocking call and will only return on a 
         // successful connection or an exception 
         Log.d(TAG, " ** Waiting connection for socket " + i + " ** "); 
         BluetoothSocket myBTsocket = myServerSocket.accept(); 
         Log.d(TAG, " ** Socket accept for uuid " + i + " ** "); 
         try { 
          // Close the socket now that the 
          // connection has been made. 
          myServerSocket.close(); 
         } catch (IOException e) { 
          Log.e(TAG, " ** IOException when trying to close serverSocket ** "); 
         } 

         if (myBTsocket != null) { 
          String address = myBTsocket.getRemoteDevice().getAddress(); 

          mBtSockets.put(address, myBTsocket); 
          mBtDeviceAddresses.add(address); 

          Thread mBtConnectionThread = new Thread(new BluetoohConnection(myBTsocket)); 
          mBtConnectionThread.start(); 

          Log.i(TAG," ** Adding " + address + " in mBtDeviceAddresses ** "); 
          mBtConnectionThreads.put(address, mBtConnectionThread); 
         } else { 
          Log.e(TAG, " ** Can't establish connection ** "); 
         } 
        } 
       } catch (IOException e) { 
        Log.e(TAG, " ** IOException in ConnectionService:ConnectionProvider ** ", e); 
       } 
      } 
     } 

     private class BluetoohConnection implements Runnable { 
      private String address; 

      private final InputStream mmInStream; 

      public BluetoohConnection(BluetoothSocket btSocket) { 

       InputStream tmpIn = null; 

       try { 
        tmpIn = new DataInputStream(btSocket.getInputStream()); 
       } catch (IOException e) { 
        Log.e(TAG, " ** IOException on create InputStream object ** ", e); 
       } 
       mmInStream = tmpIn; 
      } 
      @Override 
      public void run() { 
       byte[] buffer = new byte[1]; 
       String message = ""; 
       while (true) { 

        try { 
         int readByte = mmInStream.read(); 
         if (readByte == -1) { 
          Log.e(TAG, "Discarting message: " + message); 
          message = ""; 
          continue; 
         } 
         buffer[0] = (byte) readByte; 

         if (readByte == 0) { // see terminateFlag on write method 
          onReceive(message); 
          message = ""; 
         } else { // a message has been recieved 
          message += new String(buffer, 0, 1); 
         } 
        } catch (IOException e) { 
         Log.e(TAG, " ** disconnected ** ", e); 
        } 

        mBtDeviceAddresses.remove(address); 
        mBtSockets.remove(address); 
        mBtConnectionThreads.remove(address); 
       } 
      } 
     } 

     /** 
     * @param receiveMessage 
     */ 
     private void onReceive(String receiveMessage) { 
      if (receiveMessage != null && receiveMessage.length() > 0) { 
       Log.i(TAG, " $$$$ " + receiveMessage + " $$$$ "); 
       Bundle bundle = new Bundle(); 
       bundle.putString("msg", receiveMessage); 
       Message message = new Message(); 
       message.what = 1; 
       message.setData(bundle); 
       handler.sendMessage(message); 
      } 
     } 

     /** 
     * @param device 
     * @param uuidToTry 
     * @return 
     */ 
     private BluetoothSocket getConnectedSocket(BluetoothDevice device, UUID uuidToTry) { 
      BluetoothSocket myBtSocket; 
      try { 
       myBtSocket = device.createRfcommSocketToServiceRecord(uuidToTry); 
       myBtSocket.connect(); 
       return myBtSocket; 
      } catch (IOException e) { 
       Log.e(TAG, "IOException in getConnectedSocket", e); 
      } 
      return null; 
     } 

     private void connect(BluetoothDevice device) { 
      BluetoothSocket myBtSocket = null; 
      String address = device.getAddress(); 
      BluetoothDevice remoteDevice = mBluetoothAdapter.getRemoteDevice(address); 
      // Try to get connection through all uuids available 
      for (int i = 0; i < mUuidList.size() && myBtSocket == null; i++) { 
       // Try to get the socket 2 times for each uuid of the list 
       for (int j = 0; j < 2 && myBtSocket == null; j++) { 
        Log.d(TAG, " ** Trying connection..." + j + " with " + device.getName() + ", uuid " + i + "...** "); 
        myBtSocket = getConnectedSocket(remoteDevice, mUuidList.get(i)); 
        if (myBtSocket == null) { 
         try { 
          Thread.sleep(200); 
         } catch (InterruptedException e) { 
          Log.e(TAG, "InterruptedException in connect", e); 
         } 
        } 
       } 
      } 
      if (myBtSocket == null) { 
       Log.e(TAG, " ** Could not connect ** "); 
       return; 
      } 
      Log.d(TAG, " ** Connection established with " + device.getName() +"! ** "); 
      mBtSockets.put(address, myBtSocket); 
      mBtDeviceAddresses.add(address); 
      Thread mBluetoohConnectionThread = new Thread(new BluetoohConnection(myBtSocket)); 
      mBluetoohConnectionThread.start(); 
      mBtConnectionThreads.put(address, mBluetoohConnectionThread); 

     } 

     public void bluetoothBroadcastMessage(String message) { 
      //send message to all except Id 
      for (int i = 0; i < mBtDeviceAddresses.size(); i++) { 
       sendMessage(mBtDeviceAddresses.get(i), message); 
      } 
     } 

     private void sendMessage(String destination, String message) { 
      BluetoothSocket myBsock = mBtSockets.get(destination); 
      if (myBsock != null) { 
       try { 
        OutputStream outStream = myBsock.getOutputStream(); 
        final int pieceSize = 16; 
        for (int i = 0; i < message.length(); i += pieceSize) { 
         byte[] send = message.substring(i, 
           Math.min(message.length(), i + pieceSize)).getBytes(); 
         outStream.write(send); 
        } 
        // we put at the end of message a character to sinalize that message 
        // was finished 
        byte[] terminateFlag = new byte[1]; 
        terminateFlag[0] = 0; // ascii table value NULL (code 0) 
        outStream.write(new byte[1]); 
       } catch (IOException e) { 
        Log.d(TAG, "line 278", e); 
       } 
      } 
     } 

    } 

您的主要活動應爲:

package com.example.gaby.coordinatorv1; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 

public class MainActivity extends Activity { 

    private Button discoveryButton; 
    private Button messageButton; 

    private Piconet piconet; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     piconet = new Piconet(getApplicationContext()); 

     messageButton = (Button) findViewById(R.id.messageButton); 
     messageButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       piconet.bluetoothBroadcastMessage("Hello World---*Gaby Bou Tayeh*"); 
      } 
     }); 

     discoveryButton = (Button) findViewById(R.id.discoveryButton); 
     discoveryButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       piconet.startPiconet(); 
      } 
     }); 

    } 

} 

而這裏的XML佈局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context=".MainActivity" > 

<Button 
    android:id="@+id/discoveryButton" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Discover" 
    /> 

<Button 
    android:id="@+id/messageButton" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Send message" 
    /> 

不要忘了下列權限添加到您的清單文件:

<uses-permission android:name="android.permission.BLUETOOTH" /> 
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 
0

我認爲它可能提供,如果它是一個串行數據在廣播方法。但您將無法將任何語音/音頻數據傳輸到其他從屬設備。按照藍牙4.0,協議不支持這一點。然而,廣播音頻/語音數據正在改進。

相關問題