《隐性Intent》

 


相比显性Intent,隐性Intent不用指定目的Activity.class,而是设置Action和Category等信息,然后交由系统去分析这个Intent,并找到适合的Activity启动。

打开AndroidManifest.xml,代码如下:

<activity android:name=".DestinationActivity">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

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

            </intent-filter>

</activity>

Action属性的值为一个字符串,它代表了系统中已经定义了一系列常用的动作。通过setAction()方法或在清单文件AndroidManifest.xml中设置,默认为:DEFAULT。Category属性用于指定当前动作(Action)被执行的环境。通过addCategory()方法或在清单文件AndroidManifest.xml中设置,默认为:CATEGORY_DEFAULT。<intent-filter>用于响应intent的Action和Category进行过滤,只有intent提交的Action和Category与注册在<intent-filter>中的Action和Category相匹配才能启动Activity。Action和Category即可以自定义,也可以使用系统内置的,系统内置了大量预定义的Action和Category,以下是常见的举例:

标准Action

ACTION_MAIN

Android Application的入口,每个Android应用必须且只能包含一个此类型的Action声明。

ACTION_VIEW

系统根据不同的Data类型,通过已注册的对应Application显示数据。

ACTION_EDIT

系统根据不同的Data类型,通过已注册的对应Application编辑示数据。

ACTION_DIAL

打开系统默认的拨号程序,如果Data中设置了电话号码,则自动在拨号程序中输入此号码。

ACTION_CALL

直接呼叫Data中所带的号码。

ACTION_ANSWER

接听来电。

ACTION_SEND

由用户指定发送方式进行数据发送操作。

ACTION_SENDTO

系统根据不同的Data类型,通过已注册的对应Application进行数据发送操作。

ACTION_ATTACH_DATA

别用于指定一些数据应该附属于一些其他的地方,例如,图片数据应该附属于联系人

ACTION_PICK

从数据中选择一个子项目,并返回你所选中的项目

ACTION_CHOOSER

显示一个activity选择器,允许用户在进程之前选择他们想要的

ACTION_GET_CONTENT

允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)

ACTION_INSERT

插入一条空项目到已给的容器

ACTION_DELETE

从容器中删除已给的数据

ACTION_RUN

运行数据,无论怎么

ACTION_SYNC

同步执行一个数据

ACTION_PICK_ACTIVITY

为已知的Intent选择一个Activity,返回别选中的类

ACTION_SEARCH

执行一次搜索

ACTION_WEB_SEARCH

执行一次web搜索

ACTION_FACTORY_TEST

工场测试的主要进入点

 

广播Action

ACTION_TIME_TICK

当前时间改变,每分钟都发送,不能通过组件声明来接收,只有通过Context.registerReceiver()方法来注册

ACTION_TIME_CHANGED

时间被设置

ACTION_TIMEZONE_CHANGED

时间区改变

ACTION_BOOT_COMPLETED

系统完成启动后,一次广播

ACTION_PACKAGE_ADDED

一个新应用包已经安装在设备上,数据包括包名(最新安装的包程序不能接收到这个广播)

ACTION_PACKAGE_CHANGED

一个已存在的应用程序包已经改变,包括包名

ACTION_PACKAGE_REMOVED

一个已存在的应用程序包已经从设备上移除,包括包名(正在被安装的包程序不能接收到这个广播)

ACTION_PACKAGE_RESTARTED

用户重新开始一个包,包的所有进程将被杀死,所有与其联系的运行时间状态应该被移除,包括包名(重新开始包程序不能接收到这个广播)

ACTION_PACKAGE_DATA_CLEARED

用户已经清除一个包的数据,包括包名(清除包程序不能接收到这个广播)

ACTION_BATTERY_CHANGED

电池的充电状态、电荷级别改变,不能通过组建声明接收这个广播,只有通过Context.registerReceiver()注册

ACTION_UID_REMOVED

一个用户ID已经从系统中移除

 

常见Category

CATEGORY_DEFAULT

