我是靠谱客的博主 平常可乐,最近开发中收集的这篇文章主要介绍IntentFilter的详细说明和使用方式,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 当Intent在组件间传递时,组件如果想告知Android系统自己能够响应和处理哪些Intent,那么就需要用到Intent-filter对象。

    顾名思义:Intent-filter对象负责过滤掉组件无法响应和处理的Intent,只将自己关心的Intent接收进来进行处理。


注意:

  • Intent-filter实行“白名单”管理,即只列出组件乐意接受的Intent,但Intent-filter只会过滤隐式Intent,显式的Intent会直接传送到目标组件。 
  • Android组件可以有一个或多个Intent-filter,每个Intent-filter之间相互独立,只需要其中一个验证通过则可。
  • 除了用于过滤广播的Intent-filter可以在代码中创建外其他的Intent-filter必须在AndroidManifest.xml文件中进行声明。

   

 Intent-filter中具有和Intent对应的用于过滤Action(动作)Data(数据)Category(类别)的字段,一个隐式Intent要想被一个组件处理,必须通过这三个环节的检查。

       

       一:检查 Action: 尽管一个Intent只可以设置一个Action,但一个Intent-filter可以持有一个或多个Action用于过滤,到达的Intent只需要匹配其中一个Action即可。

 深入思考:如果一个Intent-filter没有设置Action的值,那么,任何一个Intent都不会被通过;反之,如果一个Intent对象没有设置Action值,那么它能通过所有的Intent-filter的Action检查。

        

       二:检查 Data: 同Action一样,Intent-filter中的Data部分也可以是一个或者多个,而且可以没有。每个Data包含的内容为URL和数据类型,进行Data检查时主要也是对这两点进行比较,比较规则: 如果一个Intent对象没有设置Data,只有Intent-filter也没有设置Data时才可通过检查。 如果一个Intent对象包含URI,但不包含数据类型:仅当Intent-filter也不指定数据类型,同时它们的URI匹配,才能通过检测。 如果一个Intent对象包含数据类型,但不包含URI:仅当Intent-filter也没指定URL,而只包含数据类型且与Intent相同,才通过检测。 如果一个Intent对象既包含URI,也包含数据类型(或数据类型能够从URI推断出),只有当其数据类型匹配Intent-filter中的数据类型,并且通过了URL检查时,该Intent对象才能通过检查。

   其中URL由四部分组成:它有四个属性scheme、host、port、path对应于URI的每个部分。

      例如:content://com.wjr.example1:121/files

       scheme部分:content

       host部分:com.wjr.example1

       port部分:121

       path部分:files

    host和port部分一起构成URI的凭据(authority),如果host没有指定,那port也会被忽略。

    这四个属性是可选的,但他们之间并不是完全独立的。要让authority有意义,scheme必须要指定。要让path有意思,scheme和authority必须指定。Intent-filter中的path可以使用通配符来匹配path字段,Intent和Intent-filter都可以用通配符来指定MIME类型。

    

     三:检查 Category:Intent-filter中可以设置多个Category,Intent中也可以含有多个Category,只有Intent中的所有Category都能匹配到Intent-filter中的Category,Intent才能通过检查。也就是说,如果Intent中的Category集合是Intent-filter中Category的集合的子集时,Intent才能通过检查。如果Intent中没有设置Category,则它能通过所有Intent-filter的Category检查。 如果一个Intent能够通过不止一个组件的Intent-filter,用户可能会被问那个组件被激活。如果没有目标找到,会产生一个异常。

 

 

 

Intent-filter

应用程序的组件为了告诉Android自己能响应、处理哪些隐式Intent请求,可以声明一个甚至多个Intent-filter。每个 Intent-filter描述该组件所能响应Intent请求的能力——组件希望接收什么类型的请求行为,什么类型的请求数据。比如之前请求网页浏览器这 个例子中,网页浏览器程序的Intent-filter就应该声明它所希望接收的Intent Action是WEB_SEARCH_ACTION,以及与之相关的请求数据是网页地址URI格式。

