Android蓝牙不发送文本数据

时间:2015-04-16 21:33:18

标签: android bluetooth

我想创建两个应用程序,一个用于通过蓝牙发送文本,另一个用于接收它。但问题是,即使两个设备连接成功,也没有文本传输。特别是Messages活动中的 outStream.write(bytes) 无效。

与大多数问题不同,我只想要从Sender到Receiver的单向单面聊天;不是双向聊天。

任何帮助都将不胜感激。

这是发件人代码:

//member variables
private BluetoothAdapter btAdapter=null;
private ConnectThread btConnectThread;
private ConnectedThread btConnectedThread;
private int btState;

// Constants that indicate the current connection state
public static final int STATE_NONE = 0;       // we're doing nothing
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3;  // now connected to a remote device

//dev name to be returned to UI
private static final int DEVICE_NAME=0;
//sent message returned to UI
private static final int SENT_MESSAGE=1;
private static final int STATUS=2;


/**
 * Return Intent extra
 */
public static String EXTRA_DEVICE_ADDRESS = "device_address";
// Unique UUID for this application
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");

//handler for UI thread
private final Handler handle=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);

        TextView dvNm=(TextView) findViewById(R.id.connectedTo);
        TextView sntMsg=(TextView) findViewById(R.id.sentMessage);
        TextView stat=(TextView) findViewById(R.id.statusTest);
        EditText tyMsg=(EditText) findViewById(R.id.typedMessage);
        String temp;

        switch (msg.what)
        {
            case DEVICE_NAME:
            {
                temp=dvNm.getText().toString();
                dvNm.setText(temp+": "+msg.obj.toString());
                break;
            }

            case SENT_MESSAGE:
            {
                temp=msg.obj.toString();
                sntMsg.setText("Sent: "+temp);
                tyMsg.setText("");
                break;
            }

            case STATUS:
            {
                temp=msg.obj.toString();
                stat.setText(temp);
            }
        }
    }
};

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

    btAdapter=BluetoothAdapter.getDefaultAdapter();
}

@Override
protected void onStart() {
    super.onStart();

    Intent dList=getIntent();
    String macAddr=dList.getStringExtra(EXTRA_DEVICE_ADDRESS);

    if(btState==STATE_NONE)
    {
        connect(macAddr);
    }

}

@Override
protected void onDestroy() {
    super.onDestroy();

    if(btState!=STATE_NONE)
        stop();
}

//button listener for sending message
public void onSend(View v)
{
    //get the typed message
    EditText tyMsg=(EditText) findViewById(R.id.typedMessage);
    //convert it to byte format
    byte[] send=tyMsg.getText().toString().getBytes();

    // Create temporary object
    ConnectedThread cThrd;

    // Synchronize a copy of the ConnectedThread
    synchronized (this) {
        if (btState != STATE_CONNECTED) return;
        cThrd = btConnectedThread;
    }
    // Perform the write asynchronized
    cThrd.write(send);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_messages, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

/**
 * Bluetooth Client component code
 */
private class ConnectThread extends Thread {
    private final BluetoothSocket btSocket;
    private final BluetoothDevice btDevice;

    public ConnectThread(BluetoothDevice device) {
        // Use a temporary object that is later assigned to btSocket,
        // because btSocket is final
        BluetoothSocket tmp = null;
        btDevice = 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) { }
        btSocket = tmp;
    }

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

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

        // Do work to manage the connection (in a separate thread)
        connected(btSocket,btDevice);
    }

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


/**
 * Code to manage the connected socket
 */
private class ConnectedThread extends Thread {
    private final BluetoothSocket btSocket;
    private final OutputStream outStream;

    public ConnectedThread(BluetoothSocket socket) {
        btSocket = socket;
        OutputStream tmpOut = null;

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

        outStream = tmpOut;
    }

    public void run() { }

    /* Call this from the main activity to send data to the remote device */
    public void write(byte[] bytes) {
        try {

            Message msg2=handle.obtainMessage(STATUS,"Inside write of connectedthread");
            handle.sendMessage(msg2);

            outStream.write(bytes);
            outStream.flush();

            Message msg1=handle.obtainMessage(STATUS,"Wrote to outstream");
            handle.sendMessage(msg1);

            Message msg=handle.obtainMessage(SENT_MESSAGE,bytes);
            handle.sendMessage(msg);

        } catch (IOException e) { }
    }

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

/**
 * Start the ConnectThread to initiate a connection to a remote device.
 *
 * @param macAddr is the mac-address The BluetoothDevice to connect
 */
public synchronized void connect(String macAddr) {

    //get Bluetooth device from mac-address
    BluetoothDevice device = btAdapter.getRemoteDevice(macAddr);

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

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

    // Start the thread to connect with the given device
    btConnectThread = new ConnectThread(device);
    btConnectThread.start();

    btState=STATE_CONNECTING;
}

/**
 * Start the ConnectedThread to begin managing a Bluetooth connection
 *
 * @param socket The BluetoothSocket on which the connection was made
 * @param device The BluetoothDevice that has been connected
 */
public synchronized void connected(BluetoothSocket socket, BluetoothDevice
        device) {

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

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

    // Start the thread to manage the connection and perform transmissions
    btConnectedThread = new ConnectedThread(socket);
    btConnectedThread.start();

    // Send the name of the connected device back to the UI Activity
    Message msg = handle.obtainMessage(DEVICE_NAME,device.getName());
    handle.sendMessage(msg);

    btState=STATE_CONNECTED;
}

/**
 * Stop all threads
 */
public synchronized void stop(){

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

    // Cancel any thread currently running a connection
    if (btConnectedThread != null) {
        btConnectedThread.cancel();
        btConnectedThread = null;
    }
    btState=STATE_NONE;
}
}

