5

Bluetooth経由で1つのデバイスに接続できるようにするには、2つ以上のデバイスが必要なAndroidアプリケーションを実行しています。2 つのデバイスをピアツーピア形式で接続するコードは機能しますが、別のデバイスを接続しようとすると、ソケットが閉じられているためペアリングを完了できないため、「接続が拒否されました」という IOException が発生します。エラーを以下に示します。

Socket closed. Unable to complete pairing.
java.io.IOException: Connection refused
    at android.bluetooth.BluetoothSocket.connectNative(Native Method)
    at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:216)
    at com.ablueworld.androidgridcomputingframework.BluetoothManager$ConnectAsyncTask.doInBackground(BluetoothManager.java:270)
    at com.ablueworld.androidgridcomputingframework.BluetoothManager$ConnectAsyncTask.doInBackground(BluetoothManager.java:1)
    at android.os.AsyncTask$2.call(AsyncTask.java:264)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
    at java.lang.Thread.run(Thread.java:856)
Could not connect to this device

その後、接続ごとに異なる UUID が必要であると読みましたが、そうですか? とにかく、以下に示すように、新しい接続ごとに配列から異なる UUID を取得して、コードを記述しました。

    // Unique UUID for this application
    private static int indexUUID = 0;
    private static final UUID[] MY_UUID_SECURE = {UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d168"),
                                                  UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d169"),
                                                  UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d170"),
                                                  UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d171"),
                                                  UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d172")};
    private static final String NAME_SECURE = "GridFrameworkSecure";

    /**
     * Method to connect securely to Bluetooth device using it's MAC address
     * @param macAddress valid Bluetooth MAC address
     */
    public boolean connectSecurelyToDevice(BluetoothAdapter btAdapter, String macAddress){
        BluetoothDevice device = btAdapter.getRemoteDevice(macAddress);
        ConnectAsyncTask connectTask = new ConnectAsyncTask();
        BluetoothSocket deviceSocket = null;
        try {
            deviceSocket = connectTask.execute(device).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        } catch (ExecutionException e) {
            e.printStackTrace();
            return false;
        }
        if(deviceSocket!=null){
            if(serverBluetoothNode==null){
                try {
                    serverBluetoothNode = new BluetoothNode(deviceSocket);
                    Log.i("bluetooth manager", "You are now a slave node.");


                    return true;
                } catch (IOException e) {
                    e.printStackTrace();
                    return false;
                }
            } else {
                Log.e("bluetooth manager", "You already have a master.");
                return false;
            }
        } else return false;
    }

    /**
     * Method to allow this Bluetooth device to accept connection from another Bluetooth device
     */
    public void allowSecureConnectionFromRemoteDevice(BluetoothAdapter btAdapter){
        AcceptConnectionAsyncTask acceptTask = new AcceptConnectionAsyncTask();
        acceptTask.execute(btAdapter);
    }

    private class ConnectAsyncTask extends AsyncTask<BluetoothDevice, Void, BluetoothSocket> {

        @Override
        protected BluetoothSocket doInBackground(BluetoothDevice... params) {
            BluetoothDevice device = params[0];
            BluetoothSocket socket = null;

            // Get a BluetoothSocket for a connection with the
            // given BluetoothDevice
            try {
                socket = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE[indexUUID]);
            } catch (IOException e) {
                Log.e("Bluetooth Pairing", "create() failed", e);
            }

            Log.i("Bluetooth Pairing", "BEGIN ConnectThread SocketType: Secure");

            // Make a connection to the BluetoothSocket
            try {
                // This is a blocking call and will only return on a
                // successful connection or an exception
                socket.connect();
                Log.i("bluetooth manager", "You have connected a slave node to this one.");

                return socket;
            } catch (IOException e) {
                Log.e("Bluetooth Pairing", "Socket closed. Unable to complete pairing.", e);
                // Close the socket
                try {
                    socket.close();
                    indexUUID++;
                } catch (IOException e2) {
                    Log.e("Bluetooth Pairing", "unable to close() socket during connection failure", e2);
                }
            }

            return null;
        }

    }

    private class AcceptConnectionAsyncTask extends AsyncTask<BluetoothAdapter, Void, Void> {

        @Override
        protected Void doInBackground(BluetoothAdapter... params) {
            BluetoothServerSocket serverSocket = null;
            String socketType = "Secure";

            // Create a new listening server socket
            try {
                serverSocket = params[0].listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[indexUUID]);
            } catch (IOException e) {
                Log.e("Accept Bluetooth Pairing Thread", "Socket Type: " + socketType + "listen() failed", e);
                indexUUID++;
            }

            Log.d("Accept Bluetooth Pairing Thread", "Socket Type: " + socketType +
                    "BEGIN mAcceptThread" + this);

            BluetoothSocket socket = null;

            // Listen to the server socket if we're not connected
            while (true) { //mState != STATE_CONNECTED) {
                try {
                    // This is a blocking call and will only return on a
                    // successful connection or an exception
                    socket = serverSocket.accept();
                    Log.i("Slave", "server socket found");                    

                    // If a connection was accepted
                    if (socket != null) {
                        BluetoothNode node = null;
                        try {
                            node = new BluetoothNode(socket);
                            Log.i("connected to", node.getDeviceInformation());
                            slaveBluetoothNodes.add(node);

                            indexUUID++;
                    serverSocket = params[0].listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[indexUUID]);

                        } catch (IOException e) {
                            e.printStackTrace();

                            indexUUID++;
                            serverSocket = params[0].listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[indexUUID]);
                        }
                    }
                } catch (IOException e) {
                    Log.e("Accept Bluetooth Pairing Thread", "Socket Type: " + socketType + "accept() failed", e);

                    try {
                        indexUUID++;
                        serverSocket = params[0].listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[indexUUID]);
                    } catch (IOException e1) {
                        Log.e("Accept Bluetooth Pairing Thread", "Socket Type: " + socketType + "listen() failed", e1);
                    }
                }


            }
        }

    }

しかし、それでも、以下に示すように、2 番目のデバイスへの Bluetooth 接続が既に機能しているモバイルに接続しようとしている 3 番目のモバイルで別のエラーが発生します。

 Socket closed. Unable to complete pairing.
 java.io.IOException: Service discovery failed
    at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:406)
    at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:217)
    at com.ablueworld.androidgridcomputingframework.BluetoothManager$ConnectAsyncTask.doInBackground(BluetoothManager.java:270)
    at com.ablueworld.androidgridcomputingframework.BluetoothManager$ConnectAsyncTask.doInBackground(BluetoothManager.java:1)
    at android.os.AsyncTask$2.call(AsyncTask.java:185)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
    at java.lang.Thread.run(Thread.java:1019)
 Could not connect to this device

誰でもこれを理解するのを助けることができますか? ありがとうございました。

4

2 に答える 2

0

私は自分の問題の解決策を見つけました。

リッスンしてから接続する方法では、次のように記述しました。

UUID[] MY_UUID_SECURE = {UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d168"),
                                                  UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d169"),
                                                  UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d170"),
                                                  UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d171"),
                                                  UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d172")};

BluetoothServerSocket serverSocket = null;
            BluetoothSocket socket = null;

            try {
                // Listen for all UUIDs in array
                for (int i = 0; i < MY_UUID_SECURE.length; i++) {
                    serverSocket = btAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[i]);
                    socket = serverSocket.accept();
                    if (socket != null) {
                        BluetoothNode node = null;
                        node = new BluetoothNode(socket);
                        Log.i("connected to", node.getDeviceInformation());
                        slaveBluetoothNodes.add(node);

                        // add node to database
                        databaseManager.insertToGridTree(node.getDeviceAddress(), "slave", "active", node.getDeviceName());
                    }                       
                }
            } catch (IOException e) {
                Log.e("Accept Bluetooth Pairing Thread", "accept() failed", e);
            }

また、スレーブ デバイスがマスターに接続する方法は次のとおりです。

    BluetoothDevice device = params[0];
    BluetoothSocket socket = null;

    Log.i("Bluetooth Pairing", "BEGIN ConnectThread SocketType: Secure");

    // Get a BluetoothSocket for a connection with the
    // given BluetoothDevice
    for(int i=0; i<MY_UUID_SECURE.length; i++){
        try {
            socket = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE[i]);
            // This is a blocking call and will only return on a
            // successful connection or an exception
            socket.connect();
            Log.i("bluetooth manager", "You have connected a slave node to this one.");

            return socket;
        } catch (IOException e) {
            Log.e("Bluetooth Pairing", "create() failed", e);
            Log.i("Bluetooth Pairing", "trying another UUID");
            try {
                socket.close();
            } catch (IOException e2) {
                Log.e("Bluetooth Pairing", "unable to close() socket during connection failure", e2);
            }
        }
    }

このプロジェクトは、これを理解するのに役立ちました: https://github.com/polyclef/BluetoothChatMulti

これが同じ問題を抱えている人に役立つことを願っています。:)

于 2013-06-05T13:09:19.933 に答える
0

ソケット接続を作成する前に を呼び出しcancelDiscovery()てみてください。BluetoothAdapterこれにより、取得している問題が解決するjava.io.IOException: Service discovery failed場合があります。

于 2013-06-05T09:21:40.900 に答える