Android的进阶学习(三)--Intent和IntentFilter

IntentFilter,顾名思义,就是Intent的过滤器。回想一下,好像Intent在我们的代码中出现的频率还是挺高的,那么今天我们就来理理。

Intent

Intent的意思是意图, 而就和它的意思差不多,每当我们使用 Intent的时候, 总是去想干一些事情:

  • startActivity(Intent intent)
  • startService(Intent intent)
  • bindService(Intent intent)
  • sendBrodcast(Intent intent)
  • .......

对的,我们再很多地方都会使用Intent。对于这些请求,我们都会传入一个Intent,用来Filter并启动相应的ActivityServiceBroadcastReceiver。而在这里,我们就有两种调用方式:显示调用和隐式调用。

显式调用

就像启动Activity,我们常常就是显式的调用,那何为显式调用呢?

Intent itent = new Intent();
itent.setClass(Activity_A.this, Activity_B.class);
startActivity(itent);

哦,这就是显式调用。之说以叫做显式调用,我们为Intent清楚的指出了被启动组件的信息(这里就是Activity_B),当调用了startActivity(itent)后,我们就只会很明确的知道,这次的任务是启动Activity_B,而没有其它的过程。

隐式调用

看了显式调用,应该猜都猜得到了,隐式调用就是没有明确的指出组件信息。而是通过Filter去过滤出需要的组件。

Intent intent = new Intent();
intent.setAction(Intent.ACTION_BATTERY_LOW);
intent.addCategory(Intent.CATEGORY_APP_EMAIL);
intent.setDataAndType(Uri.EMPTY, "video/mpeg");
startActivity(intent);

这里就是一个隐式的调用,可以看到我为Intent设置了三个属性ActionCategoryData
然后startActivity(intent)就会根据我们设置的这三个属性去筛选合适的组件来打开,也就是因为这样,所以有时候,当我们APP来分享一个东西的时候,会有很多组件(比如QQ、微信、微博...)来供我们选择,因为他们都满足Filter条件。或许你还有许多疑问,来我们就接着来看IntentFilter吧!


IntentFilter

IntentFilter的意思就是意图过滤器,当我们隐式的启动系统组件的时候,就会根据IntentFilter来筛选出合适的进行启动。

现在我们知道了可以在Intent启动的时候对应设置ActionCategoryDataAndType,这里设置的是为了过滤的时候对应IntentFilter匹配actioncategorydata

除开过滤广播的的IntentFilter可以在代码中创建外,其它的IntentFilter都得在AndroidManifest.xml中给设置。

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_BATTERY_LOW);
intentFilter.addCategory(Intent.CATEGORY_APP_EMAIL);
intentFilter.addDataType("video/mpeg");
Reciver reciver = new Reciver();
registerReceiver(reciver, intentFilter);

这里就是在代码中设置IntentFilter,可以看到我们设置了三个属性。让后我们再看看在AndroidManifest.xml的设置方法:

<activity  android:name=".Activity_B"    
           android:label="@string/title_activity_activity__b"
           android:launchMode="singleInstance">  
  <intent-filter> 
    <action android:name="android.intent.action.ANSWER" />    
    <category android:name="android.intent.category.APP_EMAIL" />        
    <data  android:host="www.mathiasluo.com"   
           android:scheme="http" />  
  </intent-filter>
</activity>

我们在这里给Activity设置了一个IntentFilter,但是值得注意的是,一个组件可以有多个IntentFilter,在过滤的时候只要有一个符合要求的,就会被视为过滤通过。

那我们就看看是怎样过滤的吧,首先我们应该明白一个大的思路:当我们隐式的启动一个组件的时候,就会一个一个的去过滤对应组件的全部,(比如你是隐式的启动一个Activity,就会一个一个的在全部Activity中筛选),然后根据Intent的所设置的actioncategorydata去比较IntentFilter所设置的这三个属性,相同的话就过滤留下来了。

action的匹配#####

action的匹配要求Intent中的action存在且必须和过滤规则中的其中一个action相同

首先,action是一个字符串,匹配的话就是说两个action的字符串完全相同(Intent和IntentFilter中的action)。然后我们就看看具体的匹配方法:

  • 如果IntentFilter中有action,Intent中必须有action
  • Intent中的action必须在相应IntentFilter中存在
  • Intent中只需要有一个actionIntentFilter中相同即可

IntentFilter中可以设置多个action,Intent中也可以设置多个action,这里就是说我们Intent中的action必须存在IntentFilter中,但是Intent中不必包括IntentFilter中全部的action,但是至少包括一个。

category的匹配#####

category 要求Intent中可以没有category,但是你一旦有category,不管几个,每个都要和IntentFilter中的category相同。

这里我们说Intent中可以没有category,其实不然,只是在我们启动组件(eg:startActivity( ))的时候,默认给我们的Intent给加了一个category("android.intent.category.DEFAULT" ).

哦,我们知道了这里,那么匹配就和action差不多了,就是我们的Intent中的category必须在IntentFilter中存在。这里得注意,Intent中都会包括默认的category,并且如果你想隐式启动某个组件,那么就得在IntentFilter中添加android.intent.category.DEFAULT这个category才行哟。

data的匹配#####

如果IntentFilter中有定义data,那么Intent中也必须也要定义可以的date

看了上面的两个的匹配规则,发现其实还是很有规律的,对的,data的匹配也差不多(其实我认为是一样的,只是data的结构要复杂些)。

<data    android:mimeType="text/plain"
         android:host="www.mathiasluo.com"      
         android:path="/myfolder/my.txt"
         android:pathPattern="/myfolder/*" 
         android:port="80"
         android:scheme="http" />

一看,吓死,这么多。
但其实一个data主要包括的就是一个URImimeTypemimeType就是媒体类型,就像"text/plain"这样的,可以表示data是图片呀、文本呀、视频等等。其它的就是URI的了,简单点,就是除开mimeType,剩下的全部都是属于URI的,它们组成了URI。而URI中属性就特别容易懂了,就像host指的是主机名、Scheme指的是URI的模式、Port指的端口号......

Inten中,我们通过setDataAndType(Uri data, String type)方法对date进行设置。这个方法接受两个参数,第一个就是URI,第二个就是String类型的mimeType了,通过这一个方法,我们就可以给Intent设置data了。、


隐式启动的判断

当我们隐式启动的时候,获取无法过滤找到所需要的组件,这样的话就会报错了。那么有没有什么方法来判断隐式启动的Intent是否能找到相应的组件呢?
当然我们谷歌大法肯定是会知道我们的需求的。

Intent intent = new Intent();
intent.setAction(Intent.ACTION_BATTERY_LOW);
intent.addCategory(Intent.CATEGORY_APP_EMAIL);
intent.setDataAndType(Uri.EMPTY, "video/mpeg");
PackageManager packageManager = getPackageManager();
List<ResolveInfo> infoList = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
Log.i(TAG, infoList.size() + "");
if (infoList.size() != 0) {  
  startActivity(intent);
} else { 
   Log.e(TAG, "没有匹配到Activity");
}

这里我们是通过PackageManager来判断的,还有一种Intent的方法:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_BATTERY_LOW);
intent.addCategory(Intent.CATEGORY_APP_EMAIL);
intent.setDataAndType(Uri.EMPTY, "video/mpeg");
ComponentName name =  intent.resolveActivity(getPackageManager());
if (name != null){
    startActivity(intent);
}else {
    Log.e(TAG,"没有匹配到Activity");
}

这两个方法差不多,也都很简单,所以就不多说了。


最后

还有,这些是我参考《Android开发艺术探索》的,对,就是任大大的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容