Android Quick Tips #7 — Intents

We've been through various Android Quick Tips. This week we'll focus on Intents.

Android Quick Tips #1 Series Overview

Internal use of startActivityForResult()

Every Android developer is aware of the startActivityForResult(Intent i) to call external apps to do something specific and get the result back, like calling the camera app to take a photo. However, startActivityForResult(Intent i) isn't used as much internally. The best example is if your app has a LoginActivity. That LoginActivity often is not part of a forward flow, it's rather a one-time thing, which fulfills a specific action with a result.

So, instead of building a funky combination of startActivity() and finish() in the LoginActivity, this is going to be a better, cleaner solution. The calling activity calls the login activity and signals that it would like to have a result with:

public final static int LOGIN_REQUEST_CODE = 1;

public void loginButtonClick(View view) {  
    Intent intent = new Intent(MainActivity.this, LoginActivity.class);
    startActivityForResult(intent, LOGIN_REQUEST_CODE);
}

This will open the LoginActivity. The LoginActivity then handles the login and should send a result back, for example a User object in case the login was successful, or an error message in case it wasn't successful.

bool loginSuccessful = true; // or false, depending on the login  
String errorMessage = .. // set when there was an error

if (loginSuccessful) {  
    setResult(RESULT_OK); // you can call setResult() without additional data
}
else {  
    // you can call setResult() with additional data by passing an intent
    Intent resultIntent = new Intent();
    resultIntent.putExtra("error", errorMessage);
    setResult(RESULT_CANCELED, resultIntent);  
}

finish();  

In either case, this will send data back to the calling MainActivity. The MainActivity has to receive the result and take the appropriate action:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    if (requestCode == LOGIN_REQUEST_CODE) {
        if (resultCode == RESULT_OK){
             // todo login was successful, take appropriate action
        }
        else if (resultCode == RESULT_CANCELED) {
            // login failed, get error message
            String errorMessage = data.getStringExtra("error");

            // todo take appropriate action matching the error message
        }
    }
}

This should give you a good example of how clean and easy it is to implement an Activity, which returns a result. Take a look at these two links if you want to know more:

Difference between Intent.ACTION_CALL and Intent.ACTION_DIAL

We've seen it multiple times that Android developers are not aware of the subtle difference between Intent.ACTION_CALL and Intent.ACTION_DIAL.

Intent.ACTION_CALL opens the phone app, dials and calls to a number. The user has no option of reviewing the phone call before its actually made. That's why the Intent.ACTION_CALL requires an extra permission:

<uses-permission android:name="android.permission.CALL_PHONE" />  

In almost all use cases, it's sufficient and user friendlier to just pull up the phone app and dial the number, but not hit the virtual green "call" button. The user has to decide himself if he really wants to call the number, or if he just hit the wrong button. This requires no permission.

We hope you learned a little bit about Intents today. Let us know your Intent tips in the comments!

Explore the Library

Find interesting tutorials and solutions for your problems.