I have a application where in the main activity the user selects a Bluetooth device and the app connects to it. Then a new activity is launched where the user can select between different activities (there are different ways to interact with the Bluetooth device). Lastly the selected activity is launched and the user is happy.
My problem is that when the connection is lost I should finish the list of activities activity and interaction activity somehow… but how? I’ve heard of Intents to pass messages between activities and Broadcasts, even Helpers, but no examples of how to pass an information from a running thread to multiple other activities.
The different connection threads (which I borrowed from the BluetoothChat example) are in the Application class, so I can access the writing function from any activity. That’s also where I detect the lost connection.
Here’s the relevant code from my app:
the Application class:
public class BluetoothRemoteControlApp extends Application {
public final int BT_CONNECTION_LOST = 1;
// . . .
private class ConnectedThread extends Thread {
// . . .
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (true) {
try {
bytes = mmInStream.read(buffer);
mHandler.obtainMessage(0, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
e.printStackTrace();
// the lost connection is detected here
connectionLost();
break;
}
}
}
// . . .
}
private void connectionLost() {
Log.e("BT", "Connection lost");
// inform that connection was lost,
// finish all activities and (re)start device select activity again
}
}
The activity where the different activities (called “actions”) are proposed:
public class ActionListActivity extends ListActivity {
ArrayList<Action> activityList = new ArrayList<Action>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// list of available activities, arguments: title, description and class name
activityList.add(new Action("Accelerometer Control", "Control your robot by tilting the phone", "AccelerometerControl"));
// . . .
setListAdapter(new ActionListBaseAdapter(this, activityList));
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
String activity = activityList.get(position).getClassName();
try {
Class<?> activityClass = Class.forName("com.bluetooth.activities." + activity);
Intent intent = new Intent(ActionListActivity.this, activityClass);
startActivity(intent);
}
catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
// add a method here to finish the activity when connection is lost
}
So let’s say I launch my AccelerometerControl activity, what to put in connectionLost() to send a message to ActionListActivity() and AccelerometerControl() so that they would finish?
use
startActivityOnResultinstead of startActivity and when you want to finish the activity use finishActivity (int requestCode) with the same requestcode used instartActivityOnResultEdit:
Create an ArrayList of Handlers in Application and also a static BluetoothRemoteControlApp field in your Application class and instantiate this to the present Application class instance.
In each Activity create a Handler. In Activity’s Onresume register this Handler with Application using static field of BluetoothRemoteControlApp.
As soon as Connection is dropped, Iterate over all the handlers and sendmessage.
In all Handler’s , handleMessage use finish().
In Onpause remove this handler from Application