这是收件人代码:

//member variables
private BluetoothAdapter btAdapter=null;
private AcceptThread btAcceptThread;
private ConnectedThread btConnectedThread;
private int btState;

// Constants that indicate the current connection state
public static final int STATE_NONE = 0;       // we're doing nothing
public static final int STATE_LISTEN = 1;     // now listening for incoming connections
public static final int STATE_CONNECTED = 3;  // now connected to a remote device

//dev name to be returned to UI
private static final int DEVICE_NAME=0;
//received message returned to UI
private static final int RECEIVED_MESSAGE=1;

// Name for the SDP record when creating server socket
private static final String NAME = "BluetoothAnnouncement";
// Unique UUID for this application
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");

//handler for UI thread
private final Handler handle=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);


        TextView dvNm=(TextView) findViewById(R.id.connectedTo);
        TextView rcvdMsg=(TextView) findViewById(R.id.receivedMessage);
        String temp;

        switch (msg.what)
        {
            case DEVICE_NAME:
            {
                temp=dvNm.getText().toString();
                dvNm.setText(temp+": "+msg.obj.toString());
                break;
            }

            case RECEIVED_MESSAGE:
            {
                temp=msg.obj.toString();
                rcvdMsg.setText("Received: "+temp);
                break;
            }
        }
    }
};

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

    //Acquiring Bluetooth Adapter
    btAdapter = BluetoothAdapter.getDefaultAdapter();
    //setting initial state
}

@Override
protected void onStart() {
    super.onStart();

    if(!btAdapter.isEnabled())
    {
        Toast.makeText(this, "Please enable Bluetooth to receive announcements",
                Toast.LENGTH_SHORT).show();
    }
}

@Override
protected void onResume() {
    super.onResume();

    if(btAdapter.isEnabled())
    {
        if(btState==STATE_NONE)
        {
            start();
        }
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();

    if(btState!=STATE_NONE)
        stop();
}

//enabling Bluetooth
public void btEnable(View v)
{
    if (btAdapter.isEnabled())
    {
        Toast.makeText(this, "Bluetooth already enabled",
                Toast.LENGTH_SHORT).show();
    }
    else
    {
        Intent discoverableIntent = new
                Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
        startActivity(discoverableIntent);
    }
}

/**
 * Server component code
 */
private class AcceptThread extends Thread {
    private final BluetoothServerSocket btServerSocket;

    public AcceptThread() {
        // Use a temporary object that is later assigned to btServerSocket,
        // because btServerSocket is final
        BluetoothServerSocket tmp = null;
        try {
            // MY_UUID is the app's UUID string, also used by the client code
            tmp = btAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
        } catch (IOException e) { }
        btServerSocket = tmp;
    }

    public void run() {
        BluetoothSocket socket = null;
        BluetoothDevice device;
        // Keep listening until exception occurs or a socket is returned
        while (true) {
            try {
                socket = btServerSocket.accept();
            } catch (IOException e) {
                break;
            }
            // If a connection was accepted
            if (socket != null) {
                device=socket.getRemoteDevice();
                // Do work to manage the connection (in a separate thread)
                connected(socket, device);
                try {
                    btServerSocket.close();
                } catch (IOException e) { }
                break;
            }
        }
    }

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

/**
 * Code to manage the connected socket
 */
private class ConnectedThread extends Thread {
    private final BluetoothSocket btSocket;
    private final InputStream inStream;

    public ConnectedThread(BluetoothSocket socket) {
        btSocket = socket;
        InputStream tmpIn = null;

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

        inStream = tmpIn;
    }

    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 = inStream.read(buffer);
                // Send the obtained bytes to the UI activity
                Message msg = handle.obtainMessage(RECEIVED_MESSAGE,bytes);
                handle.sendMessage(msg);

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

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

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

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

    // Start the thread to listen on a BluetoothServerSocket
    if (btAcceptThread == null) {
        btAcceptThread = new AcceptThread();
        btAcceptThread.start();
    }

    //set state
    btState=STATE_LISTEN;
}

/**
 * Start the ConnectedThread to begin managing a Bluetooth connection
 *
 * @param socket The BluetoothSocket on which the connection was made
 * @param device The BluetoothDevice that has been connected
 */
public synchronized void connected(BluetoothSocket socket, BluetoothDevice
        device) {

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

    // Cancel the accept thread because we only want to connect to one device
    if (btAcceptThread != null) {
        btAcceptThread.cancel();
        btAcceptThread = null;
    }

    // Start the thread to manage the connection and perform transmissions
    btConnectedThread = new ConnectedThread(socket);
    btConnectedThread.start();

    // Send the name of the connected device back to the UI Activity
    Message msg = handle.obtainMessage(DEVICE_NAME,device.getName());
    handle.sendMessage(msg);

    btState=STATE_CONNECTED;
}

/**
 * Stop all threads
 */
public synchronized void stop(){

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

    // Cancel the accept thread because we only want to connect to one device
    if (btAcceptThread != null) {
        btAcceptThread.cancel();
        btAcceptThread = null;
    }

    btState=STATE_NONE;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}

0 个答案:

没有答案