蓝牙套接字冻结手机

9
我正在开发一个Android应用程序。该应用程序应该与蓝牙(BT)设备通信(发送一些字节)。我在调试/运行此应用程序时遇到了问题,我的设备(三星Galaxy mini)出现了问题。当我创建一个BT套接字并停止调试时,手机会冻结,我必须通过取出电池来重新启动它。如果从Eclipse运行此应用程序,则一切正常,但是当我尝试再次运行它时,电话会冻结并且应用程序未安装。如果我尝试在第二次运行之前手动卸载此应用程序,则电话再次冻结。以下是有问题的代码:
private final BluetoothDevice mmDevice;
private UUID uuid;

public ConnectionThread(BluetoothDevice device) {
    Log.d(TAG, "create ConnectionThread");

    uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 
    BluetoothSocket tmp = null;
    mmDevice = device;

    try {
        tmp = mmDevice.createRfcommSocketToServiceRecord(uuid);
    } catch (IOException e) { }
    mmSocket = tmp;
    socketConnected = true;
}

这是一个线程的构造器。当我注释掉这行代码时,

……

    tmp = mmDevice.createRfcommSocketToServiceRecord(uuid);

手机没有冻结,问题出在创建套接字上(不是连接)。每次调试或运行后重启手机非常麻烦,而且我还有很多工作要做。

如果我从手机上运行这个应用程序(未连接到Eclipse),它可以无问题地运行。任何解决方法或建议吗?谢谢。


4
听起来像是固件漏洞,对吗? - Code Painters
@CodePainters:固件或IDE的错误。我发现了一个相同的主题:https://dev59.com/PFLTa4cB1Zd3GeqPbo8N。所以如果我在onDestroy回调中关闭BT,一切都没问题。 - DanielH
1
IDE?不太可能。而且安卓本来就充满了漏洞... - Code Painters
如果只有在从Eclipse调试时才会冻结,你可能会意外地设置了一个应用正在命中的断点吗? - Bryan Herbst
所有断点都已删除...我已经尝试了IntelliJIDEA IDE,问题仍然存在,所以这不是IDE的错误。 - DanielH
显示剩余4条评论
2个回答

0

我也在使用SGSIII mini进行开发。以下代码对我来说运行良好:

    private class ConnectThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;

    public ConnectThread(BluetoothDevice device) {
        mmDevice = device;

        BluetoothSocket tmp = null;

        // Get a BluetoothSocket for a connection with the
        // given BluetoothDevice
        try {
            //tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
            tmp = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            Log.e(LOG_TAG, "create() failed", e);
        }
        mmSocket = tmp;

        Main.myBluetoothSocket = mmSocket;
        Main.myBluetoothDevice = mmDevice;
    }

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

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

        // Send a failure message back to the Activity
        Message msg = mHandler.obtainMessage(MESSAGE_TOAST);
        Log.e(LOG_TAG, "Attempting connection to " + mmSocket.getRemoteDevice().getName());
        String ss = "Attempting connection to " + mmSocket.getRemoteDevice().getName();
        Bundle bundle = new Bundle();
        bundle.putString(TOAST, ss);
        msg.setData(bundle);
        mHandler.sendMessage(msg);

        // Make a connection to the BluetoothSocket
        try {
            // This is a blocking call and will only return on a
            // successful connection or an exception
            mmSocket.connect();
        } catch (IOException e) {
            Log.e(LOG_TAG, "*+*+*+*   Connection Failed");
            connectionFailed();
            // Close the socket
            try {
                mmSocket.close();
            } catch (IOException e2) {
                Log.e(LOG_TAG, "unable to close() socket during connection failure", e2);
            }
            // Start the service over to restart listening mode
            BluetoothCommandService.this.start();
            return;
        }

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

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

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

0

我也遇到了同样的问题,你可以使用反射方法,它会起作用的。

Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
BluetoothSocket socket = socket = (BluetoothSocket) m.invoke(device, 1);

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