I am developing an android application with bluetooth chat. I have successfully implemented bluetooth chat with two phones.But my problem is that if I Change to next activity from the chatting activity the connection is lost then I am not able to send messages from second activity. How can I maintain my connection?
That is I want to stay connected through out my app. Whenever the user press on exit button then only the connection can disconnect. I want to send message from one activity and receive from another activity this is what I want. I am not able to create a background service with my code.
Can anyone help me to split my code? If I got a message from one phone then I want to process the message and I want to send back the result, that processing will be on next activity this is the working of my app.
public class BluetoothTexting extends Activity {
private static int DISCOVERY_REQUEST = 1;
private Handler handler = new Handler();
private ArrayList<BluetoothDevice> foundDevices = new ArrayList<BluetoothDevice>();
private ArrayAdapter<BluetoothDevice> aa;
private ListView list;
private BluetoothAdapter bluetooth;
private BluetoothSocket socket;
private UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
configureBluetooth();
setupListView();
setupSearchButton();
setupListenButton();
}
private void configureBluetooth() {
bluetooth = BluetoothAdapter.getDefaultAdapter();
}
private void setupListenButton() {
Button listenButton = (Button)findViewById(R.id.button_listen);
listenButton.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
Intent disc = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(disc, DISCOVERY_REQUEST);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == DISCOVERY_REQUEST) {
boolean isDiscoverable = resultCode > 0;
if (isDiscoverable) {
String name = "bluetoothserver";
try {
final BluetoothServerSocket btserver =
bluetooth.listenUsingRfcommWithServiceRecord(name, uuid);
AsyncTask<Integer, Void, BluetoothSocket> acceptThread =
new AsyncTask<Integer, Void, BluetoothSocket>() {
@Override
protected BluetoothSocket doInBackground(Integer... params) {
try {
socket = btserver.accept(params[0]*1000);
return socket;
} catch (IOException e) {
Log.d("BLUETOOTH", e.getMessage());
}
return null;
}
@Override
protected void onPostExecute(BluetoothSocket result) {
if (result != null)
switchUI();
}
};
acceptThread.execute(resultCode);
} catch (IOException e) {
Log.d("BLUETOOTH", e.getMessage());
}
}
}
}
private void setupListView() {
aa = new ArrayAdapter<BluetoothDevice>(this,
android.R.layout.simple_list_item_1,
foundDevices);
list = (ListView)findViewById(R.id.list_discovered);
list.setAdapter(aa);
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view,
int index, long arg3) {
AsyncTask<Integer, Void, Void> connectTask =
new AsyncTask<Integer, Void, Void>() {
@Override
protected Void doInBackground(Integer... params) {
try {
BluetoothDevice device = foundDevices.get(params[0]);
socket = device.createRfcommSocketToServiceRecord(uuid);
socket.connect();
} catch (IOException e) {
Log.d("BLUETOOTH_CLIENT", e.getMessage());
}
return null;
}
@Override
protected void onPostExecute(Void result) {
switchUI();
}
};
connectTask.execute(index);
}
});
}
private void setupSearchButton() {
Button searchButton = (Button)findViewById(R.id.button_search);
searchButton.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
registerReceiver(discoveryResult,
new IntentFilter(BluetoothDevice.ACTION_FOUND));
if (!bluetooth.isDiscovering()) {
foundDevices.clear();
bluetooth.startDiscovery();
}
}
});
}
private void switchUI() {
final TextView messageText = (TextView)findViewById(R.id.text_messages);
final EditText textEntry = (EditText)findViewById(R.id.text_message);
final Button btnSend = (Button)findViewById(R.id.send);
messageText.setVisibility(View.VISIBLE);
list.setVisibility(View.GONE);
textEntry.setEnabled(true);
btnSend.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(textEntry.getText().length()>0)
{
sendMessage(socket, textEntry.getText().toString());
}
else
{
sendMessage(socket, "Test_String");
}
}
});
/*textEntry.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
if ((keyEvent.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_DPAD_CENTER)) {
sendMessage(socket, textEntry.getText().toString());
textEntry.setText("");
return true;
}
return false;
}
});*/
BluetoothSocketListener bsl = new BluetoothSocketListener(socket, handler, messageText);
Thread messageListener = new Thread(bsl);
messageListener.start();
}
private void sendMessage(BluetoothSocket socket, String msg) {
OutputStream outStream;
try {
outStream = socket.getOutputStream();
byte[] byteString = (msg + " ").getBytes();
byteString[byteString.length - 1] = 0;
outStream.write(byteString);
// outStream.close();
// socket.close();
} catch (IOException e) {
Log.d("BLUETOOTH_COMMS", e.getMessage());
}
}
BroadcastReceiver discoveryResult = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
BluetoothDevice remoteDevice;
remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (bluetooth.getBondedDevices().contains(remoteDevice)) {
foundDevices.add(remoteDevice);
aa.notifyDataSetChanged();
}
}
};
private class MessagePoster implements Runnable {
private TextView textView;
private String message;
public MessagePoster(TextView textView, String message) {
this.textView = textView;
this.message = message;
}
public void run() {
textView.append("\n"+message);
Toast.makeText(getApplicationContext(),message,Toast.LENGTH_LONG).show();
}
}
private class BluetoothSocketListener implements Runnable {
private BluetoothSocket socket;
private TextView textView;
private Handler handler;
public BluetoothSocketListener(BluetoothSocket socket,
Handler handler, TextView textView) {
this.socket = socket;
this.textView = textView;
this.handler = handler;
}
public void run() {
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
try {
InputStream instream = socket.getInputStream();
int bytesRead = -1;
String message = "";
while (true) {
message = "";
bytesRead = instream.read(buffer);
if (bytesRead != -1) {
while ((bytesRead==bufferSize)&&(buffer[bufferSize-1] != 0)) {
message = message + new String(buffer, 0, bytesRead);
bytesRead = instream.read(buffer);
}
message = message + new String(buffer, 0, bytesRead - 1);
handler.post(new MessagePoster(textView, message));
socket.getInputStream();
}
}
} catch (IOException e) {
Log.d("BLUETOOTH_COMMS", e.getMessage());
}
}
}
}
I developed a similar bt-chat and i'll tell u what i did different which evantually worked:
instead of doInBackground, asyncTask and defining new runnable inside the activity i initiated and managed the connection on different threads. that way the connection stays opened.
EDIT: i added the server thread code. notice that when the server is connected it sends a broadcast so any activity could register it and receive so there is no problem in changing activities while the BT connects.
public class Server extends Thread {
private BluetoothAdapter btAdapter;
private String socketString = "a random string";
private BluetoothServerSocket btServerSocket;
private BluetoothSocket btConnectedSocket;
private final String TAG = "Server";
private MainActivity parent;
/*package-protected*/ static final String ACTION = "Bluetooth socket is connected";
private boolean connected;
public Server(MainActivity parent) {
this.parent = parent;
connected= false;
}
@Override
public void run() {
btAdapter = BluetoothAdapter.getDefaultAdapter();
try {
Log.i(TAG, "getting socket from adapter");
btServerSocket = btAdapter.listenUsingRfcommWithServiceRecord(socketString, MainActivity.BT_UUID);
listen();
}
catch (IOException ex) {
Log.e(TAG, "error while initializing");
}
}
private void listen() {
Log.i(TAG, "listening");
btConnectedSocket = null;
while (!connected) {
try {
btConnectedSocket = btServerSocket.accept();
}
catch (IOException ex) {
Log.e(TAG,"connection failed");
connectionFailed();
}
if (btConnectedSocket != null) {
broadcast();
closeServerSocket();
}
else {
Log.i(TAG, "socket is null");
connectionFailed();
}
}
}
private void broadcast() {
try {
Log.i(TAG, "connected? "+btConnectedSocket.isConnected());
Intent intent = new Intent();
intent.setAction(ACTION);
intent.putExtra("state", btConnectedSocket.isConnected());
parent.sendBroadcast(intent);
connected = true;
}
catch (RuntimeException runTimeEx) {
}
closeServerSocket();
}
private void connectionFailed () {
}
public void closeServerSocket() {
try {
btServerSocket.close();
}
catch (IOException ex) {
Log.e(TAG+":cancel", "error while closing server socket");
}
}
}