What's alternative menu (Alternative menu)
For example, activity displays a text file. If a user wants to edit a text file, activity does not provide editing power, but it can be provided by other activity or other apps. We store the relevant information in a intent, such as the URI of the text. This intent can be used to match multiple applications of the system, and the alternate menu lists the apps, and the title of the menu item is the name of the activity that can be called, and the icon is the graph of the activity that can be called.
Small example Description
We learn through a small example and simply open a url:wei://flowingflying/helloworld. In previous Intent's study, we were able to open the URL by matching the URL with the schema configuration, that is, the activity (Intent Basic Test) that we already have for other applications. We can also open the URL by adding an activity to the app. This will add two menu items to the Alternative menu, click on them, open the corresponding activity, and pass the relevant data information through intent.
The new acitivity name is the Invoke Action (as if it should be invoked, sorry). Add a description of Intent-fliter in Androidmanifest.xml, see: Pro Android Learning Note (11): Learn about Intent (medium).
<activity android:name= ". Invokeaction "android:label=" @string/invokeaction "android:icon=" @drawable/leaf ">
<intent-filter >
<action Android:name= "Android.intent.action.VIEW" />
<data android:scheme= "Wei"/>
<category android:name= "Android.intent.category.DEFAULT"/>
<category Android:name= "Android.intent.category.ALTERNATIVE"/><!--will be discussed at the end of this page-
</intent-filter>
</activity>
Alternative Menu Code
Let's see how to add the alternate menu to the Optionmenu. Alternative menu can also be loaded in Submenu,context menu.
@Override
public boolean Oncreateoptionsmenu (Menu menu) {
Contrast: Add a regular menu item
Menu.add ("ordinary menu item");
//"Step 1" Setup Intent, this example is simple and useful for a known URI.
Intent menuintent = new Intent (Null,uri.parse ("Wei://flowingflying/helloworld"));
//"Step 2" Join alternative menu。 As already mentioned in the previous item ID category, Android has a alternative ID range.
int menugroup = menu.category_alternative;
int startingitemid =menu.category_alternative;
int orderId = menu.category_alternative;
Menu.addintentoptions(//Returns the number of added menu items, this example is 2
Menugroup,/* int groupId */
Startingitemid,/* int itemId: This parameter can be set to Menu.none because it jumps automatically. */
OrderId,/*int order*/
This.getcomponentname (),/* componentname Caller: Current activity name, which is the Android system processing Alternatice menu is the parameter that is required to invoke the Queryintentactivityoptions () function. Getcomponentname () returns the package name and class name, which is the system to learn who the source activity is. */
NULL,/* intent[] specifics: match may have more than one Intent, this is used for filtering, but the specific purpose is unknown */
Menuintent,/* Intent Intent: Key Intent */
0,/* flages: about how items are added. 0 means no flag*/
NULL); /* menuitem[] outspecificitems, related to Specifice */
return Super.oncreateoptionsmenu (menu);
}
About category and canonical code notation
We notice that in the evoked actvity there is the following description:
[HTML]View Plaincopy
- <category android:name="Android.intent.category.ALTERNATIVE" />
In the experiment, it was found that this was dispensable and did not really affect the result. In reference, it is clear that the category_alternative or category_selected_alternative. Why?
We call other activity as alternative menu, and the normal practice is that the aroused activity should be allowed to be aroused by the alternative menu. So the awakened activity needs to be given a category in the Intent-fliter. At the same time alternative menu intent should also indicate their own type. So the code for the specification is:
Intent menuintent = new Intent (Null,this.getintent (). GetData ());
menuintent.addcategory (intent.category_alternative);
In the small case, because the activity of other applications (Intent Basic Test) is not given a corresponding category in the manifest XML, it is not matched. Run results
About Flags
The penultimate parameter of Menu.addintentoptions () is flags, which indicates how the menu item is added. 0, which is the default, means that if the groupid is the same, the alternative menu replaces the original menu item setting. If we want to keep the original menu item of the same GROUP, we can set the flags to Menu.flag_append_to_group. Note that if GroupID is Menu.none is not replaced, this indicates that GroupID is not set, not GroupID is 0.
Multiple matching parameters such as Itemid
Let's see how the system implements the alternative menu. As seen from reference, menu is a interface, specifically through the Menubuilder implementation (source code see ANDROID-17 (version)/com/android/internal/view/menu/ Menubuilder.java. The relevant code is as follows:
public int addintentoptions (int group, int id, int categoryorder, componentname caller,
Intent[] Specifics, Intent Intent, int flags, menuitem[] outspecificitems) {
Packagemanager pm = Mcontext.getpackagemanager ();
Final list<resolveinfo> LRI =//Query matching activity information
Pm.queryintentactivityoptions (caller, specifics, intent, 0);
Final int N = LRI! = null? Lri.size (): 0;
The following shows that if flag represents flag_append_to_group, the entire GROUP will be deleted and replaced
if ((Flags & flag_append_to_group) = = 0) {
Removegroup (group);
}
for (int i=0; i<n; i++) {
Final ResolveInfo ri = Lri.get (i);
Intent rintent = new Intent (
Ri.specificindex < 0? Intent:specifics[ri.specificindex]);
Rintent.setcomponent (New ComponentName (
Ri.activityInfo.applicationInfo.packageName,
Ri.activityInfo.name));
Final MenuItem item = Add (group, ID, Categoryorder, Ri.loadlabel (PM))
. SetIcon (Ri.loadicon (PM))
. Setintent (rintent);
if (outspecificitems! = null && ri.specificindex >= 0) {
Outspecificitems[ri.specificindex] = Item;
}
}
return N;
}
From the source code, it may be seen that if there are multiple matches, these menu items have the same group, the same ID, and the same categoryorder. Although we used startingitemid in a small example, the Itemid is actually the same. In the small example, we added the public boolean onoptionsitemselected (MenuItem Item) and checked the value of the item's parameters inside, confirming that it was true.
This code also explains the name and picture of the menu item, and why it evokes activity. Using Setintent (), is in Pro Android Learning Note (30): Menu (1): Learn about a trigger mechanism that Menu has learned.
This post covers example code that can be downloaded in Pro Android Learning: Menu.
Pro Android Learning Note (33): Menu (4): Alternative menu