Android 第6讲:意图
1. 什么是意图
Android四大组件:活动、服务、广播、内容提供者。活动、服务、广播这些组件之间的调用和消息传递都是通过意图实现的,意图是一种消息机制
1.1 意图与目标组件
意图就像是快递源,穿行在各个组件之间。意图有三种主要的方式来实现组件间的通信:
- 启动活动。通过将意图对象传递给活动的startActivity()方法或startActivityForResult()方法来启动一个活动。
- 启动服务。通过将意图对象传递给服务startService()方法启动一份本地服务,通过将意图传递给服务bindService()方法,连接一个远程服务。
- 发送广播。通过调用给广播接收器sendBroadcast()等方法可将广播发送给其他应用。
1.2 意图包含
意图对象包含:目标组件(Component)、动作(Action)、数据(Data)、类别(Category)、附加数据(Extra)、标志(Flag)。其中目标组件可以帮助应用发送显式意图调用请求,动作、数据、类别可以构建一个意图过滤器。意图过滤器可以帮助应用发送隐式意图调用请求,实现查询目标组件。附加数据用于传递参数给目标组件,标志是指目标组件任务行为。
2. Intent常用构造方法
-
Intent()
创建一个没有任何意图的Intent对象,该对象可以使用 setActio (String action) 方法添加相应的动作,以便体现Intent对象的意图,例如:Intent intent = new Intent(); intent. setAction(Intent. ACTION_DIAL);
-
Intent(String action)
创建一个Intent 对象,该对象中的动作由参数 action 来描述 ,例如:Intent intent= new Intent(Intent. ACTION_DIAL);
也就是说 Intent(String action) 构造方法的关键是通过一个动作来构造 Intent对象,即通过 个动作来体现一个意图
-
lntent(String action, Uri uri)
lntent(String action, Uri uri) 构造方法的关键是通过一个动作 action 和一个 Uri 类型的数据 uri 来体现 一个意图,即构造 Intent 对象,例如:Uri uri =Uri.parse("tel: 13887698765"); Inten intent = new Intent (In ent ACTION DIAL,u立);
那么, Intent 对象体现的意图就是"拨打电话 13887698765", 即该意图是通过一个动作"拨打电话”和一个数据 “13887698765” 来体现的。
Ur parse 方法会从 “tel: 13887698765” 中解析出 一个 电话号码 “13887698765” 放到Uri 对象中,比如,对于Uri uri=Uri. parse(“tel:-lpolicelO”); Uri 对象中的电话号码110。
上述三个构造方法创建的 Intent 对象所体现的意图被习惯地称为隐式意图 (ImplicitIntents) , 即没有明确给出启用哪个 Activity 对象来完成意图,因此使用上述构造方法创建
Intent 对象,可能启动多个 Activity 对象。比如, Intent 类的静态常量VIEW 表示的动作是将数据显示给用户(甚至没有说显示怎样类型的数据),那么程序执行下列代码后:
Intent intent= new Intent(Intent. ACTION_ VIEW);
startAcvity(intent);
startActivity(Intent intent) 方法在手机(或 AVD)的Android 系统内找到有多个 Activity 对象能完成这个意图(这些Activity 主要是显示系统内部的一些数据),因此列出了所有Activity 对象,让用户选择其中一个Activity 对象,并**所选择的 Activity 对象。
- Intent(Context packageContext,Class< ?> els)
该构造方法创建的 Intent 对象体现的意图被习惯地称为显式意图 (Explicit Intents), 即非常准确地给出了要启动的Activity 对象 该构造方法的参数 packageContext 是当前应用程序所在的上下文,参数 els 是打算启动的 Activity 对象的类的名字(该类负责创建要启动的 Activity 对象),比如,当前应用程序中有名字为 Hello的Activity 的子类,那么可如下创建一个 Intent 对象:Intent intent= new Intent(this, Hello. class);
3. 意图类型
意图分为两种类型:显示意图(Explicit Intent)和隐式意图(Implicit Intent)
3.1 显示意图
显示意图是通过指定组件名称直接启动组件,可以通过下面的方法实现显示意图。Intent类中方法
- setComponent(ComponentName name)。其中ComponentName类是Android框架提供的组件封装类,需要提供包名、类名或context上下文对象。
- setClassName(String packageName,String classNameInThatPackage)。提供包名和目标组件类名。
- setClassName(Context context,String classNameInThatContext)
- setClass(Context context,Class classObjectInThatContext)
除了上述方法外,可以在直接构造意图对象时,指定context对象和目标组件类型
Intent intent =new Intent(LoginActivity.this,FailureActivity.class);
startActivity(intent);
3.2 隐式意图
隐式意图用于不同应用之间调用。因此隐式意图请求要提供意图过滤器,目标组件要在它所在的应用的AndroidManidest.xml中注册该组件和意图过滤器。
<activity android:name=".AppStart">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
4. 匹配组件
为了能够找到应用程序的组件,Android通过一些隐式意图请求实现。Android系统查找所有与意图匹配的意图过滤器,然后启动目标组件。步骤如下:
- Activity A创建包含动作、数据、类别等信息的隐式意图,并将其传递给startActivity(),交给Android系统。
- Activity 系统查找相匹配的应用组件,即满足目标组件声明的意图过滤器条件。
- 如果找到匹配的过滤器,Android系统启动目标组件
在匹配时,通过三个意图属性考虑匹配
- 动作
- 数据
- 类别
一个隐式意图要求能够传递给目标组件,必须要通过这三个属性的检查,如任意一方不匹配,Android都不会将该隐式意图传递给目标组件。
4.1 动作(Action)
动作是指定意图要执行的任务。动作是用一个字符串常量描述。
意图对象中的动作可以通过 setAction() 方法来设置,也可以在创建 Intent 的同时进行设置,通过 getAction() 方法来读取。
常量名称 | 常量值 | 意义/描述 |
---|---|---|
ACTION_MAIN | android.intent.action.MAIN | 应用程序入口 |
ACTION_VIEW | android.intent.action.VIEW | 显示数据给用户 |
ACTION_ATTACH_DATA | android.intent.action.ATTACH_DATA | 指明附加信息给其他地方的一些数据 |
ACTION_EDIT | android.intent.action.EDIT | 显示可编辑的数据 |
ACTION_PICK | android.intent.action.PICK | 选择数据 |
ACTION_CHOOSER | android.intent.action.CHOOSER | 显示一个Activity选择器 |
ACTION_GET_CONTENT | android.intent.action.GET_CONTENT | 获得内容 |
ACTION_DIAL | android.intent.action.GET_CONTENT | 显示打电话面板 |
ACITON_CALL | android.intent.action.DIAL | 直接打电话 |
ACTION_SEND | android.intent.action.SEND | 直接发短信 |
ACTION_SENDTO | android.intent.action.SENDTO | 选择发短信 |
ACTION_ANSWER | android.intent.action.ANSWER | 应答电话 |
ACTION_INSERT | android.intent.action.INSERT | 插入数据 |
ACTION_DELETE | android.intent.action.DELETE | 删除数据 |
ACTION_RUN | android.intent.action.RUN | 运行数据 |
ACTION_SYNC | android.intent.action.SYNC | 同步数据 |
ACTION_PICK_ACTIVITY | android.intent.action.PICK_ACTIVITY | 选择Activity |
ACTION_WEB_SEARCH | android.intent.action.WEB_SEARCH | Web搜索 |
ACTION_FACTORY_TEST | android.intent.action.FACTORY_TEST | 工厂测试入口点 |
ACTION_SEARCH | android.intent.action.SEARCH | 搜索 |
举例选择发短息
在AndroidManifest.xml文件中。指定SENDTO动作过滤器的代码如下
<activity android:name=".SendActivity">
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
隐式意图需要设置这个动作才能匹配,代码如下:
Intent intent=new Intent();
intent.setAction(Intent.ACTION_SENDTO);
startActivity(intent);
自定义动作
可以在自己的应用中指定动作,他的命名规则一般是“应用包名+自己动作”
在AndroidManifest.xml文件中代码如下:
<activity android:name=".SuccessActivity">
<intent-filter>
<action android:name="com.a51work6.loginsample.SUCCESS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
隐式意图的设置
private static final String ACTION_APP_SUCCESS ="com.a51work6.loginsample.SUCCESS";
Intent intent =new Intent();
intent.setAction(ACTION_APP_SUCCESS);
startActivity(intent);
4.2 数据(Data)
数据是指定目标组件需要的数据,他是由指定数据的URI和数据的MIME类型两部分组成的。
URI是统一资源标识符,它可以指定一个资源
MIME类型是资源的数据类型,是设定某种扩展名的文件用一种应用程序来打开的方式类型。
添加数据的意图过滤器在AndroidManifest.xml中代码如下
<intent-filter>
....
<data android:mimeType="sudio/MP3" android:scheme="http"..../>
</intent-filter>
android:scheme属性设置URI中scheme,此外还包括android:host、android: port、android:path
隐式意图设置数据代码如下:
Intent intent =new Intent();
Uri playUri =new Uri.parse("www.51work6.com/mp3/ma_mma.mp3");
intent.setDataAndType(playUri,"audio/MP3");
startActivty(intent);
在隐式意图中,单独设置MIME类型使用setType()方法,单数设置Uri使用setData()方法,但是如果同时设置MIME和Uri必须使用setDataAndType()方法。同时使用setType()方法和setData()方法会覆盖数据。
4.3 类别(Category)
类别包含了请求组件的一些附加信息。常用的类别有两种
- android.intent.category.LAUNCHER和android.intent,action.MAIN动作一起使用,表明该活动是一个启动的活动
<activity android:name=".AppStart"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
- android.intent.category.DEFAULT,指定默认的类别,意图过滤器必须要指定一个类别,默认情况下可以使用该类别
每一个通过测试的隐式意图都至少有一个类别,如果没有别的类别指定,默认要指定android.intent.category.DEFAULT;如果没有任何类别,系统会抛出异常。<activity android:name=".FailureActivity"> <intent-filter> <action android:name="com.a51work6.loginsample.FALLURE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
自定义类别
AndroidManifest.xml
<activity android:name=".SuccessActivity">
<intent-filter>
<action android:name="com.a51work6.loginsample.SUCCESS" />
<category android:name="com.a51work6.loginsample.SUCCESS" />
<data android:mimeType="text/html"/>
</intent-filter>
</activity>
隐式意图代码
public static final String ACTION_APP_SUCCESS ="com.a51work6.loginsample.SUCCESS";
public static final String CATEGORY_APP_SUCCESS="com.a51work6.loginsample.SUCCESS";
....
Intent intent =new Intent();
intent.setAction(ACTION_APP_SUCCESS);
intent.addCategory(String CATEGORY_APP_SUCCESS);
...
startActivity(intent);
附加数据(Extra)和 标志(Flag)在Android第2讲中提过
后续文章持续更新中。。。。