I am trying to setup a Bluetooth connection between an Android device and an rPi. However I am getting an unresolved symbol error on socket in the testouput function. However, socket works just fine further down the code. I am not sure what I am doing wrong here. Thanks!
ArrayAdapter<String> listAdapter;
ListView listView;
BluetoothAdapter btAdapter;
Set<BluetoothDevice> devicesArray;
ArrayList<String> pairedDevices;
ArrayList<BluetoothDevice> devices;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
IntentFilter filter;
BroadcastReceiver receiver;
String tag = "debugging";
Handler mHandler = new Handler(){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log.i(tag, "in handler");
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
// DO something
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
Toast.makeText(getApplicationContext(), "CONNECT", 0).show();
String s = "successfully connected";
connectedThread.write(s.getBytes());
Log.i(tag, "connected");
break;
case MESSAGE_READ:
byte[] readBuf = (byte[])msg.obj;
String string = new String(readBuf);
Toast.makeText(getApplicationContext(), string, 0).show();
break;
}
}
};
#Override
public void testoutput(String str){
final BluetoothSocket mmSocket;
mmSocket = socket;
byte[] toSend=str.getBytes();
OutputStream mmOutStream = socket.getOutputStream();
mmOutStream.write(toSend);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bluetooth);
init();
if(btAdapter==null){
Toast.makeText(getApplicationContext(), "No bluetooth detected", 0).show();
finish();
}
else{
if(!btAdapter.isEnabled()){
turnOnBT();
}
getPairedDevices();
startDiscovery();
}
}
private void startDiscovery() {
// TODO Auto-generated method stub
btAdapter.cancelDiscovery();
btAdapter.startDiscovery();
}
private void turnOnBT() {
// TODO Auto-generated method stub
Intent intent =new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
private void getPairedDevices() {
// TODO Auto-generated method stub
devicesArray = btAdapter.getBondedDevices();
if(devicesArray.size()>0){
for(BluetoothDevice device:devicesArray){
pairedDevices.add(device.getName());
}
}
}
private void init() {
// TODO Auto-generated method stub
listView=(ListView)findViewById(R.id.listView);
listView.setOnItemClickListener(this);
listAdapter= new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,0);
listView.setAdapter(listAdapter);
btAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevices = new ArrayList<String>();
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
devices = new ArrayList<BluetoothDevice>();
receiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
devices.add(device);
String s = "";
for(int a = 0; a < pairedDevices.size(); a++){
if(device.getName().equals(pairedDevices.get(a))){
//append
s = "(Paired)";
break;
}
}
listAdapter.add(device.getName()+" "+s+" "+"\n"+device.getAddress());
}
else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
// run some code
}
else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
// run some code
}
else if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){
if(btAdapter.getState() == btAdapter.STATE_OFF){
turnOnBT();
}
}
}
};
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(receiver, filter);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
unregisterReceiver(receiver);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_CANCELED){
Toast.makeText(getApplicationContext(), "Bluetooth must be enabled to continue", Toast.LENGTH_SHORT).show();
finish();
}
}
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
if(btAdapter.isDiscovering()){
btAdapter.cancelDiscovery();
}
if(listAdapter.getItem(arg2).contains("Paired")){
BluetoothDevice selectedDevice = devices.get(arg2);
ConnectThread connect = new ConnectThread(selectedDevice);
connect.start();
Log.i(tag, "in click listener");
}
else{
Toast.makeText(getApplicationContext(), "device is not paired", 0).show();
}
}
private class ConnectThread extends Thread {
private final 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;
Log.i(tag, "construct");
// 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) {
Log.i(tag, "get socket failed");
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
btAdapter.cancelDiscovery();
Log.i(tag, "connect - run");
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
Log.i(tag, "connect - succeeded");
} catch (IOException connectException) { Log.i(tag, "connect failed");
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} 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;
// 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;
}
public void run() {
byte[] buffer; // 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
buffer = new byte[1024];
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
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) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
Related
I have used BluetoothSPP Library:
https://github.com/akexorcist/Android-BluetoothSPPLibrary
The arduino connecting successfully to the android studio application, but I can't receive the data, I will import both of my codes and please some one tell me if I did something wrong, from what I read and understood , bluetooth.setOnDataReceivedListener is the function to receive and you should place bluetooth.print(data) on the arduino part in order to
Android:
public class MainActivity extends AppCompatActivity {
final String ON = "1";
final String OFF = "0";
BluetoothSocket socket;
private BluetoothAdapter mAdapter;
BluetoothSPP bluetooth;
private BluetoothDevice remoteDevice;
TextView text;
private BluetoothServerSocket mmServerSocket;
String TAG = "TEST: ";
Button connect;
Button on;
Button off;
private OnDataReceivedListener mDataReceivedListener = null;
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == BluetoothState.REQUEST_CONNECT_DEVICE) {
if (resultCode == Activity.RESULT_OK)
bluetooth.connect(data);
} else if (requestCode == BluetoothState.REQUEST_ENABLE_BT) {
if (resultCode == Activity.RESULT_OK) {
bluetooth.setupService();
} else {
Toast.makeText(getApplicationContext()
, "Bluetooth was not enabled."
, Toast.LENGTH_SHORT).show();
finish();
}
}
}
public void setOnDataReceivedListener (OnDataReceivedListener listener) {
if (mDataReceivedListener == null)
mDataReceivedListener = listener;
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
}
public void onStart() {
super.onStart();
if (!bluetooth.isBluetoothEnabled()) {
bluetooth.enable();
} else {
if (!bluetooth.isServiceAvailable()) {
bluetooth.setupService();
bluetooth.startService(BluetoothState.DEVICE_OTHER);
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bluetooth = new BluetoothSPP(this);
text = (TextView) findViewById(R.id.textView2);
connect = (Button) findViewById(R.id.connect);
on = (Button) findViewById(R.id.on);
off = (Button) findViewById(R.id.off);
BluetoothSocket socket = null;
mAdapter = BluetoothAdapter.getDefaultAdapter();
if (!bluetooth.isBluetoothAvailable()) {
Toast.makeText(getApplicationContext(), "Bluetooth is not available", Toast.LENGTH_SHORT).show();
finish();
}
bluetooth.setOnDataReceivedListener(new BluetoothSPP.OnDataReceivedListener() {
public void onDataReceived(byte[] data, String message) {
Log.d(TAG, "Start Reading");
/*Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();*/
Log.i("Check", "Message : " + message);
}
});
bluetooth.setBluetoothConnectionListener(new BluetoothSPP.BluetoothConnectionListener() {
public void onDeviceConnected(String name, String address) {
connect.setText("Connected to " + name);
}
public void onDeviceDisconnected() {
connect.setText("Connection lost");
}
public void onDeviceConnectionFailed() {
connect.setText("Unable to connect");
}
});
connect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (bluetooth.getServiceState() == BluetoothState.STATE_CONNECTED) {
bluetooth.disconnect();
} else {
Intent intent = new Intent(getApplicationContext(), DeviceList.class);
startActivityForResult(intent, BluetoothState.REQUEST_CONNECT_DEVICE);
}
}
});
on.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Its on");
bluetooth.send(ON, true);
}
});
off.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Its off");
bluetooth.send(OFF, true);
}
});
}
arduino part:
The Arduino code looks right.
Try first a Bluetooth serial monitor on your Android to check if the data is really being sent and received.
Then make sure in your Android code you connect to the module first then try to receive the data.
I'm making a OBDII reader app and would like to see the (in this case) voltage on text rather than in the Logcat which is what I currently see. You can see in the code below where I read the voltage in my while loop. Is it possible to update the textView everytime the loop runs?
Any help is appreciated!
.java
public class BTHandler {
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
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
BluetoothAdapter mBluetoothAdapter;
UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private String status;
private BluetoothDevice mmDevice;
private ConnectedThread mConnectedThread;
private ConnectThread mConnectThread;
private int pPlatform = Constants.SPA;
private boolean connectionStatus = false;
public BTHandler(Context context, Handler handler) { // Konstruktor
mAdapter = BluetoothAdapter.getDefaultAdapter();
mHandler = handler;
}
public void write(String s) {
mConnectedThread.sendRawCommand(s);
Log.v("write", "write");
}
public void close() {
try {
mConnectedThread.cancel();
} catch (NullPointerException e) {
}
}
public void connect(String deviceAddress) {
mConnectThread = new ConnectThread(deviceAddress);
mConnectThread.start();
}
private void guiHandler(int what, int arg1, String obj) {
Message msg = mHandler.obtainMessage();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.sendToTarget();
}
private class ConnectThread extends Thread {
private final BluetoothDevice mmDevice;
BluetoothSocket tmp = null;
private BluetoothSocket mmSocket;
public ConnectThread(String deviceAddress) {
mmDevice = mAdapter.getRemoteDevice(deviceAddress);
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = mmDevice.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) {
}
guiHandler(Constants.TOAST, Constants.SHORT, "Connection Failed");
return;
}
// Do work to manage the connection (in a separate thread)
guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_CONNECTED, "");
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
}
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private BluetoothSocket mmSocket;
private ObdMultiCommand multiCommand;
public ConnectedThread(BluetoothSocket socket) {
connectionStatus = true;
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
switch (pPlatform) {
case Constants.SPA:
multiCommand = new ObdMultiCommand();
multiCommand.add(new OdbRawCommand(SPA.VOLTAGE));
break;
}
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.v("e", "e");
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
OBDcmds();
ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();
//TextView textView = (TextView) findViewById(R.id.textView);
while (!Thread.currentThread().isInterrupted()) {
try {
voltageCommand.run(mmInStream, mmOutStream);
voltageCommand.getFormattedResult();
Log.d("Log", "Voltage:" + voltageCommand.getFormattedResult());
textView.setText(voltageCommand.getFormattedResult());
} catch (Exception e) {
e.printStackTrace();
}
}
}
// CALL this to MainActivity
public void sendRawCommand(String s) {
try {
} catch (Exception e) {
Log.v("sendRawCommand", "e");
}
}
/*
// 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();
}
}
*/
private void OBDcmds() { // execute commands
try {
new EchoOffCommand().run(mmInStream, mmOutStream);
new LineFeedOffCommand().run(mmInStream, mmOutStream);
new TimeoutCommand(100).run(mmInStream, mmOutStream);
new SelectProtocolCommand(ObdProtocols.AUTO).run(mmInStream, mmOutStream);
//ISO_15765_4_CAN
} catch (Exception e) {
Log.v("OBDcmds", "e");
// handle errors
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
connectionStatus = false;
mmSocket.close();
guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_NOT_CONNECTED, "");
} catch (IOException e) {
}
}
}
}
.xml
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="178dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button b1;
BluetoothAdapter mAdapter;
BTHandler btHandler;
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BTHandler.STATE_CONNECTED:
setContentView(R.layout.activity_connected);
Toast.makeText(getApplicationContext(), R.string.title_connected_to, Toast.LENGTH_SHORT).show();
Log.v("Log", "Connected");
break;
case BTHandler.STATE_NONE:
Toast.makeText(getApplicationContext(), R.string.title_not_connected, Toast.LENGTH_SHORT).show();
break;
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.textView);
btHandler = new BTHandler(MainActivity.this, mHandler);
b1 = (Button) findViewById(R.id.connect);
b1.setOnClickListener(this);
mAdapter = BluetoothAdapter.getDefaultAdapter();
if (mAdapter == null) {
Toast.makeText(getApplicationContext(), R.string.device_not_supported, Toast.LENGTH_LONG).show();
finish();
} else {
if (!mAdapter.isEnabled()) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
}
}
public void onClick(View v) {
int id = v.getId();
//String voltage = ("ATRV");
switch (id) {
case R.id.connect:
onConnect(); //Operation
Log.v("Log", "Pressed onClick");
break;
case R.id.getValue:
btHandler.write(SPA.VOLTAGE);
Log.v("getValue","" + SPA.VOLTAGE);
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), R.string.enable_bluetooth, Toast.LENGTH_SHORT).show();
finish();
}
}
private void onConnect() {
ArrayList deviceStrs = new ArrayList();
final ArrayList<String> devices = new ArrayList();
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
Set pairedDevices = mAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (Object device : pairedDevices) {
BluetoothDevice bdevice = (BluetoothDevice) device;
deviceStrs.add(bdevice.getName() + "\n" + bdevice.getAddress());
devices.add(bdevice.getAddress());
}
}
// show list
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.select_dialog_singlechoice,
deviceStrs.toArray(new String[deviceStrs.size()]));
alertDialog.setSingleChoiceItems(adapter, -1, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
int position = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
String deviceAddress = devices.get(position);
btHandler.connect(deviceAddress);
}
});
alertDialog.setTitle("Paired devices");
alertDialog.show();
}
#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);
}
}
Your object extends the Thread so I assume that it would be started like this
ConnectedThread ct = new ConnectedThread(socket);
ct.start();
In Android you can't update View from non-UI thread. You would need to create a Handler and pass the data to it. In you Handler implementation you would be able to call the setText() method to update your TextView.
See this link for more details about communication with UT thread.
For the updated post
I personally don't like the idea to change the layout of the Activity in the Handler implementation - I would go for Fragments usage.
Anyway after calling the setContentView(R.layout.activity_connected) in your Handler you need to call the findViewById again to find the TextView in your activity_connected layout:
case BTHandler.STATE_CONNECTED:
setContentView(R.layout.activity_connected);
Toast.makeText(getApplicationContext(), R.string.title_connected_to, Toast.LENGTH_SHORT).show();
Log.v("Log", "Connected");
TextView tv = (TextView)findViewById(R.id.textView);
tv.setText("Connected");
break;
Code snippet update
ConnectedThread#run()
public void run() {
OBDcmds();
ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();
//TextView textView = (TextView) findViewById(R.id.textView);
while (!Thread.currentThread().isInterrupted()) {
try {
voltageCommand.run(mmInStream, mmOutStream);
Log.d("Log", "Voltage:" + voltageCommand.getFormattedResult());
guiHandler(Constants.VOLTAGE_STATUS, 0, voltageCommand.getFormattedResult())
} catch (Exception e) {
e.printStackTrace();
}
}
}
Handler implementation
private Handler mHandler = new Handler() {
TextView textView = null;
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BTHandler.STATE_CONNECTED:
setContentView(R.layout.activity_connected);
Toast.makeText(getApplicationContext(), R.string.title_connected_to, Toast.LENGTH_SHORT).show();
Log.v("Log", "Connected");
textView = (TextView)findViewById(R.id.textView);
break;
case BTHandler.STATE_NONE:
Toast.makeText(getApplicationContext(), R.string.title_not_connected, Toast.LENGTH_SHORT).show();
break;
}
break;
case Constants.VOLTAGE_STATUS:
if(msg.obj != null && textView != null){
textView.setText((String)msg.obj)
}
break;
}
}
};
Use textView.setText(voltageCommand.getFormattedResult())
First, you need to map your textView to the resource ID.
TextView textView = (TextView) findViewById(R.id.textView);
you can place the above line after setContentView("your layout");
Now, you can use this textView and set the data as shown below,
textView.setText(voltageCommand.getFormattedResult());
This is about Android app development basics, you should read the tutorials at developer.android.com.
You can access the TextView with
TextView textView = (TextView) findViewbyId(R.id.textView);.
Then change your text with
textView.setText("new message");
HTH
I want to make a TCP client that can sent and receive data for server. I use Hercules(TCP/UDP test program) as Server. My code can send string "Submit" to Server. I try to make my code can receive data from Hercules but it not work.what I have to do for edit it?
This is my MainActivity code
public class MainActivity extends Activity {
// Used to reference UI elements of main.xml
private TextView text,serverResponse;
private EditText ipBox;
private EditText portBox;
private ToggleButton connect;
private Button send;
private static final String TAG = "CClient";
private String ipAddress;
private Socket client;
private DataOutputStream outToServer;
private DataInputStream inFromServer;
private boolean connected = false;
private final int START = 0xffffff;
private final int msgBoxHint = START;
private final int appendText = START + 1;
Toast mytoast , savetoast;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
Log.d(TAG, "Here 1");
ipAddress = getLocalIpAddress();
Log.d(TAG, "Get local IP="+ ipAddress);
text = (TextView) findViewById(R.id.text);
ipBox = (EditText) findViewById(R.id.ipBox);
serverResponse = (TextView) findViewById(R.id.response);
portBox = (EditText) findViewById(R.id.portBox);
send = (Button) findViewById(R.id.send);
send.setOnClickListener(buttonsendOnClickListener);
connect = (ToggleButton) findViewById(R.id.connect);
connect.setOnClickListener(buttonConnectOnClickListener);
Button buttonExit = (Button) findViewById(R.id.btnExit);
buttonExit.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.d(TAG, "Exit");
Log.d(TAG, "Disconnect" );
if(client != null)
{
try {
client.close();
} catch (IOException e) {
Log.d(TAG, "Disconnect"+e.toString() );
}
}
finish();
}
});
}
OnClickListener buttonConnectOnClickListener = new OnClickListener() {
/** Manages all button clicks from the screen */
#TargetApi(Build.VERSION_CODES.HONEYCOMB) #Override
public void onClick(View arg0) {
switch(arg0.getId())
{
case R.id.connect:
if(connect.isChecked())
{
Log.d(TAG, "Connect" );
EditText edIP = (EditText) findViewById(R.id.ipBox);
String ed_textIP = edIP.getText().toString().trim();
if(ed_textIP.isEmpty() || ed_textIP.length() == 0 || ed_textIP.equals("") || ed_textIP == null )
{
Toast.makeText(MainActivity.this, "IP Address or PORT is incorrect", Toast.LENGTH_SHORT).show();
Log.d(TAG, "IP Address or PORT is incorrect");
}
setValues(R.id.connect,true);
setValues(R.id.send,true);
setValues(R.id.ipBox,false);
String tMsg = welcomeMsg.toString();
MyClientTask myClientTask = new MyClientTask(ipBox
.getText().toString(), Integer.parseInt(portBox
.getText().toString()),
tMsg);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
myClientTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
myClientTask.execute();
}
else
{ /*Toast.makeText(this, ipBox.getText(), Toast.LENGTH_LONG).show();*/
Log.d(TAG, "Disconnect" );
if(client != null)
{
try {
client.close();
} catch (IOException e) {
Log.d(TAG, "Disconnect"+e.toString() );
}
setText(R.id.text,"Press the connect button to start the client");
setText(msgBoxHint,"");
setValues(R.id.connect,false);
setValues(R.id.ipBox,true);
setValues(R.id.send,false);
}
else
{
setValues(R.id.connect,false);
}
}
break;
}
}
};
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
String msgToServer;
MyClientTask(String addr, int port, String msgTo) {
dstAddress = addr;
dstPort = port;
msgToServer = msgTo;
}
protected Void doInBackground(Void... Arg0) {
Log.d(TAG, "InBackground");
Socket socket = null;
DataOutputStream outToServer = null;
DataInputStream inFromServer = null;
try {
client = new Socket(dstAddress, dstPort);
outToServer = new DataOutputStream(client.getOutputStream());
inFromServer = new DataInputStream(new BufferedInputStream(client.getInputStream())); // Input stream <- from server
}catch (UnknownHostException e) {
// TODO Auto-generated catch block
Log.d(TAG, "InBackground 1");
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
mytoast = Toast.makeText(MainActivity.this, "Error UnknownHostException",
Toast.LENGTH_SHORT);
mytoast.show();
setValues(R.id.send,false);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mytoast.cancel();
}
}, 500);
}
});
} catch (IOException e) {
Log.d(TAG, "InBackground 2");
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
mytoast = Toast.makeText(MainActivity.this, "Error IOException",
Toast.LENGTH_SHORT);
mytoast.show();
setValues(R.id.connect,false);
setValues(R.id.send,false);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mytoast.cancel();
}
}, 500);
}
});
}finally {
Log.d(TAG, "InBackground 3");
if (socket != null) {
try {
socket.close();
Log.d(TAG, "InBackground 3.11");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d(TAG, "InBackground 3.12");
}
}
Log.d(TAG, "InBackground 3.1");
}
Log.d(TAG, "InBackground 4");
return null;
}
#Override
protected void onPostExecute(Void result) {
serverResponse.setText(response);
super.onPostExecute(result);
}
}
OnClickListener buttonsendOnClickListener = new OnClickListener() {
/** Manages all button clicks from the screen */
#TargetApi(Build.VERSION_CODES.HONEYCOMB) #Override
public void onClick(View arg0) {
switch(arg0.getId())
{
case R.id.send:
Log.d(TAG, "Sent" );
String sentence = "Submit";
String recieve = "";
serverResponse = (TextView) findViewById(R.id.response);
try {
outToServer = new DataOutputStream(client.getOutputStream());
inFromServer = new DataInputStream(new BufferedInputStream(client.getInputStream()));
Log.d(TAG, "Sent 1-1" );
if(sentence != null){
outToServer.writeUTF(sentence);
outToServer.flush();
}
/*
*
*
*
*
*
*/
Log.d(TAG, "Sent 1-2"+ recieve);
} catch (IOException e) {
setValues(R.id.ipBox,true);
setValues(R.id.connect,false);
setValues(R.id.send,false);
}
break;
}
}
};
private String getLocalIpAddress() {
Log.d(TAG, "Here 2");
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
Log.d(TAG, "Here 3");
WifiInfo info = wifi.getConnectionInfo();
Log.d(TAG, "Here 4");
return Formatter.formatIpAddress(info.getIpAddress());
}
private void setText(int view, String content)
{
switch(view)
{
case R.id.ipBox: ipBox.setText(content); break;
case R.id.text: text.setText(content+"\n\n"); break;
case appendText: text.append(content+"\n\n"); break;
}
}
private void setValues(int view, boolean value)
{
switch(view)
{
case R.id.ipBox: ipBox.setEnabled(value); break;
case R.id.send: send.setEnabled(value); break;
case R.id.connect: connect.setChecked(value); break;
}
}
}
I think, I have to add receive code in buttonsendOnClickListener near /*****/.
Do not work with sockets in main (gui) thread. Use AsyncTask!
Android fails if work with sockets in main (gui) thread.
Example:
new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
super.onPreExecute();
// do in main thread before
}
#Override
protected Void doInBackground(Void... v) {
// do in thread, use sockets
return null;
}
#Override
protected void onPostExecute(Void v) {
super.onPostExecute(integer);
// do in main thread after
}
}.execute();
Learn about AsyncTask advance.
My aim is to connect to already paired bluetooth devices. I have got all the paired devices names and I am displaying them in a listview. When I click on any of the device name from the listview it should connect to that device if its within the range.
Whenever I try to connect to the device by calling mmSocket.connect() I get this system error in my log cat shown below and then it calls mmSocket.close():
06-22 17:40:50.617: W/System.err(25986): java.io.IOException: read failed, socket might closed or timeout, read ret: -1
06-22 17:40:50.618: W/System.err(25986): at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:510)
06-22 17:40:50.619: W/System.err(25986): at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:521)
06-22 17:40:50.619: W/System.err(25986): at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:320)
06-22 17:40:50.619: W/System.err(25986): at ik.learning.bluetooth.MainActivity$ConnectThread.run(MainActivity.java:233)
I am not sure why is this happening can some one help me out here. Below is my code:
public class MainActivity extends Activity implements OnItemClickListener{
ArrayAdapter<String> listAdapter;
Button connectNew;
ListView listView;
BluetoothAdapter btAdapter;
Set<BluetoothDevice> devicesArray;
IntentFilter filter;
BroadcastReceiver receiver;
ArrayList<String> pairedDevices;
ArrayList<BluetoothDevice> devices;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
Handler mHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
if(btAdapter == null){
Toast.makeText(this, "No bluetooth detected", Toast.LENGTH_LONG).show();
finish();
} else {
if(!btAdapter.isEnabled()){
turnOnBluetooth();
}
getPairedDevices();
startDiscovery();
}
mHandler = new Handler(){
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket) msg.obj);
Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_SHORT).show();
String s = "Successfully connected";
connectedThread.write(s.getBytes());
break;
case MESSAGE_READ:
byte[] readBuff = (byte[]) msg.obj;
String string = new String(readBuff);
Toast.makeText(getApplicationContext(), string, Toast.LENGTH_SHORT).show();
break;
}
}
};
}
private void startDiscovery() {
// TODO Auto-generated method stub
btAdapter.cancelDiscovery();
btAdapter.startDiscovery();
}
private void turnOnBluetooth() {
// TODO Auto-generated method stub
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
private void getPairedDevices() {
// TODO Auto-generated method stub
devicesArray = btAdapter.getBondedDevices();
if(devicesArray.size() > 0){
for(BluetoothDevice device : devicesArray){
//listAdapter.add(device.getName()+"\n"+device.getAddress());
pairedDevices.add(device.getName());//+"\n"+device.getAddress());
}
}
}
private void init() {
connectNew = (Button) findViewById(R.id.btnConnectNew);
listView = (ListView) findViewById(R.id.bluetoothlistView);
listView.setOnItemClickListener(this);
listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, 0);
listView.setAdapter(listAdapter);
btAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevices = new ArrayList<String>();
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
devices = new ArrayList<BluetoothDevice>();
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
devices.add(device);
String s = "";
for(int i = 0; i< pairedDevices.size(); i++){
if(device.getName().equals(pairedDevices.get(i))){
s = "PAIRED";
break;
}
}
listAdapter.add(device.getName()+" ("+s+") "+"\n"+device.getAddress());
}
else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
}
else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
}
else if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){
if(btAdapter.getState() == btAdapter.STATE_OFF){
turnOnBluetooth();
}
}
}
};
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(receiver, filter);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_CANCELED){
Toast.makeText(getApplicationContext(), "Bluetooth must be enabled to continue", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
unregisterReceiver(receiver);
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
if(btAdapter.isDiscovering()){
btAdapter.cancelDiscovery();
}
if(listAdapter.getItem(arg2).contains("PAIRED")){
//Object[] o = devicesArray.toArray();
BluetoothDevice selectedDevice = devices.get(arg2);
ConnectThread connect = new ConnectThread(selectedDevice);
connect.start();
Toast.makeText(getApplicationContext(), "Devices Paired", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Devices Not Paired", Toast.LENGTH_SHORT).show();
}
}
private class ConnectThread extends Thread {
private final 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;
// 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) { }
mmSocket = 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
Log.d("ConnectThread","try connect");
//mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
connectException.printStackTrace();
Log.d("ConnectThread","catch connect: "+connectException);
try {
Log.d("ConnectThread","try soccet close");
mmSocket.close();
} catch (IOException closeException) {
Log.d("ConnectThread","catch close: "+connectException);
}
return;
}
// Do work to manage the connection (in a separate thread)
Log.d("ConnectThread","before manage connected socket");
//manageConnectedSocket(mmSocket);
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
/*private void manageConnectedSocket(BluetoothSocket mmSocket2) {
// TODO Auto-generated method stub
}*/
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} 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;
// 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;
}
public void run() {
byte[] buffer; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
buffer = new byte[1024]; // buffer store for the stream
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
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) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
}
After onClick List Item you get the Bluetooth Name, using that name you can get Bluetooth Device object by calling BluetoothAdapter.getDefaultAdapter().getRemoteDevice(bluetoothDevice.getAddress());
Here is a sample code to connect to Bluetooth device..
//global variable
BluetoothSocket mBSocket;
// inside run() function
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter.isEnabled()) {
try {
for(BluetoothDevice bt: mBluetoothAdapter.getBondedDevices()) {
if(bt.getName().equalsIgnoreCase(selectedDevice.getName())) {
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(bt.getAddress());
mBluetoothAdapter.cancelDiscovery();
mBSocket = device.createRfcommSocketToServiceRecord(SPP_UUID);
mBSocket.connect();
return mBSocket;
}
}
} catch(IOException e) {
if(mBSocket != null) {
try {
mBSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
mBSocket = null;
}
e.printStackTrace();
return null;
}
}
return null;
Hope it helps.
I am trying to get my Android phone (NexusOne) to connect to two bluetooth chips simultaneously. I have read various responses on the internet concluding that this may or may not be able to be done. People who have gotten it working say it works by establishing multiple RFcomm connections, like two connect threads in parallel. I am not sure how to go about doing this. I have my connect code which will only connect to one chip at the moment. Ideas?
package com.example.connect;
public class ConnectThread extends Activity {
static BluetoothSocket mmSocket;
static BluetoothSocket mmSocket2;
static BluetoothDevice mmDevice;
static BluetoothDevice mmDevice2;
static InputStream mmInputStream;
static OutputStream mmOutputStream;
static BluetoothAdapter mBluetoothAdapter;
static BluetoothAdapter mBluetoothAdapter2;
TextView myLabel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connect_thread);
Button button = (Button)this.findViewById(R.id.button1);
myLabel = (TextView)findViewById(R.id.textView1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(ConnectThread.this, "Connection in progress", Toast.LENGTH_SHORT).show();
myLabel.setText("Connection in progress");
try
{
findBT2();
openBT2();
findBT();
openBT();
}
catch (IOException ex) { }
}
});}
void findBT2()
{
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null)
{
myLabel.setText("No bluetooth adapter available");
}
if(!mBluetoothAdapter.isEnabled())
{
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if(pairedDevices.size() > 0)
{
for(BluetoothDevice device2 : pairedDevices)
{
if(device2.getName().equals("H-C-2010-06-01"))
{
mmDevice2 = device2;
myLabel.setText("Bluetooth Device Found");
break;
}
}
if(pairedDevices.size()==0){myLabel.setText("Please Pair devices");}
}
}
public int openBT2() throws IOException
{
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard SerialPortService ID
mmSocket2 = mmDevice2.createRfcommSocketToServiceRecord(uuid);
mmSocket2.connect();
mmOutputStream = mmSocket2.getOutputStream();
mmInputStream = mmSocket2.getInputStream();
return 1;
}
void findBT()
{
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null)
{
myLabel.setText("No bluetooth adapter available");
}
if(!mBluetoothAdapter.isEnabled())
{
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if(pairedDevices.size() > 0)
{
for(BluetoothDevice device : pairedDevices)
{
if(device.getName().equals("HC-05"))
{
mmDevice = device;
myLabel.setText("Bluetooth Device Found");
break;
}
}
if(pairedDevices.size()==0){myLabel.setText("Please Pair devices");}
}
}
public int openBT() throws IOException
{
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard SerialPortService ID
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
return 1;
}
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action))
{ myLabel.setText("CONNECTED");}
}
void closeBT() throws IOException
{
mmOutputStream.close();
mmInputStream.close();
mmSocket.close();
myLabel.setText("Bluetooth Closed");
}
}
UPDATE: I got a double connection by instead of trying to connect to each chip separately, just pulling up a list of paired devices and connecting to each one at a time. This worked to connect to both however still no data showing...
public class Main_Activity extends Activity implements OnItemClickListener {
ArrayAdapter<String> listAdapter;
ListView listView;
static TextView MyLabel;
BluetoothAdapter btAdapter;
Set<BluetoothDevice> devicesArray;
ArrayList<String> pairedDevices;
ArrayList<BluetoothDevice> devices;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
IntentFilter filter;
BroadcastReceiver receiver;
String tag = "debugging";
Handler mHandler = new Handler(){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log.i(tag, "in handler");
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
// DO something
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
Toast.makeText(getApplicationContext(), "CONNECT", 0).show();
String s = "successfully connected";
connectedThread.write(s.getBytes());
Log.i(tag, "connected");
break;
case MESSAGE_READ:
byte[] readBuf = (byte[])msg.obj;
String string = new String(readBuf);
Toast.makeText(getApplicationContext(), string, 0).show();
MyLabel.setText(string);
break;
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MyLabel = (TextView)findViewById(R.id.Receive);
init();
if(btAdapter==null){
Toast.makeText(getApplicationContext(), "No bluetooth detected", 0).show();
finish();
}
else{
if(!btAdapter.isEnabled()){
turnOnBT();
}
getPairedDevices();
startDiscovery();
}
}
private void startDiscovery() {
// TODO Auto-generated method stub
btAdapter.cancelDiscovery();
btAdapter.startDiscovery();
}
private void turnOnBT() {
// TODO Auto-generated method stub
Intent intent =new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
private void getPairedDevices() {
// TODO Auto-generated method stub
devicesArray = btAdapter.getBondedDevices();
if(devicesArray.size()>0){
for(BluetoothDevice device:devicesArray){
pairedDevices.add(device.getName());
}
}
}
private void init() {
// TODO Auto-generated method stub
listView=(ListView)findViewById(R.id.listView);
listView.setOnItemClickListener(this);
listAdapter= new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,0);
listView.setAdapter(listAdapter);
btAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevices = new ArrayList<String>();
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
devices = new ArrayList<BluetoothDevice>();
receiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
devices.add(device);
String s = "";
for(int a = 0; a < pairedDevices.size(); a++){
if(device.getName().equals(pairedDevices.get(a))){
//append
s = "(Paired)";
break;
}
}
listAdapter.add(device.getName()+" "+s+" "+"\n"+device.getAddress());
}
else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
// run some code
}
else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
// run some code
}
else if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){
if(btAdapter.getState() == btAdapter.STATE_OFF){
turnOnBT();
}
}
}
};
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(receiver, filter);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
unregisterReceiver(receiver);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_CANCELED){
Toast.makeText(getApplicationContext(), "Bluetooth must be enabled to continue", Toast.LENGTH_SHORT).show();
finish();
}
}
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
if(btAdapter.isDiscovering()){
btAdapter.cancelDiscovery();
}
if(listAdapter.getItem(arg2).contains("Paired")){
BluetoothDevice selectedDevice = devices.get(arg2);
ConnectThread connect = new ConnectThread(selectedDevice);
connect.start();
Log.i(tag, "in click listener");
}
else{
Toast.makeText(getApplicationContext(), "device is not paired", 0).show();
}
}
private class ConnectThread extends Thread {
private final 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;
Log.i(tag, "construct");
// 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) {
Log.i(tag, "get socket failed");
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
btAdapter.cancelDiscovery();
Log.i(tag, "connect - run");
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
Log.i(tag, "connect - succeeded");
} catch (IOException connectException) { Log.i(tag, "connect failed");
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} 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;
// 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;
}
public void run() {
Toast.makeText(Main_Activity.this, "running", Toast.LENGTH_SHORT).show();
byte[] buffer; // 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
buffer = new byte[5000];
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
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) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
}