Android Development - (3) Intents 👽

An intent is an “intention” to perform an action. It is basically a message that allows us to request functionality
from other components.

Intents allow us to chain independent components to accomplish
different tasks.

Intents are objects of android.content.Intent.

Explicit Intents

Are used to call a specific component. If we want
ActivityOne to launch ActivityTwo when a button is
clicked, this is an explicit intent.

explicit intent

Intent i = new Intent(this, ActivityTwo.class);
startActivity(i);

Implicit Intents

Are used when you know what you want to do, but you do not
want to specify exactly which component should be used. Android evaluates the request at runtime to choose a component.

Implicit intents can give the user an option to choose between a list of apps. This is a common scenario when you need to do something like open a hyperlink for a webpage, a list of external apps are shown to the user.

//view a webpage using an implicit intent
String url = "http://www.example.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);

Intent filters

In the previous example, how does Android know which apps can display a webpage?

Intent filters provide the ability to evaluate if an activity can satisfy an intent. This process is known as intent resolution.

To make sure it’s the right activity for the intent, the intent filter provides three criteria:

If Android finds a single match for an implicit intent, it starts the component, and passes it the intent. If it finds multiple matches, it asks the user to pick one.

Example: Main Activity

We have seen this already. This is the entry point to our app.

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

Example: Open a webpage

<activity android:name=".BrowserActivitiy"
android:label="@string/app_name">

<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>

Example: Get an image

<activity
android:name=".GetImageActivity"
android:label="@string/app_name" >

<intent-filter>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="image/*" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>

What if you want the user to choose an app every time in response to an implicit intent?

If multiple apps can respond to an intent and the user might want to use a different app each time, you should explicitly show a chooser dialog. The chooser dialog asks the user to select which app to use for the action (the user cannot select a default app for the action).

For example, when your app performs “share” with the ACTION_SEND, users may want to share using a different app depending on their current situation.

To show the chooser, create an intent using createChooser() and pass it to startActivity(), as shown in the following example.

Intent sendIntent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);

//if no activities are resolved for this intent, a
//message will be shown informing the user
Intent chooser = Intent.createChooser(sendIntent, title);

startActivity(chooser);

Passing data between Activities

An intent can have data that is stored in a Bundle. You add data directly to the Bundle via the overloaded putExtra() methods of an intent.

Data is stored as key/value pairs. The key is always of type String. As value, you can use the primitive data types (int, float, …​), and objects of type String, Bundle, Parcelable and Serializable. You can read this to know how to pass a custom object of Parcelable and Serializable.

Intent i = new Intent(this, ActivityTwo.class);
i.putExtra("Value1", "This value one for ActivityTwo ");
i.putExtra("Value2", 2.0);

The data in an intent can be used by the receiving component. You use getExtras() to retrieve all of the values in the Bundle.

Bundle extras = getIntent().getExtras();
String value1 = extras.getString("Value1");

There is also some convenience methods to retrieve a single
value such as getStringExtra(..), getIntExtra(..).

Intent intent = getIntent();
String value1 = intent.getStringExtra("Value1");
int value2 = intent.getIntExtra("Value2");

Exercise: Login

Create a basic login.

login page welcome page after login has taken place
public class LoginActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
}

public void onClick(View view){
EditText username = (EditText) findViewById(R.id.username_input);
EditText pass = (EditText) findViewById(R.id.password_input);

String username_text = username.getText().toString();
String pass_text = pass.getText().toString();

if(username_text.equals("admin") && pass_text.equals("password")){
Intent i = new Intent(this, HomeActivity.class);
i.putExtra("username", username_text);
startActivity(i);
}
else{
Toast.makeText(this, "Incorrect username and password combination",
Toast.LENGTH_LONG).show();
}

}
}

public class HomeActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
TextView welcome = (TextView) findViewById(R.id.welcome);

String username = this.getIntent().getStringExtra("username");
welcome.setText("Welcome " + username + "!");
}
}

References