如何为组件声明自己的Intent-filter? 常见的方法是在AndroidManifest.xml文件中用属性<Intent-Filter>描述组件的Intent-filter。

前面我们提到,隐式Intent和Intent-filter进行比较时的三要素是Intent的Action、Data以及Category。实际 上,一个隐式Intent请求要能够传递给目标组件,必要通过这三个方面的检查。如果任何一方面不匹配,Android都不会将该隐式Intent传递给 目标组件。接下来我们讲解这三方面检查的具体规则。

1.动作测试

<intent-filter>元素中可以包括子元素<action>,比如:

<intent-filter> 
<action android:name="com.example.project.SHOW_CURRENT" /> 
<action android:name="com.example.project.SHOW_RECENT" /> 
<action android:name="com.example.project.SHOW_PENDING" /> 
</intent-filter> 


一条<intent-filter>元素至少应该包含一个<action>,否则任何Intent请求都不能和该<intent-filter>匹配。

如果Intent请求的Action和<intent-filter>中个某一条<action>匹配,那么该Intent就通过了这条<intent-filter>的动作测试。

如果Intent请求或<intent-filter>中没有说明具体的Action类型,那么会出现下面两种情况。

(1) 如果<intent-filter>中没有包含任何Action类型,那么无论什么Intent请求都无法和这条<intent-filter>匹配。

(2) 反之,如果Intent请求中没有设定Action类型,那么只要<intent-filter>中包含有Action类型,这个Intent请求就将顺利地通过<intent-filter>的行为测试。

2.类别测试

<intent-filter>元素可以包含<category>子元素,比如:

<intent-filter . . . > 
<category android:name="android.Intent.Category.DEFAULT" /> 
<category android:name="android.Intent.Category.BROWSABLE" /> 
</intent-filter>


只有当Intent请求中所有的Category与组件中某一个Intent-filter 的<category>完全匹配时,才会让该Intent请求通过测试,Intent-filter中多余的<category> 声明并不会导致匹配失败。一个没有指定任何类别测试的Intent-filter仅仅只会匹配没有设置类别的Intent请求。

3.数据测试

数据在<intent-filter>中的描述如下:

<intent-filter . . . > 
<data android:type="video/mpeg" android:scheme="http" . . . /> 
<data android:type="audio/mpeg" android:scheme="http" . . . /> 
</intent-filter> 


<data>元素指定了希望接受的Intent请求的数据URI和数据类 型,URI被分成三部分来进行匹配:scheme、authority和path。其中,用setData()设定的Intent请求的URI数据类型和 scheme必须与Intent-filter中所指定的一致。若IntentFilter中还指定了authority或path,它们也需要相匹配才会 通过测试。



讲解完Intent基本概念之后,接下来我们就使用Intent激活Android自带的电话拨号程序。通过这个实例你会发现,使用Intent并不像其概念描述得那样难。

 

IntentFilter 
简述:结构化描述intent匹配的信息。包含:action,categories and data(via type,scheme ,path),还有priority, to order multiple matching filters.
       IntentFilter 中如果action为空,则视为通配符,如果type为空,则intent必须不设type,否则匹配不上。 
       data被分为3个属性:type,scheme,authority/path 任何设置的属性intent必须匹配上。 
                           设置了scheme 而没设type,则intent也必须类似,不能设置type,也不能是content: URI.
                           设置了type而没设scheme:将匹配上没有URI的intent,或者content:,file:的uri。
                           设置了authority:必须指定一个或多个相关联的schemes 
                           设置了path:唏嘘指定一个或多个相关联的schemes 
       匹配规则: 
           IntentFilter 匹配Intent的上的条件: 
           Action : 值相同 ,或则IntentFilter未指定action. 
           DataType:. 系统通过调用Intent.resolve(ContentResolver)获取type,通配符* 
                     在Intent/IntentFilter的MIME type中使用,区分大小写 
           DataScheme:系统通过调用Intent. getData() and Uri.getScheme())获取scheme, 区分大小写
           DataAuthority:必须有一个dataScheme匹配上且authority值匹配上,或者IntentFilter没有定义。Intent. getData() and Uri.getAuthority()获取authority.
           DataPath: scheme and authority必须先匹配上 ntent. getData() and Uri.getPath(),获取. 或者IntentFilter没有定义
           Categories:all of the categories in the Intent match categories given in the filter 多余的Categorie,不影响intent匹配,如果IntentFilter
                  没有指定Categorie,则只能匹配上没有Categorie的intent。 

