Android Intent基础

Android Intent基础

在本篇博客中会涉及以下内容:

  • Intent的概念和基本知识以及使用
  • Action解析
  • Category解析
  • Data和Extras解析
  • 建立深度搜索(在浏览器搜索结果中打开APP特定页面)

Intent概念

Intent 即为意图,意图就是你要干啥。可以通过Intent告诉系统你要干什么,找谁干,怎么干(参数)。
Intent分为两种:

  • 显式意图

    系统根据开发者指定的组件选择处理意图的对象,使用setComponent或者setClass或者setClassName来显式指定处理意图的对象。适用条件是开发者准确知道可以处理该意图的对象的确切的位置,如果调用对象在应用内可以直接指定xxxx.class,如果调用其他应用则需要指定包名以及类名的确切路径。

  • 隐式意图

    隐式意图则是通过设置Action,Category,Data,Type等之后交给系统,由系统以及用户选择处理该意图的组件。

一些代码示例

//启动一个Activity、Service或是一个发送一个广播都离不开Intent
startActivity(intent);
startService(intent);
sendBroadcast(intent);
//startActivity,startService,sendBroadcast指明了要干什么
//找谁干和怎么干就需要设置Intent中的参数了

//intent中的参数
    private String mAction;//Action
    private Uri mData;//Data
    private String mType;//Type
    private String mPackage;
    private ComponentName mComponent;//classname
    private int mFlags;//启动模式
    private ArraySet<String> mCategories;//Category
    private Bundle mExtras;//Bundle
    private Rect mSourceBounds;
    private Intent mSelector;
    private ClipData mClipData;
    private int mContentUserHint = UserHandle.USER_CURRENT;
    private String mLaunchToken;
/**
 * intent中参数的设置
 * setClass方式是由开发者来确定由谁来完成该项工作
 * 通过setAction,addCategory,setData,setType告诉系统工作的类型以及要处理的数据和处理数据的类型,
 * 由系统决定由谁来完成(可能需要用户的参与)
 * putExtra,将数据存在bundle中,通过Intent传递的额外的数据
**/

//显式意图(通过设置ComponentName参数指定完成意图的组件)
//设置Component参数一共有三种方式
intent.setClass(this,MainActivity.class);
intent.setClassName(this,"com.nullpointer.stud.MainActivity.class");
intent.setClassName("com.nullpointer.study","com.nullpointer.study.MainActivity");
//其实质都是通过包名和类名构造了一个ComponentName
//打开当前APP内组件可以不指定包名而通过context指定,但是实质还是使用包名
//打开其他应用的组件需要指定完整包名和全限定类名


//隐式意图
//通过setAction指定操作的类型,通过setData指定操作的数据,
//通过设置Category限定类别
//通过设置setType指定操作的对象的类型

//?下面的示例就指定了一个打开拨号界面的意图,并且指定了拨号界面的数据是朕的手机号码
intent.setAction(Intent.ACTION_DIAL);
intent.setDataAndType(Uri.parse("tel:18013116680"),"uri");

//?下面的示例就打开了指定的网页
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.google.com"));

//?下面的示例就打开了搜索结果页面
intent.setAction(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY,"Android");

//需要注意的是  setData和setType互斥,如果需要同时设置 请使用setDataAndType();

public @NonNull Intent setData(@Nullable Uri data) 
    mData = data;
    mType = null;
    return this;
}
public @NonNull Intent setType(@Nullable String type) {
    mData = null;
    mType = type;
    return this;
}

Android 提供了很多标准Intent的使用范例,也预置了很多标准Action

谷歌在线文档

一个不错的中文示例

有些东西没必要去死记硬背,需要的时候去翻文档就好了

IntentFilter

就像前面讲到的,我们可以通过设置Action,设置data来让系统帮我们选择进行此操作的组件,或者应用。Action指定了将要操作的行为,是打开一个网页还是去打开一个拨号页面,或者是发短信、发邮件等等等等。Data就指定了要操作的数据。

我们使用了系统提供的Action可以方便地调用系统的一些服务。如果我们的应用需要被别的应用调用呢?这个时候我们可以设置自己应用Activity或者Service或者BrocastReceiver的interFilter来告诉系统我们的组件可以处理哪些数据。相信下面的代码大家一定不会陌生:

//这是应用的启动页,设置action=main和category=launcher表示这是应用的主屏,打开应用时默认打开的页面
<activity android:name=".MainActivity"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Action:

