Android蓝牙以编程方式重复连接

时间:2015-01-15 18:52:43

标签: android bluetooth android-studio

我试图通过蓝牙连接两部Android手机。我按照Android在线指南中的说明进行操作,并且我非常密切关注。

http://developer.android.com/guide/topics/connectivity/bluetooth.html

我可以让蓝牙连接一次,但我必须重新启动Android设备或应用程序本身才能让它连接第二次。这在开发过程中不是问题,因为每次编辑代码时,android studio程序都会重新加载应用程序。它启动它并重新启动它,以便在测试期间我可以反复连接。在实际使用过程中,我必须重新启动Android手机或转到设置下的应用程序管理器选项并实际停止该应用程序。

如果我打电话给以下代码,我可以连接:

generateDefaultAdapter();
startDiscovery();
startThreadAccept();
startThreadConnect();

我如何获得它以便可以一次又一次地启动蓝牙连接?我看到的消息“无法连接”#39;来自内心阶层' ConnectThread'和来自" printStackTrace()'的IO错误从那部分代码。我第二次尝试,我似乎能够调用方法' stopConnection()'然后是上面的行(从' generateDefaultAdapter()'开始)但我发现我无法连接。

package org.test;

//some import statements here...

public class Bluetooth {

    public boolean mDebug = true;
    public BluetoothAdapter mBluetoothAdapter;

    public UUID mUUID  = UUID.fromString(BLUETOOTH_UUID);
    public Thread mAcceptThread;
    public Thread mConnectThread;

    public ConnectedThread mManageConnectionAccept;
    public ConnectedThread mManageConnectionConnect;


    public APDuellingBluetooth() {

    }