常用intent列表: 
Android Intent 用法汇总 
显示网页 

- <activity android:name="BrowserActivity" android:label="Browser" android:launchMode="singleTask" android:alwaysRetainTaskState="true" android:configChanges="orientation|keyboardHidden" android:theme="@style/BrowserTheme">
- <!-- 
For these schemes were not particular MIME type has been 
                 supplied, we are a good candidate. 
  --> 
- <intent-filter> 
  <action android:name="android.intent.action.VIEW" /> 
  <category android:name="android.intent.category.DEFAULT" /> 
  <category android:name="android.intent.category.BROWSABLE" /> 
  <data android:scheme="http" /> 
  <data android:scheme="https" /> 
  <data android:scheme="about" /> 
  </intent-filter> 
- <!-- 
  For these schemes where any of these particular MIME types 
                  have been supplied, we are a good candidate. 
  --> 
- <intent-filter> 
  <action android:name="android.intent.action.VIEW" /> 
  <category android:name="android.intent.category.BROWSABLE" /> 
  <category android:name="android.intent.category.DEFAULT" /> 
  <data android:scheme="http" /> 
  <data android:scheme="https" /> 
  <data android:mimeType="text/html" /> 
  <data android:mimeType="text/plain" /> 
  <data android:mimeType="application/xhtml+xml" /> 
  <data android:mimeType="application/vnd.wap.xhtml+xml" /> 
  </intent-filter> 
- <!-- 
We are also the main entry point of the browser. 
  --> 
- <intent-filter> 
  <action android:name="android.intent.action.MAIN" /> 
  <category android:name="android.intent.category.DEFAULT" /> 
  <category android:name="android.intent.category.LAUNCHER" /> 
  <category android:name="android.intent.category.BROWSABLE" /> 
  </intent-filter> 
- <intent-filter> 
  <action android:name="android.intent.action.WEB_SEARCH" /> 
  <category android:name="android.intent.category.DEFAULT" /> 
  <category android:name="android.intent.category.BROWSABLE" /> 
  <data android:scheme="" /> 
  <data android:scheme="http" /> 
  <data android:scheme="https" /> 
  </intent-filter> 
- <intent-filter> 
  <action android:name="android.intent.action.WEB_SEARCH" /> 
  <action android:name="android.intent.action.MEDIA_SEARCH" /> 
  <category android:name="android.intent.category.DEFAULT" /> 
  </intent-filter> 
- <intent-filter> 
  <action android:name="android.intent.action.SEARCH" /> 
  <category android:name="android.intent.category.DEFAULT" /> 
  </intent-filter> 
  <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" />
- <intent-filter> 
  <action android:name="android.net.http.NETWORK_STATE" /> 
  <action android:name="android.intent.action.PROXY_CHANGE" /> 
  </intent-filter> 
  </activity> 



Uri uri = Uri.parse("http://google.com");   
Intent it = new Intent(Intent.ACTION_VIEW, uri);   
startActivity(it);  



显示地图 

   
Uri uri = Uri.parse("geo:38.899533,-77.036476");   
   Intent it = new Intent(Intent.ACTION_VIEW, uri);    
   startActivity(it);    
   //其他 geo URI 範例   
   //geo:latitude,longitude   
   //geo:latitude,longitude?z=zoom   
   //geo:0,0?q=my+street+address   
   //geo:0,0?q=business+near+city   
   //google.streetview:cbll=lat,lng&cbp=1,yaw,,pitch,zoom&mz=mapZoom  




路径规划 

   
 Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en");  
    Intent it = new Intent(Intent.ACTION_VIEW, uri);   
   startActivity(it);   
    //where startLat, startLng, endLat, endLng are a long with 6 decimals like: 50.123456  




