Android落后/不稳定的蓝牙连接

时间:2014-01-16 15:36:58

标签: android bluetooth ioexception android-bluetooth

我在使用不安全的RFCOMM连接连接到WML-C46 AH Bluetooth Chip时遇到问题。我用相关代码编写了一个Android应用程序来向您展示我的问题。

该应用

该应用只有一个按钮。如果单击此按钮,将启动蓝牙设备发现。发现完成后,应用程序连接到蓝牙设备(我只使用一个蓝牙设备进行测试,因此无法找到任何其他设备)。然后它打开一个输入流来读取该设备的数据。如果连接断开(抛出ioexception)或再次单击该按钮,则关闭连接(关闭所有线程,套接字和流)。如果再次单击该按钮,将启动新设备发现,依此类推......

问题

连接无法正常工作。数据输入流似乎有点滞后,有时连接中断没有任何可观察的原因( IOException:软件导致连接中止 IOException:再试一次)。它几乎是android蓝牙聊天示例的简化版本,它使用设备发现而不是配对设备,只使用一个活动。

守则

public class MainActivity extends Activity implements View.OnClickListener {

    BluetoothDevice btDevice;
    BluetoothSocket btSocket;
    InputStream inStream;
    OutputStream outStream;
    Object lock = new Object();
    boolean connected = false;
    boolean canceled = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(this);

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        getApplicationContext().registerReceiver(btReceiver, filter);
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        getApplicationContext().registerReceiver(btReceiver, filter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onClick(View arg0) {
        if (!connected) {
            connected = true;
            canceled = false;

            new Thread(new Runnable() {
                @Override
                public void run() {
                    BluetoothAdapter btAdapter = BluetoothAdapter
                            .getDefaultAdapter();

                    try {
                        if (btAdapter.isDiscovering())
                            btAdapter.cancelDiscovery();
                        btAdapter.startDiscovery();

                        // block until device discovery has finished
                        synchronized (lock) {
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                Log.d("EXCEPTION", "", e);
                            }
                        }

                        btSocket = btDevice.createInsecureRfcommSocketToServiceRecord(UUID
                                .fromString("00001101-0000-1000-8000-00805F9B34FB"));
                        btSocket.connect();

                        inStream = btSocket.getInputStream();
                        outStream = btSocket.getOutputStream();

                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                while (!canceled) {
                                    try {
                                        int in;
                                        while ((in = inStream.read()) != -1) {
                                            Log.d("Received new byte: ", in
                                                    + "");
                                        }
                                    } catch (IOException e) {
                                        Log.d("EXCEPTION IN LISTENER", "", e);
                                        disconnect();
                                    }
                                }
                            }
                        }).start();
                    } catch (IOException e) {
                        Log.d("", "", e);
                    }
                }
            }).start();
        } else {
            disconnect();
        }
    }

    private void disconnect() {
        connected = false;
        canceled = true;

        try {
            btSocket.close();
        } catch (Exception e) {
            Log.d("EXCEPTION DISCONNECTING", "", e);
        }
        try {
            inStream.close();
        } catch (Exception e) {
            Log.d("EXCEPTION DISCONNECTING", "", e);
        }
        try {
            outStream.close();
        } catch (Exception e) {
            Log.d("EXCEPTION DISCONNECTING", "", e);
        }

        btDevice = null;
        btSocket = null;
        inStream = null;
        outStream = null;
    }

    private final BroadcastReceiver btReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            try {
                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                    synchronized (lock) {
                        lock.notifyAll();
                    }
                }
            } catch (Exception e) {
                Log.d(this.getClass().getName(), "", e);
            }
        }
    };
}

我只使用阻止方法或自行阻止。因此连接建立工作非常程序化。

当我调整它时,我可能已经丢失了android示例的连接流程。但是我找不到问题。

输出

建立连接:

01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): initSocketNative
01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): ...fd 47 created (RFCOMM, lm = 0)
01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): initSocketFromFdNative
01-16 16:52:46.257: D/BluetoothUtils(6961): isSocketAllowedBySecurityPolicy start : device null
01-16 16:52:47.171: V/BluetoothSocket.cpp(6961): connectNative
01-16 16:52:47.570: V/BluetoothSocket.cpp(6961): ...connect(47, RFCOMM) = 0 (errno 115)

连接中断:

01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961): java.io.IOException: Software caused connection abort
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at android.bluetooth.BluetoothSocket.readNative(Native Method)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:388)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:60)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at com.example.bttest.MainActivity$2$1.run(MainActivity.java:100)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at java.lang.Thread.run(Thread.java:856)

谢谢!

1 个答案:

答案 0 :(得分:0)

发现问题。蓝牙设备没有按预期工作,并在几秒钟后关闭连接。但是代码工作得很好。