简体   繁体   中英

Receiving Bluetooth Serial Port (Virtual COM Port) data from Android 2.3.3 device in HyperTerminal

I'm developing an Android application which includes Bluetooth SPP Connection. The post on Receiving String from RFCOMM on PC, sent from Android really helped me.

Even my log in Eclipse says 'wrote 6 bytes out of 6' many times and then the socket gets closed. But, I want to receive (whatever I sent) in my PC using Hyperterminal. How do I do that? How to specify Virtual COM Port in code?

I'm using a Samsung SGH-T759 for testing in USB Debugging mode.

Here's my code:

public class BluetoothActivity extends Activity {

private int bluetooth = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_bluetooth);
    TextView text = (TextView) findViewById(R.id.text);
    text.setText("Click on the button to access devices through Bluetooth");
}

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

public void bluetoothActivate(View view) {
    int REQUEST_ENABLE_BT = 1;
    int RESULT_ENABLE_BT  = 0;
    //TextView text = (TextView) findViewById(R.id.text);
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    System.out.println("Button clicked...");
    if (mBluetoothAdapter == null) {
        //txtView.setText("This device does not support Bluetooth");
        CharSequence txt = "This device does not support Bluetooth";
        Toast toast = Toast.makeText(getApplicationContext(), txt, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();

    }
    else {
        //CharSequence text = "Bluetooth is supported!!!";
        System.out.println("Bluetooth is supported!!!");
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            onActivityResult(REQUEST_ENABLE_BT, RESULT_ENABLE_BT, enableBtIntent);
        }
        else 
            bluetooth = 1;

        device_access(view);
    }
}

public void device_access(View view) {
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    TextView text = (TextView) findViewById(R.id.text);
    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    Spinner btDevices = (Spinner) findViewById(R.id.btDevices);

    System.out.println("Bluetooth devices...");

    if (bluetooth == 1)
        // If there are paired devices
        if (pairedDevices.size() > 0) {
            // Loop through paired devices
            System.out.println("Bluetooth paired devices...");
            final ArrayAdapter<CharSequence> mArrayAdapter = new ArrayAdapter<CharSequence>(this, android.R.layout.simple_list_item_1);
            ArrayAdapter<CharSequence> deviceName = new ArrayAdapter<CharSequence>(this, android.R.layout.simple_list_item_1);
            mArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            deviceName.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            for (BluetoothDevice device : pairedDevices) {

                // Add the name and address to an array adapter to show in a ListView
                mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                deviceName.add(device.getName());
            }
            btDevices.setVisibility(1);
            btDevices.setAdapter(mArrayAdapter);
            //txtView.append("\nPaired Bluetooth Devices Found...");


            /*// Create a BroadcastReceiver for ACTION_FOUND
            final BroadcastReceiver mReceiver = new BroadcastReceiver() {
                public void onReceive(Context context, Intent intent) {
                    String action = intent.getAction();
                    // When discovery finds a device
                    if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                        // Get the BluetoothDevice object from the Intent
                        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                        // Add the name and address to an array adapter to show in a ListView
                        mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                    }
                }
            };
            // Register the BroadcastReceiver
            IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
            registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
             */         

            String[] dvc = btDevices.getSelectedItem().toString().split("\n");
            final UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //UUID for serial connection
            String mac = "90:00:4E:DC:41:9D"; //my laptop's mac adress
            //mac = dvc[1];
            text.append("\n Data sent to " + btDevices.getSelectedItem().toString());
            BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mac); //get remote device by mac, we assume these two devices are already paired


            // Get a BluetoothSocket to connect with the given BluetoothDevice
            BluetoothSocket socket = null;
            OutputStream out = null;
            InputStream inp = null;
            //try {
            //socket = device.createRfcommSocketToServiceRecord(SERIAL_UUID);
            Method m;
            try {
                m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
                socket = (BluetoothSocket) m.invoke(device, 1); 
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            //}catch (IOException e) {}

            try {     
                mBluetoothAdapter.cancelDiscovery();
                socket.connect(); 
                out = socket.getOutputStream();
                inp = socket.getInputStream();
                //now you can use out to send output via out.write
                String outputValue = "Hi...\n",inputValue;
                byte[] op = outputValue.getBytes(),buffer = null;
                int inpBytes;
                for (int i=0; i<1000000; i++) {
                    out.write(op);
                    out.flush();
                }   
                System.out.println("Data written!!");
                /*while (true) {
                    try {
                        // Read from the InputStream
                        inpBytes = inp.read(buffer);

                        inputValue = buffer.toString();
                        text.append(inpBytes+ " " + inputValue);

                    } catch (IOException e) {

                    }

                }*/ }catch (IOException e) {} finally {
                    try {
                        socket.close();
                        System.out.println("Socket closed...");
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } 
                }
        }

}

}