一个想要执行的动作的名称,通常是系统已经定义好的值或者自定义的值。使用action进行匹配需要Intent中的Action可以和xml中定义的Action中的一个相同。

Data/Type:

Intent附带的数据以及数据的类型。分为两部分:URI和mimeType.
URI的格式:scheme://host:port/path|pathPattern|pathPrefix
mimeType的常见类型:image/*、video/*、string、text/plain等

Category:用的比较少,我也不是很懂。

系统也预定义了一些Category,或者开发者可以自定义。使用category进行过滤的规则是,如果Intent中包含Category,则每一个Category都被包含在xml中Intent-Filter中的设置的category中时才能匹配成功。

根据上面的介绍的匹配规则看一下下面的示例:

<!--假设现在有一个Activity在清单文件中的设置如下:-->
<activity android:name=".TestActivity"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <action android:name="android.intent.action.SENDTO"/>
        <action android:name="android.intent.action.SEND_MULTIPLE" />

        <category android:name="android.intent.category.APP_MAPS" />
        <category android:name="android.intent.category.APP_BROWSER" />
        <category android:name="android.intent.category.VOICE"/>

        <data
            android:scheme="http"
            android:host="www.shaishufang.com"
            android:mimeType="text/plain"
            />
    </intent-filter>
</activity>

如果根据Action 进行匹配:下面两个Intent都可以与该Activity匹配成功

Intent intent1 = new Intent();
intent1.setAction("Intent.ACTION_SEND");

Intent intent2 = new Intent();
intent2.setAction("Intent.ACTION_SENDTO");

如果根据Data进行匹配:intent1匹配不成功,intent2则匹配成功

Intent intent1 = new Intent();
intent1.setDataAndType(Uri.parse("http://www.google.com"),"text/plain");

Intent intent2 = new Intent();
intent2.setData(Uri.parse("http://www.shaishufang.com/bookdetail?bid=1234"),"text/plain");

如果根据Category进行匹配:

  1. intent1可以匹配成功,因为添加的两个category在Activity的intent-filter中都有设置
  2. intent2匹配不成功,因为虽然Maps有设置,但是Email没有设置,根据规则必须两个都在intent-filter中设置才可以匹配成功。
Intent intent1 = new Intent();
intent1.addCategory(Intent.CATEGORY_APP_MAPS);
intent1.addCategory(Intent.CATEGORY_APP_BROWSER);

Intent intent2 = new Intent();
intent2.addCategory(Intent.CATEGORY_APP_MAPS);
intent2.addCategory(Intent.CATEGORY_APP_EMAIL);

如果将三种匹配规则进行混合匹配,则必须全部满足才能匹配成功。

实战演练

下面通过两个应用中的实例来直观的感受一下如何在我们的APP中设置intent-filter达到特定的目的。
现在假设用户可以通过我们的应用给好友发送数据,但是只能发文字,我们可以这么设置。(如果也可以发图片,把注释放开就可以了):

<!--
 在这里,我们通过Action设置了我们的应用可以执行发送数据的操作,
 并且通过data属性指定了我们的这个页面可以操作的数据对象是text/plain格式的数据
 这样,当其他的APP通过隐式意图的时候,系统匹配到我们的这个页面有这个功能,
 并且将我们的应用和其他的同样具有此功能的APP展示给用户,由用户选择一个APP进行发送
-->
<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
        <!--<data android:mimeType="image/*"/>-->
    </intent-filter>
</activity>

现在又有一个常见需求,在浏览器打开网页,自动跳转了app,也是通过设置IntentFilter实现的。

<!--
在网页中打开一个Uri格式为shaishufang://shaishufang.com?type=book&bid=1234的链接时,
如果您的手机安装的有晒书房,浏览器会自动跳转到应用内打开特定页面(根据后面的参数会知道用户要访问的内容)
又有如果您允许允许谷歌搜索您的APP,建立深度链接,把注释放开就可以了
您可以试试使用谷歌搜索“丝袜 知乎”,随便点击搜索结果前几个中的一个,
会直接打开知乎的该问题页面,百度搜索就不行。
我本来也想做来着,可是我们的产品是必须登录才有权限访问,不符合谷歌的建议,就没做
如果您有兴趣,可以跟产品建议一下,为用户提供更好的使用体验吧
-->
<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:host="shaishufang.com"
        android:scheme="shaishufang" />
    <!--<data
        android:host="shaishufang.com"
        android:scheme="http" />-->
</intent-filter>

好了,关于Intent的基本知识就先到这里为止了。

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

推荐阅读更多精彩内容