How to Filter and match Intent objects and Intent filters in Android

Source: Internet
Author: User

How to Filter and match Intent objects and Intent filters in Android

If you do not have a special understanding of Intent, you can refer to the blog "Intent overview and use in Android". This article gives a detailed introduction to the action, category, and data to be used in this article.

The content of this article is a bit long. I hope you can read it with patience.

This article uses Intent-Filter to describe the intent filter filters registered by the component in manifest.

Overview

We know that Intent has two types: explicit Intent and implicit Intent. If an Intent explicitly specifies the complete Class Name of the component to be started, the Intent is an explicit Intent, otherwise it is an implicit Intent. When an explicit Intent is used to start a component, Android directly finds the component to be started based on the component name provided by the Intent object, when we use an implicit Intent to start a component, the Android system cannot directly know the name of the component to be started, this article explains how to find and match the components to be started based on the implicit Intent.

When the Android system receives an implicit Intent to start an Activity (or other components, android compares the Intent information with the intent-filter information of the registered component based on the following information to select the most matched Activity (or other components) for the Intent ):

Data in category intent of action intent in intent (including the MIME type of Uri and data)

That is, the implicit intent object must meet the requirements of intent-filter registered in the target component to be started., ,The information in the three tags must pass the action test, category test, and data test respectively. Intent-filter information is described in the manife file of Android. As the name suggests, intent-filter is an intent filter, which is used to filter intent.

If the implicit intent object passes the intent-filter action test, category test, and data test of a component at the same time, the component can be started by the intent object. If the implicit intent object does not pass the intent-filter test of any components in the system, no Android system can find the component to be started for this intent object. Next, let's take a look at how we can pass these three tests.

Action Test

To specify the Intent type that can be received and processed, the component can declare in intent-filter that it supports 0 or more actions, for example:


              
   
  

The intent object can use the setAction () method to set a unique action value. There are two scenarios for action testing:

The intent object sets the action
If the intent object sets the action value by calling the setAction () method, the action test is successful only when the intent-filter of the component contains the action value of the intent object, otherwise, it fails.
For example, assume that the intent-filter of our Activity is as follows:


           
      
    
   
  

The following intent object can be tested using the action in intent-filter:

