Android is saturated with Inter Process Communication (IPC) mechanisms used for both cross system and process communication (i.e. Binder, Sockets, and IOCTL calls) and for inter application communication (i.e. Intents and Broadcasts). This article will focus on Android Intents, one of the simplest and most used IPC techniques for inter app communication in Android. 

WHat Is an Intent?

Intents allow for applications to communicate (e.g., send data or initiate an action) with other Android components on the device, even if the recipient is not currently running. This means that an application can send intents to a wide variety of Android components – including application activities (using startActivity() or startActivityForResult()), background services (using startService()), and broadcast receivers (usingsendBroadcast() or sendOrderedBroadcast()). An application can send an intent that will fall into one of two (or three, depending on how you look at it) categories, these being:

  • Explicit – Explicit intents are intents that specify the application or both the application and component that will action the request.
  • Implicit – Implicit intents are more vague and specify a type of action that is desired (e.g., opening a camera or location application).
  • Broadcasts – These broadcast messages, which can be sent by the Android system or applications, are simultaneously received by all applications on the device that have previously registered for the specific broadcast action type.

An Intent class object is created in Java or Kotlin and has several core and additional attributes. These can be seen below:

  • Action (Core) –  Settable using an initialized Intent object’s setAction method. The action defines the high-level action to be performed.
  • Category (Core) –  Settable using an initialized Intent object’s setData method. The data field includes the data this intent is operating on (e.g., a file to open in an image editing app).
  • Type (Additional) – Settable using an initialized Intent object’s addCategory method. Categories provide additional context about the action to be performed by the intent. Only activities that can facilitate all specified categories can be chosen to receive the intent.
  • Component (Additional) – Settable using an initialized Intent object’s setComponent method. This attribute identifies the name of a component class to use for the intent. This is an optional attribute as it is normally identified based on the content of the intent.

intent filters

All components should have an android:exported tag. This is false by default, and if it is false, then the component can only receive messages from inside of its application. By adding any intent filters, this is automatically true and means that external applications can interact with the component. These intent filters are also used to advertise the component when the system receives an implicit intent.

The following is an example of a typical entry point (as defined in the Android Manifest) to an application with the MAIN action and LAUNCHER category set. The main action defines that this component should be started as the entry point to the application and that it does not receive any data. The launcher category defines that the activity should be displayed in the top-level launcher.

<intent-filter> 
     <action android:name="android.intent.action.MAIN" /> 
    <category android:name="android.intent.category.LAUNCHER" /> 
</intent-filter>

Receiving and Sending

Below are several examples of how intents can be used inside of an application to communicate with internal or external components:

Starting an internal activity with data:

public void sendIntentToActivityInApp(){
    Intent intent= new Intent(this, IntentReceiver.class);
    // Update class to be internal class (to the application) to receive the intent
    Bundle bundle= new Bundle();
    bundle.putString("key", "value");
    intent.putExtras(bundle);
    startActivity(intent);
}

Receiving an intent bundle in an activity:

protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getIntent().hasExtra("key")) {
        String value = getIntent().getExtras().getString("key");
        Log.v(this.getClass().getSimpleName(), value);
    }
}

Starting an external application:

public void startActivityViaIntent(){
    Intent launchIntent = getPackageManager().
    getLaunchIntentForPackage("com.android.chrome");
    startActivity(launchIntent);
}

Starting a specific activity of an external application:

public void sendIntentToAnotherActivity(){
    Intent intent = new Intent();
    intent.setClassName("com.android.chrome", "com.google.android.apps.chrome.Main");
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) ;
    startActivity(intent);
}

 

Read More

This article was derived from a chapter in my book Android Software Internals Quick Reference. If you found it interesting please think about picking the book up for yourself! 

 

 

 

Adverts