    public void generateDefaultAdapter() {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            // Device does not support Bluetooth
        }
        if (mBluetoothAdapter != null && !mBluetoothAdapter.isEnabled() ) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            (mDialogDuel.getActivity()).startActivityForResult(enableBtIntent, INTENT_ACTIVITY_BLUETOOTH_REQUEST_ENABLE);
        }
    }


    public void cancelDiscovery() { if (mBluetoothAdapter != null) mBluetoothAdapter.cancelDiscovery();}
    public void startDiscovery() { mBluetoothAdapter.startDiscovery();}
    public BluetoothAdapter getBluetoothAdapter() {return mBluetoothAdapter;}


    public void stopConnection () {

        try {
            if (mAcceptThread != null) {

                mAcceptThread.interrupt();
                //mAcceptThread.join();
                mAcceptThread = null;
            }

            if (mConnectThread != null) {

                mConnectThread.interrupt();
                //mConnectThread.join();
                mConnectThread = null;
            }

            if (mManageConnectionConnect != null) {
                mManageConnectionConnect.cancel();
                mManageConnectionConnect.interrupt();
                mManageConnectionConnect = null;
            }

            if (mManageConnectionAccept != null) {
                mManageConnectionAccept.cancel();
                mManageConnectionAccept.interrupt();
                mManageConnectionAccept = null;
            }

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


    }



    public void startThreadAccept () {

        if (mAcceptThread != null && !mAcceptThread.isInterrupted()) {
            if (mDebug) System.out.println("server already open");
            //return;
            mAcceptThread.interrupt();
            mAcceptThread = new AcceptThread();

        }
        else {
            mAcceptThread = new AcceptThread();
        }
        if (mAcceptThread.getState() == Thread.State.NEW ){
                //mAcceptThread.getState() == Thread.State.RUNNABLE) {
            mAcceptThread.start();
        }
    }



    public void startThreadConnect () {

        BluetoothDevice mDevice = mBluetoothAdapter.getRemoteDevice(mChosen.getAddress());
        //if (mDebug) System.out.println(mDevice.getAddress() + " -- " + mChosen.getAddress() );

        if (mConnectThread != null && !mConnectThread.isInterrupted()) {
            if (mDebug) System.out.println("client already open");
            //return;
            mConnectThread.interrupt();
            mConnectThread = new ConnectThread(mDevice);
        }
        else {
            mConnectThread = new ConnectThread(mDevice);
        }


        if (mConnectThread.getState() == Thread.State.NEW){// ||
                //mConnectThread.getState() == Thread.State.RUNNABLE) {
            mConnectThread.start();
        }
    }



    public void manageConnectedSocketAccept(BluetoothSocket socket) {


        String mTemp = mBluetoothAdapter.getName();
        if (mDebug) {
            System.out.println("socket accept from " + mTemp);
            System.out.println("info accept " + socket.getRemoteDevice().toString());
        }
        if (mManageConnectionAccept != null && !mManageConnectionAccept.isInterrupted()) {
            //mManageConnectionAccept.cancel();
            //mManageConnectionAccept.interrupt();
            if (mAcceptThread == null) System.out.println(" bad thread accept");
        }
        else {
            mManageConnectionAccept = new ConnectedThread(socket, "accept");
        }

        if (mManageConnectionAccept.getState() == Thread.State.NEW ){//||
                //mManageConnectionAccept.getState() == Thread.State.RUNNABLE) {
            mManageConnectionAccept.start();
        }

    }

    public void manageConnectedSocketConnect(BluetoothSocket socket) {


        String mTemp = mBluetoothAdapter.getName();
        if (mDebug) {
            System.out.println("socket connect from " + mTemp);
            System.out.println("info connect " + socket.getRemoteDevice().toString());

        }

        if (mManageConnectionConnect != null && !mManageConnectionConnect.isInterrupted()) {
            //mManageConnectionConnect.cancel();
            //mManageConnectionConnect.interrupt();
            if (mConnectThread == null) System.out.print(" bad thread connect ");
        }
        else {
            mManageConnectionConnect = new ConnectedThread(socket, "connect");
        }
        if (mManageConnectionConnect.getState() == Thread.State.NEW){// ||
                //mManageConnectionConnect.getState() == Thread.State.RUNNABLE) {
            mManageConnectionConnect.start();
        }
    }




    public void decodeInput (String mIn, ConnectedThread mSource) {
        // do something with info that is returned to me...

    }

    public void encodeOutput (String mMac1, String mMac2, int mLR1, int mLR2) {


        String mTemp = composeOutputString ( mServer, mMac1,mMac2, mLR1, mLR2);


        if (mManageConnectionConnect != null && mManageConnectionConnect.isConnected()) {
            mManageConnectionConnect.write(mTemp.getBytes());
            mManageConnectionConnect.flush();

        }
        if (mManageConnectionAccept != null && mManageConnectionAccept.isConnected()) {
            mManageConnectionAccept.write(mTemp.getBytes());
            mManageConnectionAccept.flush();
        }

        mTemp = composeOutputString ( mClient, mMac1,mMac2, mLR1, mLR2);


        if (mManageConnectionConnect != null && mManageConnectionConnect.isConnected()) {
            mManageConnectionConnect.write(mTemp.getBytes());
            mManageConnectionConnect.flush();
        }
        if (mManageConnectionAccept != null && mManageConnectionAccept.isConnected()) {
            mManageConnectionAccept.write(mTemp.getBytes());
            mManageConnectionAccept.flush();
        }
    }

    public String composeOutputString (SocketConnectData mData, String mMac1, String mMac2, int mLR1, int mLR2) {

        // make a string here with the data I want to send...
        String mTemp = new String();
        return mTemp;
    }



    /////////////////////////////////////////////
    private class AcceptThread extends Thread {
        private final BluetoothServerSocket mmServerSocket;
        private boolean mLoop = true;

        public AcceptThread() {


            // Use a temporary object that is later assigned to mmServerSocket,
            // because mmServerSocket is final
            mLoop = true;

            BluetoothServerSocket tmp = null;
            try {
                // MY_UUID is the app's UUID string, also used by the client code
                tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(mServiceNameReceive, mUUID );
            } catch (IOException e) {
                System.out.println("rfcomm problem ");
            }
            mmServerSocket = tmp;
        }

        public void run() {
            BluetoothSocket socket = null;
            // Keep listening until exception occurs or a socket is returned
            while (mLoop) {
                try {
                    if (mmServerSocket != null) {
                        socket = mmServerSocket.accept();
                    }
                } catch (IOException e) {
                    if (mDebug) System.out.println("rfcomm accept problem");
                    e.printStackTrace();
                    break;
                }
                // If a connection was accepted
                if (socket != null && ! isConnectionOpen() ) {
                    // Do work to manage the connection (in a separate thread)
                    manageConnectedSocketAccept(socket);
                    try {
                        mmServerSocket.close();

                    }
                    catch (IOException e) {}
                    break;
                }
            }
        }

        /** Will cancel the listening socket, and cause the thread to finish */
        public void cancel() {
            try {
                mLoop = false;
                mmServerSocket.close();
            } catch (IOException e) { }
        }
    }
    /////////////////////////////////////////////

    private class ConnectThread extends Thread {
        //private final BluetoothSocket mmSocket;
        private 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;

            try {

                tmp = device.createRfcommSocketToServiceRecord(mUUID);


                if (mDebug) System.out.println("connect -- rf socket to service record " + tmp);

            } catch (Exception e) {
                System.out.println("exception -- rf socket to service record problem " + tmp);

            }
            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 (InterruptedException e ) {System.out.println("interrupted exception");}

            catch (IOException e) {
                // Unable to connect; close the socket and get out
                if (mDebug) System.out.println("unable to connect ");

                e.printStackTrace(); //   <---- I see output from this spot!!



                try {
                    mmSocket.close();
                } catch (IOException closeException) {
                    System.out.println("unable to close connection ");
                }

                return;
            }


            // Do work to manage the connection (in a separate thread)
            if (mmSocket.isConnected() && ! isConnectionOpen()) {
                manageConnectedSocketConnect(mmSocket);
            }
        }

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

        public boolean isConnected() {
            return mmSocket.isConnected();
        }
    }

    /////////////////////////////////////////////
    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        public String mTypeName = "";

        private boolean mLoop = true;

        public StringWriter writer;

        public ConnectedThread(BluetoothSocket socket, String type) {
            mTypeName = type;
            mLoop = true;

            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;

            try {


                writer = new StringWriter();
            }
            catch (Exception e) {}

        }

        public void run() {
            byte[] buffer = new byte[1024];  // 

            int bytes; // bytes returned from read()
            String [] mLines ;



            // Keep listening to the InputStream until an exception occurs
            while (mLoop) {
                try {
                    // Read from the InputStream
                    bytes = mmInStream.read(buffer);

                    if (bytes == -1 || bytes == 0) {
                        if (mDebug) System.out.println("zero read");
                        return;
                    }

                    writer.append(new String(buffer, 0, bytes));

                    mLines = writer.toString().split("!");

                    if (mDebug) System.out.println( "lines " +mLines.length);

                    for (int i = 0; i < mLines.length; i ++ ) {


                        if (true) {
                            if (mDebug) System.out.println("  " + mLines[i]);
                            decodeInput (mLines[i], this);


                        }

                    }


                } catch (Exception e) {
                    e.printStackTrace();
                    if (mDebug) System.out.println("read buffer problem");
                    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) {
                e.printStackTrace();
                if (mDebug) System.out.println("bad write");
            }
        }

        /* Call this from the main activity to shutdown the connection */
        public void cancel() {
            try {
                mLoop = false;
                mmSocket.close();
                mmOutStream.close();
                mmInStream.close();
            } catch (IOException e) { }
        }

        public boolean isConnected() {
            boolean mIsOpen = false;
            try {
                mIsOpen = mmSocket.isConnected() ;
            } catch (Exception e) {}
            return mIsOpen;
        }

        public void flush() {
            try {
                mmOutStream.flush();
            }
            catch (IOException e) {e.printStackTrace();}
        }
    }

    ///////////////////////////////////////////////
}

感谢您的时间。

编辑:这是错误消息:

W/System.err﹕ java.io.IOException: read failed, socket might closed or timeout, read ret: -1
W/System.err﹕ at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:553)
W/System.err﹕ at android.bluetooth.BluetoothSocket.waitSocketSignal(BluetoothSocket.java:530)
W/System.err﹕ at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:357)
W/System.err﹕ at org.davidliebman.test.Bluetooth$ConnectThread.run(Bluetooth.java:761)

1 个答案:

答案 0 :(得分:0)

试试这个: 而不是重新启动应用程序。关闭Android设备上的蓝牙,并在延迟5秒后重新打开蓝牙。如果您可以成功建立连接,通常表明您没有完全关闭连接和套接字。记录您的代码。确保关闭套接字例程顺利执行。检查IOException的{​​{1}}方法中的cancel是否没有发现任何异常:

ConnectedThread