Parse Intent to find matching Activity
If the component name (package name and class name) is explicit it intent, otherwise it is implicit intent. For explicit intent, the key is the component name. Other attributes declared in <intent-fliter> are ignored. For implicit intent, match based on action, category and data. However, one intent fliter can declare multiple actions, multiple categories, and multiple data attributes, so different intents can be satisfied.
If an action is set for implicit intent, the action must exist in <action nandroid: Name = "…"> under <intent-fliter>. However, unlike what is written in pro Android 4.0, after testing, we found that the action statement must exist in intent-fliter.
1) intent with Action Settings cannot match the action not defined in intent-fliter;
2) intent with no action set cannot match the action defined in intent-fliter;
3) intent without action settings can match any defined action in intent-fliter, But intent should provide sufficient filtering conditions, for example, the URI of data (the test shows that the category filter cannot match ).
At least in Android 4.2. Therefore, we should declare the action name in inter-fliter, and the intent should provide the action name. In special cases, if it cannot be provided, we need to provide the data attribute for filtering. However, this special case should not occur. In other words, we must perform action matching.
If data schema is set for implicit intent, it must match a data schema of intent fliter. If data schema is set for intent fliter, implicit intent must provide a valid data Uri and cannot be empty. In addition to schema, Uri also requires authority (domain), which is defined as follows in manifest.
<Data Android: Scheme = "wei" Android:Host= "Flowingflying.com"/>
Matched URI: Wei: // flowingflying.com /...., You can also use Android: path, Android: pathprefix, Android: pathpattern for further restrictions. For details, refer to http://developer.android.com/guide/topics/manifest/data-element.htm.
Similarly, data mimetype must be matched by both parties. If the data mimetype does not exist, it cannot be regarded as a match. Set by settype (), such as intent. settype ("text/html"); in addition, for subtype, you can use * as the wildcard, such as intent. settype ("text /*");
ACTION_PICK
Activity A calls Activity B through intent. In some cases, we want B to return information to a at the end so that a can determine the next step, this is also a way to use B as the UI. A common method is that B is the list UI. The following is a small example. We do not implement the list UI of B, but just simulate the selection of item and set the return value and return information, the returned information is carried by intent. In this example, B is automatically disabled.
Activity B Step 1: add the pick action to intent fliter of B in andriodmanifest. xml
<Activity ...... >
<Intent-filter>
... ...
<Data Android: Scheme = "wei"/>
<Action Android: Name = "android. Intent. Action. Pick"/>
<Category android: name = "android. intent. category. DEFAULT"/>
</Intent-filter>
</Activity>
Activity B Step 2: Set the return value and return information in B. In this example, the returned information simulates a NotePad Uri and automatically closes B.
......
Private void testPick (int itemIndex ){
// Because intent fliter can contain multiple actions, filter them first. Only PICK actions can return values.
If (Intent. action_pick.equals (this. getintent (). getaction ())){
// Sets the returned value RESULT_ OK and transmits the information through intent. In this example, the Uri is transmitted through data.
Setresult (activity. result_ OK/* return value */,
New intent ().SetData (getNoteUri (itemIndex ))
/* Intent carrying information */);
// Automatically closes Activity B. the return value is passed to Activity B only when Activity B ends. Of course, you can also manually end B, such as pressing the system return key.
Finish ();
}
}
Private Uri getNoteUri (int itemIndex ){
Return Uri. parse ("content: // com. google. provider. NotePad/notes/" + itemIndex );
}
Activity:
Private static final int PICK_REQUEST_CODE = 1000;
Private void invokePick (Activity activity ){
// Sets the intent that calls B. The action is PICK. In this example, setData is only for implicit matching.
Intent intent = new Intent (Intent. action_pick);
Intent. setdata (URI. parse ("Wei: // flowingflying.com/notes "));
// StartActivity is not used, because startActivity is similar to opening a modal dialog and callBack cannot be performed, so startActivityForResult () is used ()
Activity. startactivityforresult (Intent, Pick_request_code/* Request Code */);
// Because the PICK method can be used to evoke multiple different activities, all callBack triggers the onActivityResult () method, and request code is used for distinguishing.
}
// The onActivityResult () method of the Activity is rewritten. It is triggered when B ends. The first parameter requestCode is carried in startActivityForResult, it can be determined that the returned value is from that Activity; the second parameter is the return value of B. The system value is RESULT_ OK (-1), RESULT_CANCELED (1), or the user-defined value, the custom value must start with RESULT_FIRST_USER (1). The third parameter is the returned information carried by B through intent.
@ Override
Protected void onactivityresult (INT requestcode, int resultcode, intent outputintent){
// TODO Auto-generated method stub
Super. onActivityResult (requestCode, resultCode, outputIntent );
// In this example, only the returned results of Activity B are processed. The request code is PICK_REQUEST_CODE ){
If (requestCode! = PICK_REQUEST_CODE ){
Log. d ("WEI", "Some one else called this. not us ");
Return;
}
// If the returned value is not OK, that is, RESULT_CANCELED, It is not processed.
If (resultCode! = Activity. RESULT_ OK ){
Log. d ("WEI", "Result is not OK ");
Return;
}
// Read the information carried by intent
Uri uri = outputIntent. getData ();
Log. d ("WEI", "uri is" + uri. toString ());
// Process according to the carrying information: In this example, B returns the content Uri of a NotePad, which is used to open the NotePad. NotePad is not available on the simulator. we can import it using sample. For details, see the appendix at the end of this blog.
StartActivity (new Intent (Intent. ACTION_EDIT, uri ));
}
ACTION_GET_CONTENT
ACTION_GET_CONTENT is very similar to ACTION_PICK. ACTION_PICK is a URI. The system gives one or more matching options to the user. After execution, the returned value of the Activity is returned to the caller. ACTION_CET_CONTENT is based not on URI, but on MIME Type.
In this example, NotePad is used. See the appendix at the end of this article: Install NotePad for the simulator. Let's take a look at the Manifest. xml file of the sample NotePad. This file shows the coexistence of multiple intent-fliter instances, which are applicable to application startup, PICK and GET_CONTENT respectively.
<Activity android: name = "NotesList" android: label = "@ string/title_notes_list">
<Intent-filter>
<Action android: name = "android. intent. action. MAIN"/>
<Category android: name = "android. intent. category. LAUNCHER"/>
</Intent-filter>
<Intent-filter>
<Action android: name = "android. intent. action. VIEW"/>
<Action android: name = "android. intent. action. EDIT"/>
<Action android: name = "android. intent. action. PICK"/>
<Category android: name = "android. intent. category. DEFAULT"/>
<Data android: mimeType = "vnd. android. cursor. dir/vnd. google. note"/>
</Intent-filter>
<Intent-filter>
<Action android: name = "android. intent. action. GET_CONTENT"/>
<Category android: name = "android. intent. category. DEFAULT"/>
<Data android: mimeType = "vnd. android. cursor. item/vnd. google. note"/>
</Intent-filter>
</Activity>
Code writing is similar to PICK:
Private static final int REQUEST_CODE_GET_CONTENT = 101; Private void invokeGetContent (Activity activity ){ Intent intent = new Intent (Intent. ACTION_GET_CONTENT ); Intent. settype ("Vnd. Android. cursor. Item/vnd. Google. Note ");// GET_CONTENT for MIME TYPE
Activity. startactivityforresult (intent, request_code_get_content );
}
@ Override // receives the response from Acivity. Protected void onactivityresult (INT requestcode, int resultcode, intent outputintent){
If (resultCode! = Activity. RESULT_ OK ){ Log. d ("Wei", "Result is not OK "); Return; }
Switch (requestCode ){ Case REQUEST_CODE_PICK: ...... // Process ACTION_PICK. refer to the previous example. Break; Case REQUEST_CODE_GET_CONTENT: Uri uriContent = outputIntent. getData (); Log. D ("wei", "URI is" + uricontent. tostring ());
Startactivity (new intent (intent. action_edit, uricontent )); Break; Default: Showinfo ("some one else called this. Not us "); Break; } } |
Pending Intent
Intent can be used as a parameter in PendingIntent. PengdingIntent, as its name implies, is not called immediately. It can be invoked only after an event is triggered. For example, if you want to use it in a Notification, you can call it only when the user clicks the Notification. For more information, see Android learning notes (May 4): Notification (on). For example, warning. For example, when the geographical location matches, see Android Study Notes (five or six): Location. The instant inceptor process (Application) does not exist, and PendingIntent can still be well saved, so that it is convenient to call the process after the process ends or other processes.
Let's make a small experiment to see how PendingIntent is built:
Public static PendingIntent getActivity (Context context, int requestCode, Intent intent, int flags)
Public static PendingIntent getActivities (Context context, int requestCode, Intent [] intents, int flags)
Intent intent = new Intent (this, IntentBasicViewActivity. class );
// Normal intent
PendingIntent pi = PendingIntent. getActivity (getApplicationContext (), 0, intent, 0 );
ShowInfo ("intent is" + intent );
// ShowInfo () is displayed in both the LogCat and UI windows.
ShowInfo ("pending intent is" + pi );
Pendingintent PI1 = pendingintent. getactivity (getapplicationcontext (),0, Intent, 0 );
Showinfo ("pending intent is" + PI1 );
Pendingintent Pi2 = pendingintent. getactivity (getapplicationcontext (),1, Intent, 0 );
Showinfo ("pending intent is" + Pi2 );
Why is it so strange to use getactivity. A normal intent can call activity by startactivity (intent), startservice (intent), and sendbroadcast (intent) to enable the Service and arouse broadcast referers. Since the intent parameter in pendingintent is used to actually evoke the corresponding activity, service, or broadcast receiver, it is necessary to tell whether the system is activity, service, or broadcast. There will also be:
Getbroadcast (context, int requestcode, intent, int flags)
Getservice (context, int requestcode, intent, int flags)
As to why getxxxx is used, according to pro Android 4.0, Android stores pendingintent and can be reused multiple times (depending on the flag parameter settings ), if you want to use the same intent, you need to get the same pendingintent. If you want to differentiate, you can set different requestcodes.
For flags, the following parameters are available:
[1] FLAG_CANCEL_CURRENT: if an identical PendingIntent object already exists in the current system, the existing PendingIntent is canceled first, and a new PendingIntent object is generated.
[2] FLAG_NO_CREATE: if the same PendingIntent object does not exist in the current system, the system will not create this PendingIntent object, but will return null directly.
[3] FLAG_ONE_SHOT: The PendingIntent only works once. After the PendingIntent object is triggered by the send () method, PendingIntent will automatically call cancel () for destruction. If you call the send () method again, the system will return a SendIntentException.
[4] FLAG_UPDATE_CURRENT: if the system has a PendingInent equivalent to the PendingIntent you described, the system uses the PendingIntent object, however, the new Intent will be used to update the Intent object data in the PendingIntent, for example, updating the Extras in the Intent.
[Note] This is an explanation of several flags. For details, refer
If we get a PendingIntent and want to evoke the Intent, you can use
Pi.Send(RESULT_CODE); // PendingInten multiple send Methods
Appendix: Install NotePad for the simulator
Download the sample code from the Android SDK Manager and add it to the simulator according to the operation.
In order to have a better user experience in PICK and GET_CONTENT calls, after the item is selected, NotePad activity can be automatically disabled. Add the following code to NotesList. java:
Protected void onListItemClick (ListView l, View v, int position, long id ){
......
// Handles requests for note data
If (Intent. ACTION_PICK.equals (action) | Intent. ACTION_GET_CONTENT.equals (action )){
// Sets the result to return to the component that called this Activity.
// Result contains the new URI
SetResult (RESULT_ OK, new Intent (). setData (uri ));
// Wei Add the following: close NoteList automatically
Finish ();// Wei Add
......
}
Related links:
My android development articles