从Android中的远程蓝牙设备读取时出现问题

时间:2015-02-18 14:30:36

标签: android bluetooth

我想在我的应用程序中从蓝牙设备读取数据。在应用程序中,我显示了可用的蓝牙设备列表。点击任何列表项我都喜欢这个。

public void onItemClick(AdapterView<?> parent, View view, int position, long id)
    {
        mBluetoothAdapter.cancelDiscovery();
        stopProgressDialog();

        String bDevice = (String) mLvDevices.getItemAtPosition(position);
        String str = bDevice.substring(bDevice.length() - 17);
        BluetoothDevice device = null;

        for (int i = 0; i <= mBTDeviceList.size() - 1; i++)
        {
            if (mBTDeviceList.get(i).getAddress().toString().equalsIgnoreCase(str))
            {
                device = mBTDeviceList.get(i);
                break;
            }
        }

        BluetoothService bluetoothService = new BluetoothService(getActivity(), device);
        bluetoothService.connect(device);
    }

以下是我用来与配对设备进行交互的BluetoothService类。我可以在日志中看到我能够与设备连接,但是当我在read对象上调用InputStream时它无处可去,它只是卡在那里而且它什么都没显示。我不知道那里发生了什么。

如果有人能解决这个问题,请告诉我。

 public class BluetoothService
    {
        private static final String TAG = BluetoothService.class.getSimpleName();
        private static int MESSAGE_STATE_CHANGE = 4;
        // private final BluetoothAdapter mAdapter;
        // private final Handler mHandler;
        private ConnectThread mConnectThread;
        private ConnectedThread mConnectedThread;
        private BluetoothDevice mDevice;
        private int mState;

        private static final UUID SerialPortServiceClass_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

        private static final boolean D = true;
        public static final int STATE_NONE = 0;


public static final int STATE_LISTEN = 1;
    public static final int STATE_CONNECTING = 2;
    public static final int STATE_CONNECTED = 3;

    /****
     * Constructor. Prepares a new BluetoothChat session.
     * 
     * @param context
     *            The UI Activity Context
     * @param handler
     *            A Handler to send messages back to the UI Activity
     */
    public BluetoothService(Context context, BluetoothDevice device)
    {
        this.mState = STATE_NONE;
        this.mDevice = device;
    }

    /****
     * Set the current state of the chat connection
     * 
     * @param state
     *            An integer defining the current connection state
     */
    private synchronized void setState(int state)
    {
        if (D)
            Log.d(TAG, "setState() " + mState + " -> " + state);

        mState = state;

        /** Give the new state to the Handler so the UI Activity can update */
        // mHandler.obtainMessage(MESSAGE_STATE_CHANGE, state,
        // -1).sendToTarget();
    }

    /**
     * Return the current connection state.
     */
    public synchronized int getState()
    {
        return mState;
    }

    /**
     * Start the chat service. Specifically start AcceptThread to begin a
     * session in listening (server) mode. Called by the Activity onResume()
     */

    public synchronized void start()
    {
        if (D)
            Log.d(TAG, "start");

        /* Cancel any thread attempting to make a connection */
        if (mConnectThread != null)
        {
            mConnectThread.cancel();
            mConnectThread = null;
        }

        /* Cancel any thread currently running a connection */
        if (mConnectedThread != null)
        {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }

        setState(STATE_NONE);
    }

    /**
     * Start the ConnectThread to initiate a connection to a remote device.
     * 
     * @param device
     *            The BluetoothDevice to connect
     */
    public synchronized void connect(BluetoothDevice device)
    {

        if (D)
            Log.d(TAG, "connect to: " + device);

        /* Cancel any thread attempting to make a connection */
        if (mState == STATE_CONNECTING)
        {
            if (mConnectThread != null)
            {
                mConnectThread.cancel();
                mConnectThread = null;
            }
        }

        /* Cancel any thread currently running a connection */
        if (mConnectedThread != null)
        {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }

        /* Start the thread to connect with the given device */
        mConnectThread = new ConnectThread(device);
        mConnectThread.start();
        setState(STATE_CONNECTING);
    }

    /**
     * Start the ConnectedThread to begin managing a Bluetooth connection
     */
    public synchronized void connected(android.bluetooth.BluetoothSocket mmSocket, BluetoothDevice device)
    {

        if (D)
            Log.d(TAG, "connected");

        /* Cancel the thread that completed the connection */
        if (mConnectThread != null)
        {
            mConnectThread.cancel();
            mConnectThread = null;
        }

        /* Cancel any thread currently running a connection */
        if (mConnectedThread != null)
        {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }

        /* Start the thread to manage the connection and perform transmissions */
        mConnectedThread = new ConnectedThread(mmSocket);
        mConnectedThread.start();

        /* Send the name of the connected device back to the UI Activity */
    }

    /**
     * Stop all threads
     */
    public synchronized void stop()
    {
        if (D)
            Log.d(TAG, "stop");

        if (mConnectThread != null)
        {
            mConnectThread.cancel();
            mConnectThread = null;
        }

        if (mConnectedThread != null)
        {
            mConnectedThread.cancel();
            mConnectedThread = null;
        }
        setState(STATE_NONE);
    }

    /**
     * Write to the ConnectedThread in an unsynchronized manner
     */
    public void write(byte[] out)
    {

        /* Create temporary object */
        ConnectedThread r;

        /* Synchronize a copy of the ConnectedThread */
        synchronized (this)
        {
            if (mState != STATE_CONNECTED)
                return;
            r = mConnectedThread;
        }

        /* Perform the write unsynchronized */
        r.write(out);
    }

    /**
     * Indicate that the connection attempt failed and notify the UI Activity.
     */
    private void connectionFailed()
    {

        setState(STATE_NONE);

        /* Send a failure message back to the Activity */
    }

    /**
     * This thread runs while attempting to make an outgoing connection with a
     * device. It runs straight through; the connection either succeeds or
     * fails.
     */
    private class ConnectThread extends Thread
    {
        private final android.bluetooth.BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;

        public ConnectThread(BluetoothDevice device)
        {
            mmDevice = device;
            android.bluetooth.BluetoothSocket tmp = null;

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

        public void run()
        {

            Log.i(TAG, "BEGIN mConnectThread");
            setName("ConnectThread");

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

            /* 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)
            {
                connectionFailed();

                /* Close the socket */
                try
                {
                    mmSocket.close();
                } catch (IOException e2)
                {
                    Log.e(TAG, "unable to close() socket during connection failure", e2);
                }
                // Start the service over to restart listening mode

                return;
            }

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

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

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

    /**
     * This thread runs during a connection with a remote device. It handles all
     * incoming and outgoing transmissions.
     */
    private class ConnectedThread extends Thread
    {
        byte[] buffer = new byte[1];
        private final BluetoothSocket mmSocket;
        private final OutputStream mmOutStream;
        private final InputStream mmInStream;

        public ConnectedThread(android.bluetooth.BluetoothSocket mmSocket2)
        {
            Log.d(TAG, "create ConnectedThread");
            mmSocket = mmSocket2;

            InputStream tmpIn = null;
            BufferedOutputStream tmpOut = null;

            /* Get the BluetoothSocket input and output streams */
            try
            {
                Log.i(TAG, "input and outstreams");
                tmpIn = mmSocket2.getInputStream();
                // tmpOut = mmSocket2.getOutputStream();
                tmpOut = new BufferedOutputStream(mmSocket.getOutputStream());
            } catch (IOException e)
            {
                Log.e(TAG, "temp sockets not created", e);
            }
            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run()
        {
            int bytes = 0;

            Log.i(TAG, "Starting Connected Thread");
            /* Keep listening to the InputStream while connected */
            while (true)
            {
                try
                {
                    Log.i(TAG, "mmInStream available: " + mmInStream.available());
                    byte[] buffer = new byte[1024];
                    bytes = mmInStream.read(buffer);// , 0, buffer.length);
                    Log.i(TAG, "read in buffer: " + buffer.toString());

                } catch (IOException e)
                {
                    Log.e(TAG, "disconnected", e);
                    break;
                }
            }
        }

        public void write(byte[] bytes)
        {
            try
            {
                mmOutStream.write(bytes);
            } catch (IOException e)
            {
            }
        }

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

2 个答案:

答案 0 :(得分:0)

确保您要发送InputBuffer的数据进行阅读。 read()方法阻塞线程直到读取了某些内容

答案 1 :(得分:0)

我有一个类似的问题,在套接字创建的解决方法之后解决了。除此之外,我的课程与你工作的应用程序完全相同。

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

    public ConnectThread(BluetoothDevice device) throws IOException {
        mmDevice = device;
        BluetoothSocket tmp = null;

        Method m = null;
        try {
            m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            tmp = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        mmSocket = tmp;
    }
}