【Android基础】趣谈Intent

Intent

Intent 顾名思义,意图
类比一下,假如说把android系统中的每个Activity都看成是一个个的人,我们每个人绝不是超人,即会去响应别人的请求,也会要求得到别人的帮助,这样才能实现和谐互助,那么之间的交互用intent表示很恰当,

打电话的故事

比如在以前电话不普及的时候,有急事,自己家又没有电话,但是并不知道周围的人谁家里有,所以在大院里大声喊一下:

“hey,我想借打个电话,电话号码是 15912345678”

这里包含些关键的信息。

  • 要干啥呢:打个电话
  • 目标是什么?:电话号码是 15912345678

这样其他人听到了会考虑一下:

“我们家有电话?” :没有,那就没我事。有,下一步。

“拿起电话,并且输入号码 15912345678”

这些是我们现实生活中的交互场景,那么Android中又是怎么做到呢?

Android借打电话

    /**
     * 开启拨号页面
     */
    public void dialNumber(View view) {
        Uri uri = Uri.parse("tel:15912345678");
        Intent i = new Intent(Intent.ACTION_DIAL,uri);
        startActivity(i);
    }
action

就是上面提到的“要寻求什么样的帮助”,例子是打电话,当然计算机是听不懂人话的,他的口令就是 Intent.ACTION_DIAL

The general action to be performed, such as ACTION_VIEW, ACTION_EDIT, ACTION_MAIN, etc.

data

如果还想让人给你把号给拨好,比如老式的拨号机,还不会用,那还得告诉他电话号码是多少?官方点就是我得传递个电话号码的资源,”tel:15912345678”

The data to operate on, such as a person record in the contacts database, expressed as a Uri.
官方如是说: data 啊,就是要被使用到的数据,比如在联系人数据库中的联系人记录,这些数据都是以Uri描述的。

上例中,假如你使用Intent.ACTION_VIEW而非 Intent.ACTION_DIAL,最终的执行结果仍旧不变,为什么呢?关键在于Uri的魔力,tel已经告诉了访问资源的方式,结论就是不光只是看action,系统还会根据Uri中的scheme来做出判断

更多代码
 /**
     *展示电话本中标识为1的联系人
     */
    public void viewFirstContact(View view) {
        Uri uri = Uri.parse("content://contacts/people/1");
        Intent i = new Intent(Intent.ACTION_VIEW,uri);
        startActivity(i);
    }

    /**
     * 编辑电话本中标识为1的联系人
     */
    public void editFirstContact(View view) {
        Uri uri = Uri.parse("content://contacts/people/1");
        Intent i = new Intent(Intent.ACTION_DIAL,uri);
        startActivity(i);
    }

隐式跳转之一:自定义action

上面借打电话的例子并不太准确,那么在Android的世界里,效率还是很高的,有各种技能的人都会去市政府登记自己的技能,那么当要借打电话的时候,直接去市政府查一下登记本就能找到对应的人。

这里写图片描述

对于打电话这种很常见的需求,而且公家自己就提供这样的电话服务,所以Android里已经为他取好了名称叫:Intent.ACTION_DIAL。那么还有很多其他个性化的需求及服务,比如王二很会唱歌,刚好李四家结婚需要有人表演唱歌,

王二去登记技能

在AndroidManifest中

<activity android:name=".intent.WangErActivity">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT"></category>
                <action android:name="com.android.demos.jason.myandroiddemo.SING"></action>
            </intent-filter>
        </activity>

注:必须加上

<category android:name="android.intent.category.DEFAULT"></category>

否则crash报:No Activity found to handle Intent

李四请王二表演唱歌

     /**
     * 自定义action
     */
    public void askForSinger(View view) {
        Intent i = new Intent("com.android.demos.jason.myandroiddemo.SING");
        i.putExtra("songName","god bless american");
        startActivity(i);
    }