I myself solved it. I had to use the listenUsingRfcommWithServiceRecord(NAME,SERIAL_UUID) to register my phone's SPP capability on my laptop. Then, my laptop assigned a COM port for SPP communication with my phone. Then, I specified this port in AccessPort137 (another application similar to hyperterminal and better than that in some aspects) and established communication properly. My working code follows:

package com.example.bluetoothtest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.UUID;

import com.example.bluetoothtest.R;
import com.example.bluetoothtest.DynamicGraph;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;

import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class BluetoothActivity extends Activity {

    public final static String EXTRA_MESSAGE = "com.example.bluetoothtest.MESSAGE";
    public int bluetooth = 0, mState = 0;
    public boolean runThread = false;
    private TextView text;
    public static final UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //UUID for serial connection
    public static final int STATE_DISCONNECTED = 0;
    public static final int STATE_CONNECTED = 1;
    public static final int MESSAGE_READ = 2;
    public static final int START_INTENT = 3;
    public static final int REQ_CODE_DYNAMIC = 4;

    public static BluetoothAdapter mBluetoothAdapter = null;
    public static BluetoothDevice device = null;

    BluetoothServerSocket mmServerSocket = null;
    BluetoothSocket socket = null,finalSocket = null;
    OutputStream out = null;
    //InputStream aStream = null;
    InputStreamReader aReader = null;
    BufferedReader mBufferedReader = null;

    ConnectedThread con = null;
    AcceptThread accept = null;
    ConnectThread connect = null;

    Intent intent;


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

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

        mState = STATE_DISCONNECTED;

        // Start the thread to listen on a BluetoothServerSocket
        if (accept!= null) {
            accept = null;
        }


        text = (TextView) findViewById(R.id.text);
        text.setText("Click on the button to access devices through Bluetooth");

    }

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

    @Override
    public void onDestroy(){
        super.onDestroy();
        runThread = false;
    }

    public void bluetoothActivate(View view) {
        int REQUEST_ENABLE_BT = 1;
        int RESULT_ENABLE_BT  = 0;

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        System.out.println("Button clicked...");
        if (mBluetoothAdapter == null) {

            CharSequence txt = "This device does not support Bluetooth";
            Toast toast = Toast.makeText(getApplicationContext(), txt, Toast.LENGTH_SHORT);
            toast.setGravity(Gravity.CENTER, 0, 0);
            toast.show();

        }
        else {

            System.out.println("Bluetooth is supported!!!");
            if (!mBluetoothAdapter.isEnabled()) {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
                onActivityResult(REQUEST_ENABLE_BT, RESULT_ENABLE_BT, enableBtIntent);
            }
            else 
                bluetooth = 1;

            device_access(view);
        }
    }

    public void bluetoothDisconnect(View view) {

        runThread = false;  
        con.cancel();
        //connect.cancel();
        System.out.println("Connection disconnected");
        text.append("\n Connection disconnected");
    }

    public void device_access(View view) {

        System.out.println("Bluetooth devices...");

        if (bluetooth == 1)  {

            //String mac = "F0:08:F1:36:D3:5B"; //my other phone's mac adress
            String mac = "90:00:4E:DC:41:9D"; //my laptop's mac adress
            //String mac = "A0:4E:04:B8:1D:62";
            //mac = dvc[1];
            //text.append("\n Data sent to " + btDevices.getSelectedItem().toString());

            //device = mBluetoothAdapter.getRemoteDevice(mac); //get remote device by mac, we assume these two devices are already paired

            //text.append("device = " + device);
            text.append("\n Bluetooth started...");
            System.out.println("Bluetooth Started...");
            //ensureDiscoverable();

            String backup_file = "dynamic_bluetooth.csv";

            intent = new Intent(this, DynamicGraph.class);
            intent.putExtra(EXTRA_MESSAGE, backup_file);

            System.out.println("Dynamic intent about to start...");

            /*connect = new ConnectThread(device);
            connect.start();*/


                    CheckBox plotGraph = (CheckBox) findViewById(R.id.plotGraph);
            if (plotGraph.isChecked())
                startActivityForResult(intent,REQ_CODE_DYNAMIC);
            else {
                accept = new AcceptThread();
                accept.start();
            }


        }

    }


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

        public ConnectThread(BluetoothDevice device) {
            this.mmDevice = device;
            BluetoothSocket tmp1 = null;
            try {
                tmp1 = device.createRfcommSocketToServiceRecord(SERIAL_UUID);
            } catch (IOException e) {
                e.printStackTrace();
            }
            mmSocket = tmp1;
        }

        @Override
        public void run() {
            setName("ConnectThread");
            mBluetoothAdapter.cancelDiscovery();
            try {
                mmSocket.connect();
                System.out.println("Connected with the device");
            } catch (IOException e) {
                try {
                    mmSocket.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }

                return;

            }
            /*synchronized (PrinterService.this) {
                mConnectThread = null;
            }*/
            //connected(mmSocket, mmDevice);
        }

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


    private void ensureDiscoverable() {

        if (mBluetoothAdapter.getScanMode() !=
                BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
            Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
            startActivity(discoverableIntent);
        }
        System.out.println("Device set discoverable");

        text.append("\n Device set discoverable");
        return;
    }

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {

            case MESSAGE_READ:
                /*byte[] readBuf = (byte[]) msg.obj;
                // construct a string from the valid bytes in the buffer
                String readMessage = new String(readBuf, 0, msg.arg1);*/
                //float readM = Float.parseFloat(readMessage);

                System.out.println("Into handler...");
                String readMessage = (String) msg.obj;
                text.append("\n" + readMessage);
                try{
                    float readM = Float.parseFloat(readMessage);
                    text.append(" " + readM);
                }catch (NumberFormatException e) {
                    text.append(" - Number Format Exception!!");
                    e.printStackTrace();
                }
                break;

            case START_INTENT:
                System.out.println("Dynamic intent about to start...");
                //startActivityForResult(intent,REQ_CODE_DYNAMIC);
                break;
            }

        }

    };

    private class AcceptThread extends Thread {

        public AcceptThread() {

            BluetoothServerSocket tmp = null;

            try {
                System.out.println("Listening...");
                tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("SPP", SERIAL_UUID);

            }catch (IOException e) {
                System.out.println("Listening Failed");


            }

            mmServerSocket = tmp;
            if (mmServerSocket != null)
                System.out.println("Server socket established: tmp = " + tmp);
            else
                System.out.println("Server socket NOT established: tmp = " + tmp);


        }

        public void run() {

            // Get a BluetoothSocket to connect with the given BluetoothDevice
            try {     
                //socket = mmServerSocket.accept();

                System.out.println("AcceptThread Run");
                while (true) {
                    if ((mmServerSocket != null) && (mState != STATE_CONNECTED)) {  
                        try {
                            socket = mmServerSocket.accept();
                            device = socket.getRemoteDevice();
                        } catch (IOException e) {
                            System.out.println("Socket not received");
                            break;
                        }

                        if (socket!= null)  {

                            System.out.println("Device Address: " + device.getAddress());
                            runThread = true;
                            con = new ConnectedThread(socket);
                            con.start();
                            mState = STATE_CONNECTED;

                            break;
                        }
                    }
                    else {
                        System.out.println("Code incomplete. Repeat Listening");
                        break;
                    }


                }
            } 
            finally {
                /*try {
                                con.cancel();
                                mmServerSocket.close();
                                System.out.println("Socket closed...");
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                System.out.println("Server Socket close problem...");
                                e.printStackTrace();
                            } */
            }
        }

        public void cancel() {

            try {
                mmServerSocket.close();
                accept.start();
            } catch (IOException e) {

            }
        }
    }


    private class ConnectedThread extends Thread {

        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;


        public ConnectedThread(BluetoothSocket socket) {

            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {

            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run() {

            byte[] buffer = new byte[1024],readBuffer = new byte[1024];
            int bytesAvailable,readBufferPosition;
            char[] readMsg = new char[8192];
            /*try {
                aStream = socket.getInputStream();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                System.out.println("InputStream problem...");
                e.printStackTrace();
            }*/

            /*aReader = new InputStreamReader( mmInStream );
            mBufferedReader = new BufferedReader( aReader );*/ 

            String aString = "---";

            System.out.println("Waiting for input...");

            /*try {
                Thread.sleep(10000);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                System.out.println("Sleeping problem...");
                e1.printStackTrace();
            }*/


            while (runThread) {
                try {

                    /*aReader = new InputStreamReader( mmInStream );

                    mBufferedReader = new BufferedReader( aReader );
                    //aString = mBufferedReader.readLine();

                    mBufferedReader.read(readMsg);
                    aString = new String(readMsg);
                    readMsg = new char[8192];
                    System.out.println(aString);*/

                    aString = "---";
                    byte delimiter = 'N';     //New line
                    readBuffer = new byte[1024];
                    readBufferPosition = 0;
                    bytesAvailable = mmInStream.read(buffer);
                    boolean copied = false;

                    if (bytesAvailable > 0)
                        System.out.println(bytesAvailable + " bytes available");
                    else
                        System.out.println("Bytes not available");

                    for(int i=0;i<bytesAvailable;i++)
                    {
                        byte b = buffer[i];
                        System.out.println("Byte = "+ b);
                        if(b == delimiter)
                        {
                            byte[] encodedBytes = new byte[readBufferPosition];
                            System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
                            aString = new String(encodedBytes, "US-ASCII");
                            readBufferPosition = 0;
                            copied= true;
                            break;

                        }
                        else
                        {
                            readBuffer[readBufferPosition++] = b;
                        }
                    }

                    /*aString = new String(buffer);
                    aString = aString.trim();*/
                    //float rx_data = Float.parseFloat(aString);

                    System.out.println("aString = " + aString);


                    /*mHandler.obtainMessage(BluetoothActivity.MESSAGE_READ, bytes, -1, buffer)
                    .sendToTarget();*/

                    //buffer = new byte[1024];

                    if (copied && (aString != "---"))
                        mHandler.obtainMessage(BluetoothActivity.MESSAGE_READ, aString)
                        .sendToTarget();



                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    System.out.println("mBufferedReader problem...");
                    e.printStackTrace();
                    break;
                }

            }


            //cancel();

            /*out = socket.getOutputStream();
            //now you can use out to send output via out.write
            String outputValue = "Hi...\n",inputValue;
            byte[] op = outputValue.getBytes(),buffer = null;
            int inpBytes;
            for (int i=0; i<1000000; i++) {
                out.write(op);
                out.flush();
            }   
            System.out.println("Data written!!");


            while (true) {
    try {
        // Read from the InputStream
        inpBytes = inp.read(buffer);

        inputValue = buffer.toString();
        text.append(inpBytes+ " " + inputValue);

    } catch (IOException e) {

    }

} */
        }

        public void cancel() {
            try {

                /*aReader.close();
                mBufferedReader.close();*/
                runThread = false;
                mState = STATE_DISCONNECTED;
                mmSocket.close();
                mmServerSocket.close();
                System.out.println("Socket closed in thread...");
                accept = new AcceptThread();
                accept.start();
            } catch (IOException e) {
                System.out.println("Socket close problem...");
            }
        }

    }



}

Uncomment and run the ConnectThread also if you want bi-directional communication. I only had to receive values; so, I've commented it out. But, this thread has to be run in order to establish a COM port for your phone with your laptop. This is because, only when an application like this which uses Bluetooth SPP is run in the phone and tries to pair with the laptop (using this ConnectThread), the laptop will register the SPP capability of the phone. To see this and enable SPP from your laptop's side, do the following:

  1. Right-click on your Bluetooth icon in the taskbar and click on 'Show Bluetooth Devices'.

  2. In the window that opens, find your phone (remember that it must already be paired with your laptop before even running this SPP application), right-click it and go to 'Properties'.

  3. Go to the 'Services' tab and you'll find a new entry called by the name that you provide as the first parameter in the listenUsingRfcommWithServiceRecord() method. For me it's 'SPP'.

  4. Check that new service to enable SPP between your laptop and your phone.

  5. Now, if you check the 'Hardware' tab, a COM port will be specified which you can use in HyperTerminal or any such application and start communicating.

Also, remember that this is NOT possible with Windows 8 yet! Whatever I've mentioned here pertains to Windows 7; I haven't done this in Windows XP even though it will be pretty much the same method.

I hope my solution helps! And, I welcome comments on my (novice) code from experts in these things - after all, I guess StackOverflow is primarily for that purpose.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM