Allow other apps to launch your app

The first two lessons focus on one aspect: starting the activity of another application from your application. But if your application can perform operations that may be useful to another application, your application should be prepared to respond to operation requests from other applications. For example, if you build a social application that can share messages or photos with a user ’s friends, your primary concern is to support ACTION_SEND Intent so that users can initiate a “share” operation from another application and start your application to perform the operation.

To allow other applications to start your Activity, you need the corresponding file in the list of <activity>elements to add an <intent-filter>element.

When your app is installed on the device, the system will recognize your Intent filter and add information to the internal directory of Intent supported by all installed apps. When an application calls startActivity () or startActivityForResult () through an implicit Intent, the system will find an Activity that can respond to the Intent.

Add Intent filter

In order to correctly define the Intent that your Activity can handle, each Intent filter you add should be as specific as possible in terms of operation type and data accepted by the Activity.

If the Activity has an Intent filter that meets the following Intent object conditions, the system may send the given Intent to the Activity:

operating

  • A string named for the operation to be performed. Usually one of the platform-defined values, such as ACTION_SEND or ACTION_VIEW. Use <action>element specifies this value in your Intent filter. The value you specify in this element must be the full string name of the operation, not an API constant (see example below).

data

  • The data description associated with the Intent. Use an element to specify this content in your Intent filter. Using one or more attributes in this element, you can specify only the MIME type, URI prefix, URI scheme, or a combination of these, and other items that indicate the type of data accepted.

Note: If you do not need to declare specific information about the data Uri (for example, when your Activity handles other types of "extra" data instead of URI), you should only specify the android: mimeType attribute to declare the data type your Activity processes, such text / plain or image / jpeg.

category

  • Provide another method of characterizing the Activity that handles Intent, usually related to the user's gesture or the location where the Activity is started.
    The system supports many different categories, but most are rarely used. However, all implicit Intents are defined by default using CATEGORY_DEFAULT. Use the <category>element to specify this content in your Intent filter.

Intent on your filter, you can declare nested <intent-filter>elements having the corresponding XML elements to declare your Activity acceptable conditions.

For example, here is an Activity and an Intent filter that handles ACTION_SEND Intent when the data type is text or image:

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

Each incoming Intent specify only one operation and a data type, but in each of <intent-filter>the statements <action>、<category>and <data>multiple instances of elements.

If the behavior of any two pairs of operations and data are mutually exclusive, you should create a separate Intent filter to specify which operations are acceptable when paired with which data type.

For example, suppose your Activity handles both ACTION_SEND and ACTION_SENDTO Intent text and images. In this case, you must define two different intent filters for the two operations, because the ACTION_SENDTO Intent must use the data Uri to specify the recipient address using the send or sendto URI scheme. E.g:

<activity android:name="ShareActivity">
    <!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
    <intent-filter>
        <action android:name="android.intent.action.SENDTO"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="sms" />
        <data android:scheme="smsto" />
    </intent-filter>
    <!-- filter for sending text or images; accepts SEND action and text or image data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

Note: In order to receive implied intents, you must include the CATEGORY_DEFAULT category in the Intent filter. The methods startActivity () and startActivityForResult () will process all intents in the same way as the CATEGORY_DEFAULT category has been declared. If you do not declare it in the Intent filter, there is no implicit Intent decomposition into your Activity.

Handle the Intent in your Activity

In order to decide which operation to perform in your Activity, you can read the Intent used to start the Activity.

When your Activity starts, call getIntent () to retrieve the Intent that started the Activity. You can do this at any time in the Activity life cycle, but you should usually do it at an early callback (for example, onCreate () or onStart ()).

E.g:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // Get the intent that started this activity
    Intent intent = getIntent();
    Uri data = intent.getData();

    // Figure out what to do based on the intent type
    if (intent.getType().indexOf("image/") != -1) {
        // Handle intents with image data ...
    } else if (intent.getType().equals("text/plain")) {
        // Handle intents with text ...
    }
}

Return result

If you want to return the result to the Activity that called your Activity, just call setResult () to specify the result code and result Intent. When your operation is complete and the user should return to the original Activity, call finish () to close (and destroy) your Activity. E.g:

// Create intent to deliver some kind of result data
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"));
setResult(Activity.RESULT_OK, result);
finish();

You must always specify a result code for the result. Usually, it is RESULT_OK or RESULT_CANCELED. You can then provide additional data for the Intent as needed.

Note: By default, the result is set to RESULT_CANCELED. Therefore, if the user presses the back button before completing the operation action or setting the result, the original Activity will receive a "cancelled" result.

If you only need to return an integer indicating one of several result options, you can set the result code to any value greater than 0. If you use a result code to pass an integer and you do not need to include an Intent, you can call setResult () and pass only the result code. E.g:

setResult(RESULT_COLOR_RED);
finish();

In this case, there are only a few possible results, so the result code is a locally defined integer (greater than 0). This is very effective when you return the result to the Activity in your application, because the Activity that receives the result can refer to the public constant to determine the value of the result code.

Note: There is no need to check whether your Activity was started using startActivity () or startActivityForResult (). If the Intent that starts your Activity may require results, just call setResult (). If the original Activity has called startActivityForResult (), the system will pass it the result you provided to setResult (); otherwise, the result will be ignored.

Published 80 original articles · Like 319 · Visits 340,000+

Guess you like

Origin blog.csdn.net/jimo_lonely/article/details/53244348