Intent最基本的功能就是启动组件。Intent能启动android四大组件中的三种:Activity、Service和BroadcastReceiver。
Intent有如下七个重要的属性:ComponentName、Action、Category、Data、Type、Extra和Flag。
Intent分为两类:显示Intent和隐式Intent。
通过Intent的ComponentName属性去启动组件就叫显示Intent。ComponentName是android对系统组件的标识,它包含一个包名和一个类全名(都是字符串类型)。
通过Intent的属性Action、Category等去启动组件就叫隐式Intent。通过隐式Intent去启动组件需要在被启动的组件元素下配置intent-filte子元素。intent-filte可以配置Action和Category子元素,与Intent设置的Action和Category相对应。
显示Intent只能启动同一应用下的组件;隐式Intent不但能启动同一应用下的组件,也能启动其他应用下的组件(这正是隐式Intent的真正意图)。例如,要在应用中启动浏览器,就需要隐式Intent。
显示Intent会覆盖隐式Intent,也就是说如果一个Intent既配置了ComponentName,又配置了Action等,ComponentName会覆盖其他属性。
显示Intent很简单,就不多少了。下面说说隐式Intent。
隐式Intent
下面通过一个例子来说明如何通过隐式Intent来启动一个组件。
启动另一个组件activity代码:
Intent intent = new Intent();
intent.setAction("com.zzj.ui.INTENTACTIVITY");
intent.addCategory("com.zzj.ui.DEFAULT");
intent.setDataAndType(Uri.parse("http://www.csdn.net:80/article"),
"text/html");
startActivity(intent);
在被启动的Activity中显示Intent信息:
package com.zzj.ui.intentdemo;
import java.util.Set;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;
import com.zzj.ui.R;
public class OtherActivity extends Activity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other_intent_activity);
textView = (TextView) findViewById(R.id.textView);
StringBuilder sb = new StringBuilder();
Intent intent = getIntent();
// 输出包名和类名
sb.append("--------包名和类名--------");
sb.append("\r\n");
ComponentName componentName = intent.getComponent();
sb.append("packageName --> ");
sb.append(componentName.getPackageName());
sb.append("\r\n\r\n");
sb.append("className --> ");
sb.append(componentName.getClassName());
sb.append("\r\n\r\n");
sb.append("shortClassName --> ");
sb.append(componentName.getShortClassName());
sb.append("\r\n\r\n");
// 输出action
sb.append("--------action--------");
sb.append("\r\n");
sb.append(intent.getAction());
sb.append("\r\n\r\n");
// 输出category
sb.append("--------categories--------");
sb.append("\r\n");
Set<String> categories = intent.getCategories();
for (String category : categories) {
sb.append(category);
sb.append("\r\n");
}
sb.append("\r\n");
// 输出MimeType
sb.append("--------MimeType--------");
sb.append("\r\n");
sb.append("MimeType --> ");
sb.append(intent.getType());
sb.append("\r\n\r\n");
// 输出data
sb.append("--------data(uri)--------");
sb.append("\r\n");
Uri uri = intent.getData();
sb.append("uri --> ");
sb.append(uri.toString());
sb.append("\r\n\r\n");
sb.append("scheme --> ");
sb.append(uri.getScheme());
sb.append("\r\n\r\n");
sb.append("host --> ");
sb.append(uri.getHost());
sb.append("\r\n\r\n");
sb.append("port --> ");
sb.append(uri.getPort());
sb.append("\r\n\r\n");
sb.append("path --> ");
sb.append(uri.getPath());
sb.append("\r\n\r\n");
textView.setText(sb.toString());
}
}
在AndroidManifest.xml中配置被启动的Activity:
<intent-filter>
<action android:name="com.zzj.ui.OTHERACTIVITY" />
<action android:name="com.zzj.ui.INTENTACTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.zzj.ui.DEFAULT" />
<category android:name="com.zzj.ui.INTENT" />
<data
android:host="www.csdn.net"
android:mimeType="text/html"
android:path="/article"
android:port="80"
android:scheme="http" />
</intent-filter>
一般情况下,Intent会默认添加一个名为android.intent.category.DEFAULT的category,所以需要在intent-filter中配置。
布局文件很简单,就不贴了。下面贴出被启动的Activity的界面效果:
URI分为scheme、host、port和path四个部分,标准模式为:
scheme://host:port/path
or pathPrefix
or pathPattern
不是每个部分都是必须的。
隐式Intent需要匹配三个元素:Action、Category以及Data。
Action和Category的匹配很简单,只要保证Intent中设置的Action和Category是intent-filter中配置的Action和Category的子集就行了。
Data的匹配比较复杂,就不去研究了。下面说说如何利用Data传参。
利用Data传参
我们跳转到拨号界面时,可以传递一个电话号码,通过intent.setData(Uri data)设置。下面我们来模拟一下。
intent设置:
intent.setAction("com.zzj.ui.PHONE");
intent.setData(Uri.parse("tel:13478764456"));
拨号activity类:
package com.zzj.ui.intentdemo;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;
import com.zzj.ui.R;
public class PhoneActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.phone_activity);
Uri uri = getIntent().getData();
if (uri != null) {
String[] uris = uri.toString().split(":");
if (uris.length > 1) {
((TextView) findViewById(R.id.phone_number)).setText(uris[1]);
}
}
}
}
在AndroidManifest.xml中配置拨号Activity:
<intent-filter>
<action android:name="com.zzj.ui.PHONE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
拨号activity布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/phone_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拨号" />
</LinearLayout>
拨号界面效果:
系统自带的Action和Category
Action常量 | 对应字符串 | 简单说明 |
---|---|---|
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.DIAL | 显示拨号面板 |
ACTION_CALL | android.intent.action.CALL | 直接向指定用户打电话 |
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_SEARCH | android.intent.action.SEARCH | 执行搜索 |
ACTION_WEB_SEARCH | android.intent.action.WEB_SEARCH | 执行Web搜索 |
ACTION_FACTORY_TEST | android.intent.action.FACTORY_TEST | 工厂测试的入口点 |
Category常量 | 对应字符串 | 简单说明 |
---|---|---|
CATEGORY_DEFAULT | android.intent.category.DEFAULT | 默认的Category |
CATEGORY_BROWSABLE | android.intent.category.BROWSABLE | 指定该Activity能被浏览器安全调用 |
CATEGORY_TAB | android.intent.category.TAB | 指定该Activity作为TabActivity的Tab页 |
CATEGORY_LAUNCHER | android.intent.category.LAUNCHER | Activity显示顶级程序列表中 |
CATEGORY_INFO | android.intent.category.INFO | 用于提供包信息 |
CATEGORY_HOME | android.intent.category.HOME | 设置该Activity随系统启动而运行 |
CATEGORY_PREFERENCE | android.intent.category.PREFERENCE | 该Activity是参数面板 |
CATEGORY_TEST | android.intent.category.TEST | 该Activity是一个测试 |
CATEGORY_CAR_DOCK | android.intent.category.CAR_DOCK | 指定手机被插入汽车底座(硬件)时运行该Activity |
CATEGORY_DESK_DOCK | android.intent.category.DESK_DOCK | 指定手机被插入桌面底座(硬件)时运行该Activity |
CATEGORY_CAR_MODE | android.intent.category.CAR_MODE | 设置该Activity可在车载环境下使用 |