Tag Archive: intent


When switching between activities (via Intents), it may be reasonable to distinguish between who started the activity and which activity is to be started. For that reason, Android allows to transfer a request code to the newly started activity. That activity can check who called it by taking a look at the request code.
So far this is easy. But if an activity is finished, the method onActivityResult of the original activity is called with the request code that the original activity transferred (to the finished activity). If you need to make a distinction which activity has finished, then your request codes should be properly defined. One way to achieve this is to have your request code include the source and the destination activity. If you use many many activities, you should think of an encoding for that, otherwise simply number the different combinations as in the class RequestCodes.

public class RequestCodes {
	//activity request_codes
	public final static int START_TO_CHOOSER = 1;
	public final static int START_TO_SETTINGS = 2;
          ...
}

In the following code snippet, different activities are launched, depending on the button clicked. The method startActivityForResult takes an intent and a request code as parameters. When clicking on the button with the id R.id.settings, the request code RequestCodes.START_TO_SETTINGS is used that tells the activity to be started (i.e. SETTINGS) that the source activity is START.

public void onClick(View target)
{
  int id = target.getId();
  switch(id)
  {
    case R.id.select:
      Intent chooserInt = new Intent(this, ChooserAct.class);
      startActivityForResult(chooserInt, 
        RequestCodes.START_TO_CHOOSER);  
      break;
    case R.id.settings:
      Intent settingsInt = new Intent(this, SettingsAct.class);
      startActivityForResult(settingsInt,
        RequestCodes.START_TO_SETTINGS);  
      break;
    default:
  }
}

Upon finishing of the SETTINGS activity, the request code additionally tells the START activity that the SETTINGS activity is the one that triggered the startActivityForResult method call.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	if (resultCode == RESULT_OK 
         && requestCode == RequestCodes.START_TO_SETTINGS)
	{
             ...
	}
	else if (requestCode == RequestCodes.START_TO_CHOOSER)
	{
		if (resultCode == RESULT_OK)
		{
			...
		}
		else if (resultCode == RESULT_CANCELED)
		{
			...
		}
	}
}

Suppose you want create an Android application (the main application) and several other applications that use your main application. The other applications bring data for your main application, extending it (so further on, I will call them extensions). Basically you need to solve two issues:

  • The main applications needs to know whether there are other applications that extend it.
  • The applications need to communicate with one another.

First of all, I tried to copy the data from the extension to the private data of the application upon installation of the extension. That means I searched for a kind of an onInstall event where I could execute custom code. This does not seem to be possible in Android.

Then I stumbled upon services and receivers. Now, my main application (package=“com.example“) sends a broadcast with an intent:

Intent intent = new Intent(action);
activity.sendBroadcast(intent);

The action string could be something like: your application package name + actions + a verb, such as COLLECT, e.g. com.example.actions.COLLECT.

My extension (package=“com.example.extensions.test“) uses a broadcast receiver with an onReceive() method to receive the sent broadcast of the main application:

public class TestReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
	Toast toast = Toast.makeText(context, "Received message",	Toast.LENGTH_LONG);
	toast.show();
          ...

Beside the Java code, you also need to configure the AndroidManifest.xml of the extension to make the receiver react to the above action:

<application>
  <receiver android:name="com.example.TestReceiver">
     <intent-filter>
       <action android:name="com.example.plugins.COLLECT"></action>
     </intent-filter>
  </receiver>
</application>

In the next step, I copy the data of the extension to the private area of the main application. This is possible by creating the context of the package of the main application. The new context can access the private data of the main application.

@Override   public void onReceive(Context context, Intent intent) {
...
  AssetManager am = context.getAssets();
  FileOutputStream fos;
  Context ctx;
  try {
    ctx = context.createPackageContext("com.example", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
    InputStream is = am.open(...);
    ...
    fos = ctx.openFileOutput(..., Context.MODE_PRIVATE);

To make the code above work, a sharedUserId has to be provided in both AndroidManifests, that of the main application and that of the extension.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     android:sharedUserId="com.example" ... >

In the main application, it is possible to list all private files:

String[] fileList = fileList();
for (String string : fileList) {
  ...
}