Intent intent = new Intent();intent.setAction(com.ispring.action.ACTION_TEST1);Uri uri = Uri.parse(ispring://blog.csdn.net/sunqunsunqun);intent.setData(uri);

The intent can pass the action test because the intent-filter contains the intent action value com. ispring. action. ACTION_TEST1.

The following intent object cannot pass the action test in intent-filter above:

Intent intent = new Intent();intent.setAction(com.ispring.action.ACTION_TEST3);Uri uri = Uri.parse(ispring://blog.csdn.net/sunqunsunqun);intent.setData(uri);

The intent cannot pass the action test because the intent-filter does not contain the intent action value com. ispring. action. ACTION_TEST3.

Action is not set for intent object
If the intent object does not call the setAction () method to set the value of action, if intent-filter has at least one arbitrary action value, the intent object can be tested by the action of the intent-filter. If no action is defined in the intent-filter, the intent object cannot be tested by the action of the intent-filter.
For example, assume that our intent object is as follows:

Intent intent = new Intent (); // do not set the action value // intent. setAction (com. ispring. action. ACTION_TEST1); Uri uri = Uri. parse (ispring: // blog.csdn.net/sunqunsunqun); intent. setData (uri );

The above intent object can be passed through the following intent-filter:


          
       
    
   
  

The above intent object cannot pass the following intent-filter:


      
       
    
   
  

Through the above examples, we must have understood the action test rules. The use of the category and data labels above will be described in detail below.

There are two conclusions:
1.To allow the intent object to pass the action test, the action declared in intent-filter cannot be empty and must contain the action value in the intent object (if the intent action value is not empty ).
2.If intent-filter does not declare any action, all intent objects (regardless of how intent is configured) cannot be tested using the action of intent-filter.

Category Test

To specify the type of Intent that can be received and processed, the component can declare in intent-filter that it supports 0 or more category, for example:


      
       
    
         ...
    
   
  

The intent object has the addCategory () method, that is, one intent object can also be associated with multiple category. To allow the intent object to pass the category test of intent-filter, all category items of the intent object must be found in intent-filter.
Specifically, there are two situations:

The intent object must have at least one category.
In this case, if the intent object has N category (N> = 1), the intent-filter must contain at least N category, and the intent object can pass the category test, otherwise, the test fails.
For example, suppose our intent-filter is as follows:


          
       
        
     
    
   
  

The following intent objects can be tested using category

Intent intent = new Intent();intent.setAction(com.ispring.action.ACTION_TEST1);intent.addCategory(com.ispring.category.TEST1);intent.addCategory(com.ispring.category.TEST2);

This intent object can pass the category test because intent-filter contains all the category values of this intent pair: com. ispring. category. TEST1 "and com. ispring. category. TEST2.

The following intent objects cannot pass the category Test

Intent intent = new Intent();intent.setAction(com.ispring.action.ACTION_TEST1);intent.addCategory(com.ispring.category.TEST1);intent.addCategory(com.ispring.category.TEST3);

The intent cannot pass the category test of intent-filter above because intent-filter only contains the value of com. ispring. category. the category of TEST1, but does not contain the value com. ispring. category. the category of TEST3 cannot fully contain all the category in intent.

The intent object does not contain any category.
If the intent object has not called the addCategory () method, the intent object does not contain any category. In this case, the intent object can always pass the category test of intent-filter regardless of how the category is configured in intent-filter, even if no category is declared in intent-filter, intent can all pass the category test.

Note that in all the examples above, the intent-filter value of the Activity isandroid.intent.category.DEFAULTThis is because when we pass an implicit intentstartActivity()OrstartActivityForResult()Android automatically adds the value of this implicit intentandroid.intent.category.DEFAULTSo in order to make the intent-filter contain all the category in the intent, we need to add the category in the intent-filter of the Activity.

Based on the examples above, we can summarize them as follows:
1.Intent that does not contain any category can always be tested by all any intent-filter category;
2.If the intent object contains at least one category, you can pass the category test only when the category declared in intent-filter contains all the category of the intent object.
3.To enable an Activity to be started by an implicit Intent, we must declare the valueandroid.intent.category.DEFAULT.

Data Testing

To specify the data of Intent that can be received, intent-filter must declare more than 0Tag, for example:


      
           ...
  

EachA tag can specify a URI structure and the MIME type of data. A complete URI consistsscheme,host,portAndpathThe structure is as follows:

:// : /

Scheme can be a common protocol in Android or a custom protocol. Common protocols in Android include the content protocol, http protocol, and file protocol. Custom protocols can use custom strings.

The following is a content protocol URI:
content://com.example.project:200/folder/subfolder/etc
In this URI, scheme is content, host is com. example. project, port is 200, and path is folder/subfolder/etc.

The following is a custom protocol URI:
ispring://blog.csdn.net/sunqunsunqun
In this URI, the scheme is ispring, the host is blog.csdn.net, the port is not explicitly set, and the path is sunqunsunqun.

The attributes that constitute the URI areTags are optional, but there are the following dependencies:

If no scheme is specified, the host parameter is ignored. If no host is specified, the port parameter is ignored. If neither scheme nor host is specified, the path parameter is ignored.

When we compare the Uri parameter in the intent object withWhen the URI format specified by the tag is different, we only compareThe part specified by the tag, for example:

If only scheme is specified in intent-filter, all URIs with the sheme can match the intent-filter. If only scheme and authority (authority includes host and port) are specified in intent-filter, but path is not specified, all URIs with the same scheme and authority can match the intent-filter without considering the value of path. If both scheme, authority, and path are specified in intent-filter, only URIs with the same scheme, authority, and path can match the intent-filter.

Note that the intent-filterWhen specifying the path value for a tag, you can use wildcards in it.*.

The data test requires that the URI, MIME type and intent-filterThe URI and MIME types specified in the tag are compared.
We know that one intent-filter can have multipleTag, intent object does not need to pass allTag testing. Generally, only one of our intent objects needs to passThe intent object passes the data test of the intent-filter.
The comparison rules are divided into the following situations:

The intent object does not contain the URI and MIME types.
In this case, you can pass the data test only when intent-filter does not specify any URI or MIME type.
For example, we have the following intent object:

Intent intent = new Intent();intent.setAction(com.ispring.action.ACTION_TEST1);

The above intent object can be tested using the following intent-filter data:


          
   
  

The above intent object cannot be tested using the following intent-filter:


          
       
    
   
  

Intent object contains URI but does not contain MIME type
In this case, you can pass the data test only when the URI of the intent object matches the URI format in the intent-filter and the intent-filter does not specify the MIME type.It should be noted that the intent-filter mentioned here does not specify the MIME type, which refers to allThe MIME type is not specified for the tag, that is, the entire intent-filter has noandroid:mimeTypeIt is very important to understand these words. You can understand this in the following examples.
For example, the following intent object is available:

Intent intent = new Intent();intent.setAction(com.ispring.action.ACTION_TEST1);Uri uri = Uri.parse(ispring://blog.csdn.net/sunqunsunqun);intent.setData(uri);

The above intent can pass the following intent-filter data test:


          
       
    
   
  

The above intent object can be tested using the following intent-filter data:


          
       
        
   
  

Although the intent object cannot useLabel test, but you can test the data label with scheme as ispring, and the intent object and the intent-filterNo MIME is specified for the tag, so the intent object above can be tested using the intent-filter.

The above intent object cannot pass the following intent-filterTag test:


          
       
    
   
  

The reason why the intent object above cannot be unique in intent-filterThe label test is because our intent object does not specify the MIME type, but the aboveLabel passedandroid:mimeType=text/plainThe MIME type is set.

The above intent object cannot pass the following intent-filter data test:


          
       
        
   
  

The intent object above cannot pass the data test in the intent-filter because the intent object does not set the MIME type, but the second data tag in the intent-filter passesandroid:mimeType=text/plainThe MIME type is set.

Intent object contains the MIME type but does not contain the URI
In this case, you can pass the data test only when the MIME type in intent is the same as the MIME type listed in intent-filter and the intent-filter does not specify any URI format.Note that the intent-filter parameter does not specify any URI format.No URI is specified for the tag, that is, the entire intent-filter has noandroid:scheme,android:host,android:portAndandroid:pathIt is very important to understand this. You can understand this in the following examples.
For example, the following intent object is available:

Intent intent = new Intent();intent.setAction(com.ispring.action.ACTION_TEST1);intent.setType(text/plain);

The above intent object can be tested using the following intent-filter data:


          
       
    
   
  

The above intent object can be tested using the following intent-filter data:


          
       
        
   
  

Although the above intent object is not passed through the MIME typeimage/*But can pass the second data tag test, and the intent object and intent-filter do not specify any URI format.

The above intent object cannot pass the data test in the following intent-filter:


          
       
    
   
  

The above intent object does not set the URI information, but the scheme value in the URI is set in the intent-filter, so the intent cannot pass the data test of the intent-filter.

The above intent object cannot pass the data test in the following intent-filter:


          
       
        
   
  

The above intent object does not specify URI information, but the second one in the intent-filter aboveThe label sets the scheme information in the URI, so the intent object cannot pass the data test of the intent-filter.

The intent object contains both the URI and MIME types.
In this case, you must test whether the URI and MIME types pass the test. Only the URI and MIME tests pass the test.

MIME test: If the MIME type of intent matches one of the intent-filter The MIME type value in the label, then the test of the MIME type will pass. For URI testing:
Further subdivided into two situations, to meet any of the following conditions can be tested through URI.
If the URI format of intent matches one of the values listed in intent-filter URI, then the URI test passes. If the intent URI is content:Protocol or file:Protocol, and all intent-filter The URI is not specified in the tag, so the intent can pass the URI test. In other words, if an intent-filter only lists MIME types and does not list any URI-related formats, the intent-filter is supported by default. content:Protocol or file:Protocol.

Let's take a few examples.

Assume that the following protocols are custom protocols:ispring:Intent object:

Intent intent = new Intent();intent.setAction(com.ispring.action.ACTION_TEST1);Uri uri = Uri.parse(ispring://blog.csdn.net/sunqunsunqun);String type = text/plain;intent.setDataAndType(uri, type);

The above intent object can be tested using the following intent-filter data:


              
         
          
   
  

The above intent object cannot pass the data test of intent-filter below:


              
         
          
   
  

If the port is not met, the URI test fails, causing data testing to fail.

The above intent object cannot pass the data test of intent-filter below:


              
         
          
   
  

android:mimeTypeIf the test fails, the test fails.

Assume that the following protocols are available:content:Intent object:

Intent intent = new Intent();intent.setAction(com.ispring.action.ACTION_TEST1);Uri uri = Uri.parse(content://com.ispring.test);String type = text/plain;intent.setDataAndType(uri, type);

The above intent object cannot pass the data test of intent-filter below:


              
         
          
   
  

The scheme in URI does not match. As a result, the URI test fails and the data test fails.

The above intent object can be tested using the following intent-filter data:


              
         
    
   
  

Intent usescontent:Protocol, and the URI format is not defined in the entire intent-filter, so the URI test can pass, and the MIME type can find matching items, so you can pass the data test.

In summary, we have completed a detailed explanation of the Intent action, category, and data testing. All the sample code in this article has been verified in the official version of Android Studio 1.0. Thank you for your patience in reading this blog. I hope this article will help you use the Intent filter correctly.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.