Android系统中默认的执行方式,按照普通Activity的执行方式执行

CATEGORY_HOME

设置该组件为Home Activity

CATEGORY_PREFERENCE

设置该组件为Preference

CATEGORY_LAUNCHER

设置该组件为在当前应用程序启动器中优先级最高的Activity,通常为入口ACTION_MAIN配合使用

CATEGORY_BROWSABLE

设置该组件可以使用浏览器启动

CATEGORY_GADGET

设置该组件可以内嵌到另外的Activity中

 

在使用intent时,可以附件Data和Extras,Data通常是URI格式定义的操作数据。例如:tel:// 。通过setData()方法设置;Extras属性主要用于传递目标组件所需要的额外的数据。通过putExtras()方法设置。

常见Data

tel://

号码数据格式,后跟电话号码

mailto://

邮件数据格式,后跟邮件收件人地址

smsto://

短息数据格式,后跟短信接收号码

content://

内容数据格式,后跟需要读取的内容

file://

文件数据格式,后跟文件路径

market://search?q=pname:pkgname

市场数据格式,在Google Market里搜索包名为pkgname的应用

geo://latitude,longitude

经纬数据格式,在地图上显示经纬度指定的位置

 

常见Extras

EXTRA_BCC

存放邮件密送人地址的字符串数组

EXTRA_CC

存放邮件抄送人地址的字符串数组

EXTRA_EMAIL

存放邮件地址的字符串数组

EXTRA_SUBJECT

存放邮件主题字符串

EXTRA_TEXT

存放邮件内容

EXTRA_KEY_EVENT

以KeyEvent对象方式存放触发Intent的按键

EXTRA_PHONE_NUMBER

存放调用ACTION_CALL时的电话号码

在intent-filter中指定data属性的实际目的是:要求接收的Intent中的data必须符合intent-filter中指定的data属性,这样达到反向限定Intent的作用

例如:在AndroidManifest.xml 中进行如下设置:

<activity android:name=".TestActivity">

    <intent-filter>

         <action android:name="com.jony.test"/>

         <data android:scheme="file"/>

    </intent-filter>

</activity>

那么启动该Activity的Intent必须进行如下设置:

Intent intent = new Intent();

Uri uri =  Uri.parse("file://com.android.test:520/mnt/sdcard");

intent.setData(uri);

data属性解析:android:scheme、android:host、android:port、android:path、android:mimeType

 

data的前四个属性构成了URI的组成部分,mimeType设置了数据的类型

 

data元素组成的URI模型如下:

 

scheme://host:port/path

 

举例说明:

 

URI   file://com.android.jony.test:520/mnt/sdcard

 

scheme-->file:

 

host-->com.android.jony.test

 

port-->520

 

path-->mnt/sdcard

 

其中host和port为URI的authority,如果没有指定host,port将被忽略

 

data的各属性并不是独立的,data的各属性构成了URI的整个组成部分。要使authority(host和port)有意义,必须指定scheme;要使path有意义,必须使scheme和authority(host和port)有意义。

 

URI和intent-filter匹配:

 

Intent中URI和intent-filter进行比较的时候只会进行部分的比较:

 

(1)当intent-filter中只设置了scheme,只会比较URI的scheme部分;

 

(2)当intent-filter中只设置了scheme和authority,那么只会匹配URI中的scheme和authority;

 

(3)当intent-filter中设置了scheme、authority和path,那么只会匹配URI中的scheme、authority、path;(path可以使用通配符进行匹配)

 

  1. 当intent-filter中设置了mimeType,还会进行数据类型的匹配。

 

总结:

 

(1)在AndroidMainfest.xml 中对每一个Activity都做了说明——intent-filter,intent-filter声明了需要接收怎样的Intent,当发送的Intent和intent-filter中定义的相符合,就会启动相应的Activity;

 

(2)当有多个Activity符合发送的Intent时,Android系统会列出所有满足Intent的Activity,用户可以通过选择进行相关的操作;

 

