android_Intent

Intent

    Intent是抽象的数据结构,包含了一系列描述某个操作的数据,使得程序在运行时可以在程序中不同组件间通信或启动

不同的应用程序。可以通过startActivity(Intent)启动一个Activity, sendBroadcast(Intent) 发送广播发送给感兴

趣的BroadcastReceiver组件, startService(Intent)启动service,bindService(Intent, ServiceConnection, int)绑定服务。

IntentFilter

Intent Filter顾名思义就是Intent的过滤器,组件通过定义Intent Filter可以决定哪些隐式Intent可以和该组件进行通讯。

关于隐式Intent的定义后面会进行介绍,Intent Filter对显式的Intent不起作用。

Action

Action就是个String类型的字符串,在隐式Intent中用来和filter进行匹配的关键指标,如ACTION_VIEW,ACTION_EDIT等,Intent内置了很多Action常量

,我们也可以自定义私有Action方便自己进行匹配。

Data为Uri类型的数据,若mType为空通过对mData的解析可以得到数据的类型。

Component表示组件信息,包含context和目标组件的class信息,设置了即为显示Intent。

Category作为决定哪个组件处理Intent的附属信息,一个Intent可以添加或删除多个Category存储在mCategories。

Flag用于标记如何启动一个活动,是NEW_TASK还是其他等等,以及启动后怎么对待这个活动。

Extras为附加信息,会传递给目标组件,比如发送邮件,Extras可以存储邮件收件人地址、内容、主题、附件等信息。

因为Intent Filter和Intent的匹配只有三个字段起作用,所以Intent Filter只包含Actions、Datas、Categorys三个属性(实际源码中会将Data划分为多个部分),

属性的意义和Intent相同。不同的是Intent Filter可以包含多个Action、多个Data、多个Category,而Intent除Category可以有多个外,只能有一个Action


Intent类型

对于一个定义好的Intent,Android如何判断和哪个目标组件通讯呢。Intent分为隐式(implicit)Intent和显式(explicit)Intent。

显式Intent通常用于在程序内部组件间通信,已经明确的定义目标组件的信息,所以不需要系统决策哪个目标组件处理Intent,如下

Intent intent = new Intent(DemoList.this, GoogleMapDemo.class);

startActivity(intent);

其中DemoList和GoogleMapDemo都是用户自定义的组件,

隐式Intent不指明目标组件的class,只定义希望的Action及Data等相关信息,由系统决定使用哪个目标组件。如发送短信

Uri uri = Uri.parse("smsto:15800000000");

Intent i = new Intent(Intent.ACTION_SENDTO, uri);

i.putExtra("sms_body", "The SMS text");

startActivity(i);

Intent和IntentFilter匹配规则

Android系统通过对Intent和目标组件在AndroidManifest文件中定义的<intent-filter>(也可以在程序中定义Intent Filter)进行匹配决定和哪个目标组件通讯。

如果某组件未定义<intent-filter>则只能通过显式的Intent进行通信。Intent的三个属性用于对目标组件选取的决策,分别是Action、Data(Uri和Data Type)、Category

。匹配规则如下

a. Intent定义的Action必须包含在<intent-filter>的Action列表中,若隐式Intent未定义Action系统会报错。由此可知一个<intent-filter>至少包含一个Action。

b. 未定义Uri和Type的Intent仅可以通过不包含包含Uri和Type的filter;包含了Uri,不包含Type的Intent仅可以通过包含匹配Uri不包含Type的filter;包含了Type不

包含Uri的Intent仅可以通过包含了相同Type不包含Uri的filter;同时包含了Uri和Type的Intent仅可以通过相同Type匹配Uri(或不包含Uri但Intent Uri为content:或file:)

的filter。

c. Intent若定义了Category(可多个),则所有Category必需包含在<intent-filter>的Category列表中。若Intent未定义Category,则<intent-filter>是否定义Category

不影响。

PS:<intent-filter>必须包含<category android:name="android.intent.category.DEFAULT" />才能通过startActivity启动,所以Activity的<intent-filter>至少包含一

个category,Service和BroadcastReceiver不必。

目标组件必须包含同时满足以上规则的<intent-filter>才能进行匹配。若有多个目标组件同时可以匹配,则系统会提示用户进行选择,若没有目标组件可以匹配系统会进行提示。

eg:

a. 发送短信

Uri uri = Uri.parse("smsto:15800000000");

Intent i = new Intent(Intent.ACTION_SENDTO, uri);

i.putExtra("sms_body", "The SMS text");

startActivity(i);

b. 打电话

Uri dial = Uri.parse("tel:15800000000");

Intent i = new Intent(Intent.ACTION_DIAL, dial);//"android.intent.action.CALL"

startActivity(i);

c. 发送邮件

Uri email = Uri.parse("mailto:[email protected];[email protected]");

Intent i = new Intent(Intent.ACTION_SENDTO, email);

startActivity(i);

Intent i = new Intent(Intent.ACTION_SEND);

String[] tos = {"[email protected]"};

String[] ccs = {"[email protected]"};

i.putExtra(Intent.EXTRA_EMAIL, tos);

i.putExtra(Intent.EXTRA_CC, ccs);

i.putExtra(Intent.EXTRA_SUBJECT, "主题");

i.putExtra(Intent.EXTRA_TEXT, "正文");

i.setType("message/rfc822");

startActivity(i);

d. 拍照

Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

String folderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "AndroidDemo" + File.separator;

String filePath = folderPath + System.currentTimeMillis() + ".jpg";

new File(folderPath).mkdirs();

File camerFile = new File(filePath);

i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(camerFile));

startActivityForResult(i, 1);

e. 浏览网页

Uri web = Uri.parse("http://www.google.com"); 

Intent i  = new Intent(Intent.ACTION_VIEW, web); 

startActivity(i);

f. 查看联系人

Intent i = new Intent();

i.setAction(Intent.ACTION_GET_CONTENT);

i.setType("vnd.android.cursor.item/phone");

startActivityForResult(i, 1);


你可能感兴趣的:(android_Intent)