打电话 
   
 //叫出拨号程序  
 Uri uri = Uri.parse("tel:0800000123");   
 Intent it = new Intent(Intent.ACTION_DIAL, uri);   
 startActivity(it);   

//直接打电话出去   
Uri uri = Uri.parse("tel:0800000123");   
Intent it = new Intent(Intent.ACTION_CALL, uri);   
startActivity(it);   
//用這個,要在 AndroidManifest.xml 中,加上   
//<uses-permission id="android.permission.CALL_PHONE" />   



传送SMS/MMS 
    
 //调用短信程序  
     Intent it = new Intent(Intent.ACTION_VIEW, uri);   
     it.putExtra("sms_body", "The SMS text");    
     it.setType("vnd.android-dir/mms-sms");   
     startActivity(it);  

     //传送消息  
     Uri uri = Uri.parse("smsto://0800000123");   
     Intent it = new Intent(Intent.ACTION_SENDTO, uri);   
     it.putExtra("sms_body", "The SMS text");   
     startActivity(it);  

     //传送 MMS   
     Uri uri = Uri.parse("content://media/external/images/media/23");   
     Intent it = new Intent(Intent.ACTION_SEND);    
     it.putExtra("sms_body", "some text");    
     it.putExtra(Intent.EXTRA_STREAM, uri);   
     it.setType("image/png");    
     startActivity(it);   



传送 Email 
    
 Uri uri = Uri.parse("mailto:xxx@abc.com");   
     Intent it = new Intent(Intent.ACTION_SENDTO, uri);   
     startActivity(it);   

     Intent it = new Intent(Intent.ACTION_SEND);   
     it.putExtra(Intent.EXTRA_EMAIL, "me@abc.com");   
     it.putExtra(Intent.EXTRA_TEXT, "The email body text");   
     it.setType("text/plain");   
     startActivity(Intent.createChooser(it, "Choose Email Client"));   

     Intent it=new Intent(Intent.ACTION_SEND);     
    String[] tos={"me@abc.com"};     
     String[] ccs={"you@abc.com"};     
     it.putExtra(Intent.EXTRA_EMAIL, tos);     
     it.putExtra(Intent.EXTRA_CC, ccs);     
     it.putExtra(Intent.EXTRA_TEXT, "The email body text");     
     it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");     
     it.setType("message/rfc822");     
     startActivity(Intent.createChooser(it, "Choose Email Client"));  

     //传送附件 
     Intent it = new Intent(Intent.ACTION_SEND);   
     it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");   
     it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/mysong.mp3");   
     sendIntent.setType("audio/mp3");   
     startActivity(Intent.createChooser(it, "Choose Email Client"));  



播放多媒体 
      
 Uri uri = Uri.parse("file:///sdcard/song.mp3");   
       Intent it = new Intent(Intent.ACTION_VIEW, uri);   
       it.setType("audio/mp3");   
       startActivity(it);  



       Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");  
       Intent it = new Intent(Intent.ACTION_VIEW, uri);   

       startActivity(it); 

 



Market 相关 
        
 //寻找某个应用  
         Uri uri = Uri.parse("market://search?q=pname:pkg_name");  
         Intent it = new Intent(Intent.ACTION_VIEW, uri);   
        startActivity(it);   
        //where pkg_name is the full package path for an application  

         //显示某个应用的相关信息  
         Uri uri = Uri.parse("market://details?id=app_id");   
         Intent it = new Intent(Intent.ACTION_VIEW, uri);  
        startActivity(it);   
         //where app_id is the application ID, find the ID    
         //by clicking on your application on Market home    
        //page, and notice the ID from the address bar  



Uninstall 应用程序 
         
Uri uri = Uri.fromParts("package", strPackageName, null);  
         Intent it = new Intent(Intent.ACTION_DELETE, uri);    
         startActivity(it);   

最后

以上就是平常可乐为你收集整理的IntentFilter的详细说明和使用方式的全部内容,希望文章能够帮你解决IntentFilter的详细说明和使用方式所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部