(3)在一个Activity的intent-filter中可以有多个action、多个category、多个data,这样可以有多种组合与Intent进行匹配。注意:如果在一个Activity中有多个Intent进行匹配的时候,建议使用多个intent-filter与Intent进行匹配。猜测:这样应该可以提高Intent的匹配速度。

 

  1. data属性,这是一个进行反向限制Intent的操作,要求Intent的data必须是intent-filter中声明的数据之一(因为在一个intent-filter中可以设置多个data)。注意:如果要启动目标Activity,但是指定的data数据类型与Activity中data数据类型不匹配,将会造成ActivityNotFoundException异常。

// 调用浏览器

 

Uri webViewUri = Uri.parse("http://blog.csdn.net/zuolongsnail");

 

Intent intent = new Intent(Intent.ACTION_VIEW, webViewUri);

 

// 调用地图

 

Uri mapUri = Uri.parse("geo:100,100");

 

Intent intent = new Intent(Intent.ACTION_VIEW, mapUri);

 

// 播放mp3

 

Uri playUri = Uri.parse("file:///sdcard/test.mp3");

 

Intent intent = new Intent(Intent.ACTION_VIEW, playUri);

 

intent.setDataAndType(playUri, "audio/mp3");

 

// 调用拨打电话

 

Uri dialUri = Uri.parse("tel:10086");

 

Intent intent = new Intent(Intent.ACTION_DIAL, dialUri);

 

// 直接拨打电话,需要加上权限<uses-permission id="android.permission.CALL_PHONE" />

 

Uri callUri = Uri.parse("tel:10086");

 

Intent intent = new Intent(Intent.ACTION_CALL, callUri);

 

// 调用发邮件(这里要事先配置好的系统Email,否则是调不出发邮件界面的)

 

Uri emailUri = Uri.parse("mailto:zuolongsnail@163.com");

 

Intent intent = new Intent(Intent.ACTION_SENDTO, emailUri);

 

// 直接发邮件

 

Intent intent = new Intent(Intent.ACTION_SEND);

 

String[] tos = { "zuolongsnail@gmail.com" };

 

String[] ccs = { "zuolongsnail@163.com" };

 

intent.putExtra(Intent.EXTRA_EMAIL, tos);

 

intent.putExtra(Intent.EXTRA_CC, ccs);

 

intent.putExtra(Intent.EXTRA_TEXT, "the email text");

 

intent.putExtra(Intent.EXTRA_SUBJECT, "subject");

 

intent.setType("text/plain");

 

Intent.createChooser(intent, "Choose Email Client");

 

// 发短信

 

Intent intent = new Intent(Intent.ACTION_VIEW);

 

intent.putExtra("sms_body", "the sms text");

 

intent.setType("vnd.android-dir/mms-sms");

 

// 直接发短信

 

Uri smsToUri = Uri.parse("smsto:10086");

 

Intent intent = new Intent(Intent.ACTION_SENDTO, smsToUri);

 

intent.putExtra("sms_body", "the sms text");

 

// 发彩信

 

Uri mmsUri = Uri.parse("content://media/external/images/media/23");

 

Intent intent = new Intent(Intent.ACTION_SEND);

 

intent.putExtra("sms_body", "the sms text");

 

intent.putExtra(Intent.EXTRA_STREAM, mmsUri);

 

intent.setType("image/png");

 

// 卸载应用

 

Uri uninstallUri = Uri.fromParts("package", "com.app.test", null);

 

Intent intent = new Intent(Intent.ACTION_DELETE, uninstallUri);

 

// 安装应用

 

Intent intent = new Intent(Intent.ACTION_VIEW);

 

intent.setDataAndType(Uri.fromFile(new File("/sdcard/test.apk"), "application/vnd.android.package-archive");

 

// 在Android Market中查找应用

 

Uri uri = Uri.parse("market://search?q=愤怒的小鸟");          

 

Intent intent = new Intent(Intent.ACTION_VIEW, uri);  


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值