【问题标题】:android Bluetooth crash when connection is stopped连接停止时android蓝牙崩溃
【发布时间】:2015-06-01 17:19:58
【问题描述】:

我正在Android Studio 上编写应用程序。 我通过Bluetooth 从Android 设备与arduino 板通信。 现在一切正常,但我正在开始一个新的Activity,我需要停止实际的BT connection。所以我想调用一个停止方法。 问题是当我调用它时它崩溃了。

这里是代码

public class BtInterface {

private BluetoothDevice device = null;
private BluetoothSocket socket = null;
private InputStream receiveStream = null;
private OutputStream sendStream = null;
String GlobalBuff="";
String Right_Buff="";


private ReceiverThread receiverThread;

Handler handler;

public BtInterface(Handler hstatus, Handler h,String Device_Name) {
    Set<BluetoothDevice> setpairedDevices = BluetoothAdapter.getDefaultAdapter().getBondedDevices();
    BluetoothDevice[] pairedDevices = (BluetoothDevice[]) setpairedDevices.toArray(new BluetoothDevice[setpairedDevices.size()]);

    for(int i=0;i<pairedDevices.length;i++) {
        if(pairedDevices[i].getName().contains(Device_Name)) {
            device = pairedDevices[i];
            try {
                socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                receiveStream = socket.getInputStream();
                sendStream = socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
            break;
        }
    }

    handler = hstatus;

    receiverThread = new ReceiverThread(h);
}

public void sendData(String data) {
    sendData(data, false);
}

public void sendData(String data, boolean deleteScheduledData) {
    try {
       sendStream.write(data.getBytes());
        sendStream.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void connect() {
    new Thread() {
        @Override public void run() {
            try {
                socket.connect();

                Message msg = handler.obtainMessage();
                msg.arg1 = 1;
                handler.sendMessage(msg);

                receiverThread.start();

            } catch (IOException e) {
                Log.v("N", "Connection Failed : " + e.getMessage());
                e.printStackTrace();
            }
        }
    }.start();
}

public void close() {


    try {
        socket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    socket=null; //???
}

public BluetoothDevice getDevice() {
    return device;
}

private class ReceiverThread extends Thread {
    Handler handler;

    ReceiverThread(Handler h) {
        handler = h;
    }

    @Override public void run() {
        while(true) {
            try {
                if(receiveStream.available() > 0) {
                    byte buffer[] = new byte[1000];
                    int k = receiveStream.read(buffer, 0, 1000);

                    if(k > 0) {
                        byte rawdata[] = new byte[k];
                        for(int i=0;i<k;i++)
                            rawdata[i] = buffer[i];

                        String data = new String(rawdata);

                        GlobalBuff= GlobalBuff+data;
                        Right_Buff= GlobalBuff.substring(GlobalBuff.length()-1,GlobalBuff.length());
                        if(Right_Buff.equals("\n")){
                            Message msg = handler.obtainMessage();
                            Bundle b = new Bundle();
                            b.putString("receivedData", GlobalBuff);
                            msg.setData(b);
                            handler.sendMessage(msg);
                            GlobalBuff="";

                        }

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

我尝试了一些额外的代码:

  receiverThread.interrupt();
    receiverThread=null;

    if (receiveStream != null) {
       try {receiveStream.close();} catch (Exception e) {}
        receiveStream = null;
    }
    if (sendStream != null) {
       try {sendStream.close();} catch (Exception e) {}
        sendStream = null;
    }

在关闭之前但结果是一样的,它崩溃了。 奇怪的行为是它没有立即崩溃,因为它可能发生类型错误或其他情况(我说的是调试模式下的行为......)

如果有人有想法。

在谷歌上搜索这会将我带到有这个问题的人那里,但没有适合我的情况的解决方案。

谢谢

更新

我在崩溃时发现的痕迹是:

06-02 07:45:27.369    9025-9133/fr.icservice.sechage A/libc? Fatal signal 11 (SIGSEGV) at 0x00000008 (code=1), thread 9133 (Thread-1436)

我还在 5.0.2 下的索尼 Z3 手机上进行了测试(与 4.4.2 下的 T210 三星 Galaxy Tab3 相比),它没有崩溃..! 也许这是一个ROM错误?!还是安卓版本问题...

【问题讨论】:

  • 发布崩溃的堆栈跟踪
  • 如何获得完整的堆栈跟踪?应用崩溃时清除logcat?
  • 我不确定它为什么被清除,但我们需要查看错误。否则,我们只是猜测。
  • 我把我的蓝牙课程放在一个服务中,我设法让它工作。我现在可以毫无问题地关闭套接字了。

标签: android bluetooth


【解决方案1】:

这是 Android 上的一个已知问题(或错误?)。如果您关闭蓝牙套接字然后稍后访问它,某些设备会因分段错误而崩溃(例如您的设备)。一个常见的解决方法是在socket.isConnected() 之前检查close(), write(), read(), ... 或通过设置closeWasCalled = true 之类的标志来同步对close(), write(), read(), ... 的访问,并防止在close() 调用之后在您的代码中进一步调用此套接字的方法。

【讨论】:

    【解决方案2】:

    问题来自Socket Input/Output。我在与对等蓝牙设备断开连接时遇到了这个问题。

    原因:

    从代码中,我们尝试从 socket 对象/连接关闭的 read()write()

    解决方案:

    在上述操作之前添加检查socket.isConnected()

    您可以在 Stack Overflow 问题上阅读有关此问题的更多信息:Here

    【讨论】: