蓝牙安卓:我Socket.connect()块,直到永远,Socket.close不解除 [英] Bluetooth On Android: my Socket.connect() Blocks forever, and Socket.close does not unblock

查看:192
本文介绍了蓝牙安卓:我Socket.connect()块,直到永远,Socket.close不解除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直对蓝牙的应用程序为Android一段时间了,我只是发现了这个问题。当我preform mySocket.connect(); 在我的蓝牙服务类偶尔无限期阻塞。我读 BluetoothSocket.close的文档()和它说以下内容:

I have been working on a bluetooth app for android for awhile now and I just discovered this problem. When I preform mySocket.connect(); in my bluetooth service class it occasionally blocks indefinitely. I read the documentation for BluetoothSocket.close() and it says the following:

立即关闭这个套接字,并释放所有相关的资源。

Immediately close this socket, and release all associated resources.

原因立即阻止此套接字在其他线程上调用
  抛出IOException。

Causes blocked calls on this socket in other threads to immediately throw an IOException.

不过,这似乎并没有为我工作。这里是我的code用于设置计时器,然后尝试连接。

However, this does not seem to work for me. Here is my code for setting a timer and then trying to connect.

//code for starting timer and connecting
    MyRunnable runner = new MyRunnable(mySocket);
    Thread countThread = new Thread(runner);
    countThread.start();

    mySocket.connect();
    runner.setSocketConnected();


//code for MyRunnable
    private class MyRunnable implements Runnable{
        private boolean didSocketConnect = false;
        private boolean socketConnectFailed = false;
        private BluetoothSocket socket;

        public MyRunnable(BluetoothSocket socket){
            this.socket = socket;
        }

        public void run() {
            long start = System.currentTimeMillis();
            while(ESTABLISH_TIMEOUT + start >= System.currentTimeMillis() && !didSocketConnect && !socketConnectFailed){

            }
            if(!didSocketConnect && !socketConnectFailed){
                Log.v(TAG,"Reached Timeout and socket not open. Look for #");
                try {
                    socket.close();
                    Log.v(TAG,"#THIS CALL SHOULD BE MADE AFTER REACHED TIMEOUT AND SOCKET NOT OPEN");
                } catch (IOException e) {
                    Log.v(TAG,"Closing the socket connection fail--", e);
                }
            }else{
                Log.v(TAG, "Connected or Failed Before Timeout Thread Hit");
            }
        }

        public void setSocketConnected(){
            didSocketConnect = true;
        }

        public void setSocketFailed(){
            socketConnectFailed= true;
        }
    }

当我无限期地调用close(),它也块和connect()调用从未抛出IOException,尽管BluetoothSocket.close()文档。是什么使它工作,这样在connect()和close()不会无限期阻塞的最佳方式?

When I call close(), it also blocks indefinitely and the connect() call never throws an IOException, despite BluetoothSocket.close() documentation. What is the best way to make it work so that the connect() and close() do not block indefinitely?

请注意:我使用的Andr​​oid 2.2为这个项目

NOTE: I am using Android 2.2 for this project.

推荐答案

BluetoothSocket.connect() - 从的文档

BluetoothSocket.connect() - From the documentation:

尝试连接到远程设备。此方法将阻塞,直到
  连接或连接失败。如果此方法返回
  无异常则此套接字现已连接。

Attempt to connect to a remote device. This method will block until a connection is made or the connection fails. If this method returns without an exception then this socket is now connected.

为了你的电话到BluetoothSocket.connect()退出阻塞,它需要进行连接。这是由设计,它是有道理的,如果你仔细想想,得到我们想要的连接,调用.connect(蓝牙设备的地址)和块,直到它的连接。这就是为什么你需要单独的线程。

In order for your call to BluetoothSocket.connect() to quit blocking, it needs to make the connection. This is by design and it makes sense if you think about it, get the address of the Bluetooth device we want to connect to, call .connect(), and block until its connected. This is why you want separate threads.

至于你调用.close(),如果你有.connect()制定的问题,.close()应该水到渠成。

As far as you calling .close(), if you work out the issues with .connect(), .close() should fall into place.

请阅读这个。它基本上是说你想称之为连接一个单独的线程(.connect())和连接(InputStream.read())。这样,你的用户界面不会被阻塞。

Please read this. It basically says you want a separate thread called "connecting" (.connect()) and "connected" (InputStream.read()). This way your UI will not be blocked.

示例(从上面的链接)。 ConnectThread启动连接。 ConnectedThread管理连接(读/写数据,等等)。

Example (from the above link). ConnectThread initiates the connection. ConnectedThread manages the connection (reads/writes data, etc...).

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

    public ConnectThread(BluetoothDevice device) {
        // Use a temporary object that is later assigned to mmSocket,
        // because mmSocket is final
        BluetoothSocket tmp = null;
        mmDevice = device;

        // Get a BluetoothSocket to connect with the given BluetoothDevice
        try {
            // MY_UUID is the app's UUID string, also used by the server code
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) { }
        mmSocket = tmp;
    }

    public void run() {
        // Cancel discovery because it will slow down the connection
        mBluetoothAdapter.cancelDiscovery();

        try {
            // Connect the device through the socket. This will block
            // until it succeeds or throws an exception
            mmSocket.connect();
        } catch (IOException connectException) {
            // Unable to connect; close the socket and get out
            try {
                mmSocket.close();
            } catch (IOException closeException) { }
            return;
        }

        // Do work to manage the connection (in a separate thread)
        manageConnectedSocket(mmSocket);
    }

    /** Will cancel an in-progress connection, and close the socket */
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
}


private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket) {
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        // Get the input and output streams, using temp objects because
        // member streams are final
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) { }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run() {
        byte[] buffer = new byte[1024];  // buffer store for the stream
        int bytes; // bytes returned from read()

        // Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);
                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                break;
            }
        }
    }

    /* Call this from the main Activity to send data to the remote device */
    public void write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);
        } catch (IOException e) { }
    }

    /* Call this from the main Activity to shutdown the connection */
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
}

这篇关于蓝牙安卓:我Socket.connect()块,直到永远,Socket.close不解除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