隐式跳转之一:定制data之URI

    * 打开网页
     */
    public void openWebsite(View view) {
        Uri uri = Uri.parse("http://www.baidu.com");
        Intent i = new Intent(Intent.ACTION_VIEW,uri);
        startActivity(i);
    }

上面的代码会默认启动浏览器并打开百度主页,为什么?在Uri中的scheme对应着http,这就表明了访问资源的方式,那么就可以匹配打开的工具。

同样接上面的唱歌的例子.

王二去登记技能

在AndroidManifest中

<activity android:name=".intent.WangErActivity">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT"></category>
                <action android:name="android.intent.action.VIEW"></action>
                <data
                    android:scheme="sing"></data>
            </intent-filter>
        </activity>

注:action不可少,起码用VIEW,否则会crash 报无法找到Activity.

李四请王二表演唱歌

 /**
     * 通过data中的Uri来隐式跳转
     */
    public void askForSinger2(View view) {
        Uri uri = Uri.parse("sing://com.demos.myandroiddemo");
        Intent i = new Intent();
        i.setData(uri);
        startActivity(i);
    }
data的过滤规则

一个完整的URI:content://com.example.project:200/folder/subfolder/etc
* scheme > host > port > path, 他们是线性依赖关系,比如,如果在intent filter 中没有定义host,那么过滤器会忽略掉 port,path 。
* 路径path规范可以包含星号通配符 (*),因此仅需部分匹配路径名即可。

结论

虽然Uri中还包含path,host等,但是起到至关重要的标识作用的还是scheme

MIME

王二的歌唱的好了,名声也渐渐传开了,但是让他苦恼的是请他的人会提出一些他并不擅长的表演项目,他只会唱民歌,但是有的人却要求来个摇滚。于是他跑到市政府的登记处,补充了技能信息。

<activity android:name=".intent.WangErActivity">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT"></category>
                <action android:name="android.intent.action.VIEW"></action>
                <data
                    android:mimeType="play/folkSong"
                    android:scheme="sing"></data>
            </intent-filter>
        </activity>

李四家又有喜事了,因为对王二唱歌比较了解,所以他请王二唱的是民歌,

public void askForSingerWithMimeType(View view) {
        Uri uri = Uri.parse("sing://com.demos.myandroiddemo");
        Intent i = new Intent();
        i.setDataAndType(uri,"play/folkSong");
        startActivity(i);
    }

没多久,张三家也有喜事了,想让王二去他家唱摇滚增加热闹气氛,

public void askForSingerWithMimeTypeForRockSong(View view) {
        Uri uri = Uri.parse("sing://com.demos.myandroiddemo");
        Intent i = new Intent();
        i.setDataAndType(uri,"play/rockSong");
        startActivity(i);
    }

但张三很快被拒绝了!
注:
* 若要同时设置 URI 和 MIME 类型,请勿调用 setData() 和 setType(),因为它们会互相抵消彼此的值。请始终使用 setDataAndType() 同时设置 URI 和 MIME 类型。
* MIME 类型可以从 URI 中推断得出,特别当数据是 content: URI 时尤其如此。这表明数据位于设备中,且由 ContentProvider 控制,这使得数据 MIME 类型对系统可见。

category

category – Gives additional information about the action to execute.
作为action的附加信息。

比如:CATEGORY_LAUNCHER 指示此 Activity 的图标应放入系统的应用启动器。如果 activity元素未使用 icon 指定图标,则系统将使用application 元素中的图标。

Note: In order to receive implicit intents, you must include the CATEGORY_DEFAULT category in the intent filter. The methods startActivity() and startActivityForResult() treat all intents as if they declared the CATEGORY_DEFAULT category. If you do not declare it in your intent filter, no implicit intents will resolve to your activity.

隐式跳转的目标Activity必须在 intent filter 定义category为CATEGORY_DEFAULT,否则 startActivity() 和 startActivityForResult() 就找不到该Activity.

参考

Intent

Intent 和 Intent 过滤器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值