Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Android上使用蓝牙服务发现失败异常_Java_Android_Bluetooth - Fatal编程技术网

Java 在Android上使用蓝牙服务发现失败异常

Java 在Android上使用蓝牙服务发现失败异常,java,android,bluetooth,Java,Android,Bluetooth,我目前正在开发一个Android应用程序,它通过蓝牙连接到一台仪器,需要编写字符串命令并接收字符串响应。目前,我的connect/read/write正在通过Wi-Fi为TCP/IP工作,现在正在尝试实现蓝牙。但我遇到了一些障碍。我一直在网上搜索,试图找到类似的例子,但没有任何运气。我一直在使用Android开发者资源示例:蓝牙聊天作为我的主要参考点 我当前的代码似乎有效。。然后在连接点抛出服务发现失败异常。我正在使用DeviceListActivity类查找和选择要连接的设备。它返回一个Act

我目前正在开发一个Android应用程序,它通过蓝牙连接到一台仪器,需要编写字符串命令并接收字符串响应。目前,我的connect/read/write正在通过Wi-Fi为TCP/IP工作,现在正在尝试实现蓝牙。但我遇到了一些障碍。我一直在网上搜索,试图找到类似的例子,但没有任何运气。我一直在使用Android开发者资源示例:蓝牙聊天作为我的主要参考点

我当前的代码似乎有效。。然后在连接点抛出服务发现失败异常。我正在使用
DeviceListActivity
类查找和选择要连接的设备。它返回一个ActivityResult,然后我的Bluetooth类等待它处理它,然后连接到它。下面的代码与蓝牙聊天应用程序几乎相同

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(!m_BluetoothAdapter.isEnabled())
    {
        m_BluetoothAdapter.enable();
    }
    switch (requestCode) {
        case REQUEST_CONNECT_DEVICE:
            // When DeviceListActivity returns with a device to connect
            if (resultCode == Activity.RESULT_OK) {
                // Get the device MAC address
                String address = data.getExtras()
                                     .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
                // Get the BLuetoothDevice object
                BluetoothDevice device = m_BluetoothAdapter.getRemoteDevice(address);
                // Attempt to connect to the device
                connect(device);
            }
            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
            }
            else {
                // User did not enable Bluetooth or an error occured

                Toast.makeText(this, "Bluetooth not enabled", Toast.LENGTH_SHORT).show();
                finish();
            }
    }
}
这是我的连接功能:

private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

private void connect(BluetoothDevice device) {
    m_Device = device;
    BluetoothSocket tmp = null;

    // Get a BluetoothSocket for a connection with the
    // given BluetoothDevice
    try {
        tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
    }
    catch (IOException e) {

    }
    m_Socket = tmp;

    m_BluetoothAdapter.cancelDiscovery();

    try {
        // This is a blocking call and will only return on a
        // successful connection or an exception
        m_Socket.connect();
    }
    catch (IOException e) {
        try {
            m_Socket.close();
        }
        catch (IOException e2) {
        }
        return;
    }
}
我希望,无论我做错什么都很简单,但恐怕从来没有那么容易。这是我第一次做蓝牙开发,也许我做错了什么。。。但我不确定为什么会出现服务发现失败异常


您可以随时在手机上手动配对/查找设备。。。它确实需要密码,但我不认为这是我遇到的问题。

三天后,由于一些非常有用的帖子,我把它弄明白了

我必须替换:

tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
与:

Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
         tmp = (BluetoothSocket) m.invoke(device, 1);
瞧,它起作用了

这是试图回答接受的答案

您的前后代码之间的一大区别是您传递的UUID。我在这里找到了答案:

我必须替换:

tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
与:

瞧,它起作用了!
原始代码是针对点对点android应用程序的。当连接到简单的串行蓝牙设备时,使用应用程序UUID毫无意义。这就是发现失败的原因。

从API 15开始,您可以使用以下方法:

尝试用
BluetoothDevice
类的()方法的返回值替换UUID。 对我起作用的是这样的:

UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
这样做的原因是,不同的设备支持不同的UUID,通过使用获取设备的UUID,您就支持了所有功能和设备


另一个有趣的新方法(从API 14开始支持)是:。还没有尝试过,但看起来很有希望…

因此,正如上面提到的,关键是您需要使用服务器正在等待的UUID

如果您正在连接蓝牙设备,如耳机或鼠标,则需要检查设备正在侦听的UUID。您可以看到这样的UUID

UUID[] uuids = bluetoothDevice.getUuids();

如果您想知道这些UUID是什么意思,请参见。

这是一个非常古老的问题,但我发现使用
CreateSecurerCommsocketToServiceRecord()
而不是
CreateRfcomsocketToServiceRecord()
以及前面提到的
getUuids()
可以帮我解决这个问题

UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid);

等等,我有一些蓝牙应用程序,但我还没有发现需要使用反射(getclass.getmethod)的情况。你能再告诉我一些你试过的硬件吗?我很想知道在某些情况下反射是否真的是必要的。我发现最好的方法是尝试第一种方法,它连接得更快。然后在服务发现失败时,在异常中实现反射。还发现同一款HTC手机在UDP检测方面也存在问题,而三星和摩托罗拉设备没有问题。阅读JellyBean中的
BluetoothDevice
类的源代码,这似乎在通道1上创建了一个RFCOMM套接字。故意跳过Javadoc,并且该方法不在API中公开。我不知道为什么这个黑客会起作用,但它允许我与一个据称缺乏SPP配置文件的设备通信,而该设备没有UUID工作。“权限被拒绝”异常会为我引发,尽管我已经请求了
BLUETOOTH
BLUETOOTH\u ADMIN
权限。当我将此代码更改回BluetoothChat中的代码时,“权限被拒绝”异常消失,但“服务发现失败”异常再次出现。我该怎么办?这对我来说也很有用,但这是一个黑客行为。这假定服务器通道是固定的。不幸的是,我不能保证该频道将是任何特定的频道。有人知道如何解决这个问题,但却避免使用这个解决方案吗?现在:建议的编辑使用与不起作用的代码完全相同的方法。工作代码使用不同的非公共方法,不需要uuid。在尝试编写连接到蓝牙扫描仪的android应用程序时,出现与上述相同的错误。这个解决方案对我很有效。@Monsingor我无法评论任何一种方式,我只是接受了建议的编辑-但请告诉我们原因,或者更好的是编辑并更正答案。@Rup原始代码从一开始就使用“00001101-0000-1000-8000-00805F9B34FB”作为CreateRfcomSocketToServiceRecord()函数的UUID参数。我不明白你为什么要添加一个建议以稍微不同的方式做同样事情的答案。显然,这不会有帮助。@Monsingor我相信关键的区别在于所使用的UUID,即使代码是相同的。上面提到的javadoc声明:提示:如果您正在连接蓝牙串行板,请尝试使用著名的SPP UUID 00001101-0000-1000-8000-00805F9B34FB。当我尝试这个方法时,它对我也很有效。