Overview
Applications (or programs) on Android are considered to be "activities". Your app itself is a single activity. Clicking on a hyperlink in your app and open up a browser means your app has started an internet browser sub-activity.
When you open up your contacts list to look for a person to call, that is also an activity. Same when an app asks you to select a file, the file selection activity will return the selected filename to the app which initiated it.
An important thing to note is that when the sub-activity starts, the initial activity will still continue to run in the background. Hitting the back button will (usually) kick you back into the initial app with the default result of Activity.RESULT_CANCELED.
You can start a sub-activity with one of the two expectations: "fire and forget" or "wait for result".
Fire and forget is usually a web browser. You send the user off to browse for something and when they're done then they can resume using your app.
Wait for result will start the sub-activity and wait until you've returned with some data. A callback is triggered in the initial activity which will let you manipulate the data accordingly.
Data can be shared between activities by sending data "bundles". You may have noticed this already when setting up your first activity in the onCreate(Bundle savedInstanceState) method.
Setting up an activity
First you'll need to configure your AndroidManifest.xml to allow for the starting of the activity. Otherwise it'll return with an error stating the activity is not found.
Using Eclipse, open up AndroidManifest.xml and go to the "Application" tab. At the bottom there is an area called "Application Nodes".
Click on the "Add" button, and select "Create a new element at the top level, in Application".
Now select that new new Activity and click on "Browse" for the "Name" field. Select the activity which this meta data will apply to.
Now to create an intent filter for it. Click "Add" again and this time select "Intent filter". Click "Add" again to add the actual intent. I used "Action" with intent "android.intent.action.VIEW" for this example.
Intent filters kind of specify what sort of activity it is. The docs can explain it way better than I can, but the basic concept behind it is to prevent you from starting a "make a call" activity with the intention of "selecting a file". It'll also allow your app to be used as various context handlers on your phone (such as "Send file to; bluetooth, messaging, dropbox, your app, Facebook, etc)".
If you want the XML for it:
<activity android:label="@string/app_name" android:name=".scoring.SubmitScoreActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
The "activity" element should go under "application".
Your sub-activity setup is now complete.
Firing up the activity
When you're ready, start setting up the intent to start the activity.
Intent intent = new Intent(G.activity, SubmitScoreActivity.class);
That's all there is to it!
Using the submitting score example, the snippet below is used to send information to the activity.
Bundle map = new Bundle();
map.putInt("score", G.gameState.getScore());
map.putString("username", G.settings.username);
intent.putExtra("SubmitScoreActivity", map);
Now remember the thing I said about "fire and forget" and "wait for result"? It's now time for you to choose.
To fire and forget, start the activity with:
yourActivity.startActivity(intent)
To wait for a result, use:
yourActivity.startActivityForResult(intent, ACTIVITY_ID_SUBMIT_SCORE)
The ACTIVITY_ID_SUBMIT_SCORE integer is just an ID that we give it so the callback function can tell which activity finished. I'll explain it a little later.
Note: Your current activity will continue to run even while it is waiting for a result.
Coding new sub-activity
Coding your new sub-activity is no different from creating a normal activity. Just remember that you should be pulling data out of the intent bundle.
public class SubmitScoreActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
this.setContentView(R.layout.score_submit);
Bundle map = getIntent().getExtras().getBundle("SubmitScoreActivity");
TextView txtScore = (TextView) findViewById(R.id.txtScore);
int score = map.getInt("score");
txtScore.setText(String.valueOf(score));
}
}
So now you know how to start an activity, pass data to it and pull data out.
Ending your sub-activity
So now that you need to end the sub-activity, you have to consider if you want to send data back or not.
If not then call Activity.finish() as you normally would and back you'll go to the main activity.
If you're waiting for a result, you've got a bit more work to do.
When you're ready to go back to the main activity:
Intent intent;
intent = new Intent();
intent.putExtra("score_submitted", true);
setResult(RESULT_OK, intent);
finish();
The RESULT_OK means this finished properly. In the same manner you send data to the sub-activity, you can use an Intent to send data back to the main activity.
Receiving the data
If you're waiting for a result, you'll also need to override onActivityResult() in your Activity so you can actually do something with the incoming data.
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // See which sub activity has finished switch (requestCode) { case ACTIVITY_ID_SUBMIT_SCORE: { // Check resultCode to see if it finished correctly if (resultCode == RESULT_OK) { boolean score_submitted = false; if (data != null) { score_submitted = data.getBooleanExtra("score_submitted", false); } if (score_submitted) { Toast toast = Toast.makeText(this.getBaseContext(), "Score submitted", Toast.LENGTH_LONG); toast.show(); } return; } default: break; } } }
And there you have it. It may be a long explanation, but it took me a while to get that all working properly so I put more detail into the post.
Hope it helps!
Sources