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:
Right-click on your Bluetooth icon in the taskbar and click on 'Show Bluetooth Devices'.
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'.
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'.
Check that new service to enable SPP between your laptop and your phone.
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.