蓝牙配对设备连接问题

3

我在连接方面遇到了问题。起初它可以工作,然后就不能工作,除非我取消配对设备。我已经遇到了可能发生的所有异常,例如套接字关闭、管道关闭、连接被拒绝、端口已被使用等。

我知道 Android 4.2 之前的版本存在蓝牙问题(https://code.google.com/p/android/issues/detail?id=37725)。

我遇到连接问题的设备有:

  • Htc one(Android 4.2)
  • Samsung Galaxy S2(Android 4.1.2)
  • Nexus 4(4.3)
  • Samsung Galaxy S4(4.2)

另一个小问题是,配对设备没有被存储(主要出现在 Nexus 4 和 SGS2 上)。

以下是我的代码:

private static final UUID MY_UUID_SECURE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //this is the other one that I've tried: fa87c0d0-afac-11de-8a39-0800200c9a66");

private static final String NAME = "BluetoothConnector";

public void listenForConnection() throws IOException, BluetoothException {
//first close the socket if it is open
closeSocket();

BluetoothServerSocket mServerSocket = null;
try {
    mServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID_SECURE); //ioexception here!         
} catch (IOException e) {
    if (Build.VERSION.SDK_INT >= 9) {
        try { //this is a stupid hack, http://stackoverflow.com/questions/6480480/rfcomm-connection-between-two-android-devices
            Method m = mBluetoothAdapter.getClass().getMethod("listenUsingRfcommOn", new Class[] { int.class });
            mServerSocket = (BluetoothServerSocket) m.invoke(mBluetoothAdapter, PORT);
        } catch (Exception ex) {
            Log.e(ex);
            throw e;
        }
    } else {
        throw e;
    }
}

while (!isCancelled) {
    try {
        socket = mServerSocket.accept();
    } catch (IOException e) {
        if (socket != null) {
            try {
                socket.close();
            } finally {
                socket = null;
            }
        }
        throw e;
    }

    if (socket == null) {
        throw new BluetoothException("Socket connection connected, but null");
    } else {
        isConnected = true;
        break; // everything is ok
    }
}
}



public void connect(String address) throws IOException, BluetoothException {
mBluetoothAdapter.cancelDiscovery();

BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);

try {
    socket = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
} catch (IOException e1) {
    Log.e(e1);

    if (Build.VERSION.SDK_INT >= 9) {
        try {
            Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
            socket = (BluetoothSocket) m.invoke(device, PORT);
        } catch (Exception e) {
            Log.e(e);
            throw e1;
        }
    } else {
        throw e1;
    }
}

// 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();
} catch (IOException e) {
    Log.e(e);
    // Close the socket
    try {
        socket.close();
    } catch (IOException e2) {
        Log.e(e2);
        Log.wtf("unable to close() socket during connection failure");
    }
    throw e;
}

}

private void closeSocket() {
    try {
        if (socket != null) {
            socket.close();
            socket = null;
            Log.d("Socket closed");
        }
    } catch (IOException e) {
        Log.e(e);
        Log.wtf("close() of connect socket failed");
    }
}

我尝试更改UUID(随机的),尝试查看旧的SDK示例。那么问题可能出在哪里?
编辑:为了澄清:通常,在已配对、连接并进行了一些成功通信的两个设备被用户断开连接后,问题就会出现。之后,除非重新启动或手动取消配对,否则它们无法重新连接。
2个回答

1
你正在尝试以这种方式进行配对:
private void TwitPairedDevice() {
    buttonTwitPairDevice.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Set<BluetoothDevice> fetchPairedDevices=bluetooth.getBondedDevices();
            Iterator<BluetoothDevice> iterator=fetchPairedDevices.iterator();
            while(iterator.hasNext())
            {
                final BluetoothDevice pairBthDevice=iterator.next();
                final String addressPairedDevice=pairBthDevice.getAddress();
                AsyncTask<Integer, Void, Void> asynchPairDevice=new AsyncTask<Integer, Void, Void>() {

                    @Override
                    protected Void doInBackground(Integer... params) {
                        try {
                            socket=pairBthDevice.createRfcommSocketToServiceRecord(uuid);
                            socket.connect();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        return null;
                    }

                    }
                };asynchPairDevice.execute();
            }
        }
    });
}

连接已配对设备:
    private void FetchPairedDevices() {
        Set<BluetoothDevice> pairedDevices=bluetooth.getBondedDevices();
        for(BluetoothDevice pairedBthDevice:pairedDevices)
        {
            listPairedDevice.add(pairedBthDevice.getName());
        }
        listviewPairedDevice.setAdapter(adapterPairedDevice);
        listviewPairedDevice.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {
                Object listPairedName=arg0.getItemAtPosition(arg2);
                String selectedPairedName=listPairedName.toString();
                Set<BluetoothDevice> bthDeviceChecking=bluetooth.getBondedDevices();
                for(final BluetoothDevice bthDevice:bthDeviceChecking)
                {
                    if(bthDevice.getName().contains(selectedPairedName))
                    {
                        listPairDevice.clear();
                        listPairDevice.add(bthDevice);
                        final String addressPairedDevice=bthDevice.getAddress();
                        AsyncTask<Integer, Void, Void> asynTask=new AsyncTask<Integer,Void,Void>() {
                            @Override
                            protected Void doInBackground(Integer... params) {
                                try {
                                    socket=bthDevice.createRfcommSocketToServiceRecord(uuid);
                                    socket.connect();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                                return null;
                            }
};
                        asynTask.execute(arg2);
                    }
                }
            }
        });
    }

在我的情况下,遍历所有可用的配对设备是没有意义的。我希望用户连接到特定的设备。 - Tamas
你将在列表视图中显示已配对的设备,然后点击你想要配对的设备...我发布了一些连接已配对设备的代码,请查看。 - Satheesh

1

目前看来,安卓系统的蓝牙功能存在问题。

没有一种可靠的连接两个设备的方法能够始终有效。有些人使用非官方方法进行连接,但这并不适用于所有设备。

我们进行了一些内部测试,测试了市场上排名前十的设备,大约进行了90次测试,但是这种黑客方法只有75%的成功率,这已经不能满足需求。

例如,htc oneX只能作为蓝牙免提设备处理传入的蓝牙请求(成功连接!),但无法进行消息传输。

在实现完整的蓝牙功能后,我们决定将其从应用程序中删除,并在没有蓝牙功能的情况下发布应用程序。我们将在以后的版本中转向wifi。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接