Android开发-API指南-常用Intent

Common Intents 

英文原文:http://developer.android.com/guide/components/intents-common.html
采集(更新)日期:2014-7-16
搬迁自原博客:http://blog.sina.com.cn/s/blog_48d491300102uy20.html

通过 Intent 可以启动其他应用程序中的 Activity ,只要在此 Intent 对象中给出需要执行的操作即可(比如“查看地图”或“拍照”)。 由于这里未指定需要启动的组件,而只是给出了 Action 和执行 Action 所用到的 数据, 这种 Intent 就被称为隐式 Intent。

在把隐式 Intent 作为参数调用 startActivity()startActivityForResult() 时,系统会 解析该 Intent 并发送给能够处理该 Intent 的应用程序,并启动相应的 Activity。 如果能够处理该 Intent 的应用程序超过一个,系统会给出对话框供用户选择。

本文介绍了多个用于执行常见 Action 的隐式 Intent,并按照处理这些 Intent 的应用程序进行了归类。 每个章节还介绍了如何通过创建 Intent 过滤器 来对应用程序的 Action 处理能力进行公布。

提醒: 如果当前设备上不存在可接收某种隐式 Intent 的应用程序,则调用 startActivity() 的应用程序将会崩溃。 为了预先判断一下是否存在可接收 Intent 的应用程序,请调用 Intent 对象的 resolveActivity()。 如果结果非空,则表示至少存在一个可处理该 Intent 的应用程序,并且可安全调用 startActivity()。 如果结果为 null ,请勿再使用该 Intent,并尽可能关闭那些会发起该 Intent 的功能。

如果还不清楚 Intent 和 Intent 过滤器的创建过程,请先去阅读 Intent 和 Intent 过滤器

闹钟


创建闹钟

要新建一个闹钟,请使用ACTION_SET_ALARM 并设置闹钟的详细参数,包括在 Intent 的附件(extra)中给出时间和文字信息,如下所示。

注意: 在 Android 2.3 (API 级别 9)版本中,附件里只能包含小时、分钟和文字信息。 其他类型的附件是在后续版本的系统中加入的。

Action
ACTION_SET_ALARM
数据 URI
MIME 类型
附件
EXTRA_HOUR
闹钟的小时数。
EXTRA_MINUTES
闹钟的分钟数
EXTRA_MESSAGE
用于标识闹钟的文字信息。
EXTRA_DAYS
一个 ArrayList 对象, 存放了本闹钟需要在每周的星期几重复触发。 每一天用 Calendar 类中定义的整数值来表示,比如 MONDAY

如果是一次性的闹钟,请勿给出该附件。

EXTRA_RINGTONE
一个 content: URI ,用于指定闹钟所用的铃声。 如果不需要铃声则为 VALUE_RINGTONE_SILENT

如果要使用默认的铃声,就不需要指定本附件。

EXTRA_VIBRATE
布尔值,指明闹钟是否需要振动。
EXTRA_SKIP_UI
布尔值,指明应用程序在设定闹钟时是否要跳过用户交互过程。 如果设为 True ,则应用程序将会跳过所有的确认界面,直接设定所需的闹钟。

Intent 示例:

1 public void createAlarm(String message, int hour, int minutes) {
2     Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
3             .putExtra(AlarmClock.EXTRA_MESSAGE, message)
4             .putExtra(AlarmClock.EXTRA_HOUR, hour)
5             .putExtra(AlarmClock.EXTRA_MINUTES, minutes);
6     if (intent.resolveActivity(getPackageManager()) != null) {
7         startActivity(intent);
8     }
9 }

 

注意:

为了调用 ACTION_SET_ALARM Intent,应用程序必须拥有 SET_ALARM 权限:

< uses-permission android:name="com.android.alarm.permission.SET_ALARM" / > 

Intent 过滤器示例:

1 <activity ...>
2     <intent-filter>
3         <action android:name="android.intent.action.SET_ALARM" />
4         <category android:name="android.intent.category.DEFAULT" />
5     </intent-filter>
6 </activity>

 

创建计时器

要创建一个倒计时的计时器,请使用 ACTION_SET_TIMER 并在附件中设定计时器的详细参数,比如时长,如下所示。

注意:本 Intent 自 Android 4.4 (API 级别 19)开始引入。

Action
ACTION_SET_TIMER
数据 URI
MIME 类型
附件
EXTRA_LENGTH
计时器的时长,单位为秒。
EXTRA_MESSAGE
用于标识该计时器的自定义文字信息。
EXTRA_SKIP_UI
布尔值,指明应用程序在设定计时器时是否要跳过用户交互过程。 如果设为 True ,则应用程序将会跳过所有的确认界面,直接设定所需的计时器。

Intent 示例:

1 public void startTimer(String message, int seconds) {
2     Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER)
3             .putExtra(AlarmClock.EXTRA_MESSAGE, message)
4             .putExtra(AlarmClock.EXTRA_LENGTH, seconds)
5             .putExtra(AlarmClock.EXTRA_SKIP_UI, true);
6     if (intent.resolveActivity(getPackageManager()) != null) {
7         startActivity(intent);
8     }
9 }

 

注意:

为了调用 ACTION_SET_TIMER Intent ,应用程序必须拥有 SET_ALARM 权限:

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

Intent 过滤器示例:

1 <activity ...>
2     <intent-filter>
3         <action android:name="android.intent.action.SET_TIMER" />
4         <category android:name="android.intent.category.DEFAULT" />
5     </intent-filter>
6 </activity>

 



列出所有闹钟

要显示所有闹钟的列表,请使用 ACTION_SHOW_ALARMS

虽然用到本 Intent 的应用程序应该不会很多(主要用于系统应用), 所有当作闹钟使用的应用程序都必须实现本 Intent 过滤器,以便能列出当前所有的闹钟。

注意: 本 Intent 自 Android 4.4 (API 级别 19)开始引入。

Action
ACTION_SHOW_ALARMS
数据 URI
MIME 类型

Intent 过滤器示例:

1 <activity ...>
2     <intent-filter>
3         <action android:name="android.intent.action.SHOW_ALARMS" />
4         <category android:name="android.intent.category.DEFAULT" />
5     </intent-filter>
6 </activity>

 

Calendar


添加日历事件

为了在用户的日历中加入一个新事件,请使用 ACTION_INSERT 并用 Events.CONTENT_URI 指定数据 URI 。 还可以在附件中设定事件的各种细节参数,如下所示。

Action
ACTION_INSERT
数据 URI
Events.CONTENT_URI
MIME 类型
"vnd.android.cursor.dir/event"
附件
EXTRA_EVENT_ALL_DAY
布尔值,指明是否为全天性事件。
EXTRA_EVENT_BEGIN_TIME
事件的起始时间(自公元纪年开始的毫秒数)。
EXTRA_EVENT_END_TIME
事件的终止时间(自公元纪年开始的毫秒数)。
TITLE
事件的标题。
DESCRIPTION
事件的说明。
EVENT_LOCATION
事件的地点。
EXTRA_EMAIL
受邀者的 Email 地址列表,中间用逗号分隔。

可用的事件参数还有很多,都在 CalendarContract.EventsColumns 类中给出了常量定义。

Intent 示例:

 1 public void addEvent(String title, String location, Calendar begin, Calendar end) {
 2     Intent intent = new Intent(Intent.ACTION_INSERT)
 3             .setData(Events.CONTENT_URI)
 4             .putExtra(Events.TITLE, title)
 5             .putExtra(Events.EVENT_LOCATION, location)
 6             .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
 7             .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end);
 8     if (intent.resolveActivity(getPackageManager()) != null) {
 9         startActivity(intent);
10     }
11 }

Intent 过滤器示例:

1 <activity ...>
2     <intent-filter>
3         <action android:name="android.intent.action.INSERT" />
4         <data android:mimeType="vnd.android.cursor.dir/event" />
5         <category android:name="android.intent.category.DEFAULT" />
6     </intent-filter>
7 </activity>

 

摄像头


拍照或摄像并返回结果

为了启动摄像头应用并接收返回的照片或视频,请使用 ACTION_IMAGE_CAPTUREACTION_VIDEO_CAPTURE 。 并且在附件 EXTRA_OUTPUT 中,还需要指定照片或视频的保存位置 URI 。

Action
ACTION_IMAGE_CAPTURE
ACTION_VIDEO_CAPTURE
数据 URI Scheme
MIME 类型
附件
EXTRA_OUTPUT
摄像头应用将把照片或视频文件保存到 URI 指定的位置 (以 Uri 对象的方式给出)。

一旦摄像头应用成功返回到调用 Activity (应用程序收到 onActivityResult() 回调方法),就可以在由 EXTRA_OUTPUT 值指定的 URI 位置访问到照片或视频文件。

注意: 当使用 ACTION_IMAGE_CAPTURE 拍照时,摄像头可以在结果 Intent 中同时返回一张小尺寸的缩略图,位于附件中的“data”字段中,格式为 Bitmap

Intent 示例:

 1 static final int REQUEST_IMAGE_CAPTURE = 1;
 2 static final Uri mLocationForPhotos;
 3 
 4 public void capturePhoto(String targetFilename) {
 5     Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
 6     intent.putExtra(MediaStore.EXTRA_OUTPUT,
 7             Uri.withAppendedPath(mLocationForPhotos, targetFilename);
 8     if (intent.resolveActivity(getPackageManager()) != null) {
 9         startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
10     }
11 }
12 
13 @Override
14 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
15     if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
16         Bitmap thumbnail = data.getParcelable("data");
17         // Do other work with full size photo saved in mLocationForPhotos
18         ...
19     }
20 }

 

关于如何通过 Intent 拍照的更多信息,包括如何为保存文件创建合适的 Uri, 请参阅 拍照初步摄像初步

Intent 过滤器:

1 <activity ...>
2     <intent-filter>
3         <action android:name="android.media.action.IMAGE_CAPTURE" />
4         <category android:name="android.intent.category.DEFAULT" />
5     </intent-filter>
6 </activity>

 

在处理该 Intent 时, Activity 应该检查传入 Intent 的附件数据 EXTRA_OUTPUT ,然后把捕获到的图像或视频保存到该其指定的位置,并用包含了缩略图的 Intent 调用 setResult() ,缩略图数据应存放在 Intent 附件的“data”部分。

通讯录/联系人应用


选择联系人

要让用户选择联系人并访问其所有数据,请使用 ACTION_PICK ,并把 MIME 类型设定为 Contacts.CONTENT_TYPE

在传给回调方法 onActivityResult() 的结果 Intent 中,包含了指向所选的联系人数据的 content: URI 。 这时还向调用方应用临时授予读取通讯录的权限,这是通过 Contacts Provider API 来完成的,即使该应用没有包含 READ_CONTACTS 权限也没有关系。

提示: 如果只需要访问联系人的部分信息,比如电话号码或 Email 地址,请参阅下一章节 选择联系人的指定信息

Action
ACTION_PICK
数据 URI Scheme
MIME 类型
Contacts.CONTENT_TYPE

Intent 示例:

 1 static final int REQUEST_SELECT_CONTACT = 1;
 2 
 3 public void selectContact() {
 4     Intent intent = new Intent(Intent.ACTION_PICK);
 5     intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
 6     if (intent.resolveActivity(getPackageManager()) != null) {
 7         startActivityForResult(intent, REQUEST_SELECT_CONTACT);
 8     }
 9 }
10 
11 @Override
12 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
13     if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
14         Uri contactUri = data.getData();
15         // Do something with the selected contact at contactUri
16         ...
17     }
18 }

有了联系人的 URI 之后,如何读取联系人详细数据的详细内容,请参阅 读取联系人详细数据。 请记住,用上述 Intent 访问联系人 URI 时,读取详细信息是不需要 READ_CONTACTS 权限的。

选择联系人的指定信息

为了能让用户选择联系人的部分信息,比如电话、Email 地址或其他数据,请使用 ACTION_PICK ,并指定下述的数据 MIME 类型,比如 CommonDataKinds.Phone.CONTENT_TYPE 就是用于获取联系人电话号码的。

如果只需要从通讯录中读取某一类数据,则用 ContactsContract.CommonDataKinds 类中定义的 CONTENT_TYPE 会比上一节提到的 Contacts.CONTENT_TYPE 效率更高,因为返回的结果直接就是目标数据,不需要再在 Contacts Provider 上执行更复杂的查询。

在传给回调方法 onActivityResult() 的结果 Intent 中,包含了指向所选的联系人数据的 content: URI 。 这时还向调用方应用临时授予读取通讯录的权限,即使该应用没有包含 READ_CONTACTS 权限也没有关系。

Action
ACTION_PICK
数据 URI Scheme
MIME 类型
CommonDataKinds.Phone.CONTENT_TYPE
读取联系人电话号码。
CommonDataKinds.Email.CONTENT_TYPE
读取联系人 email 地址。
CommonDataKinds.StructuredPostal.CONTENT_TYPE
读取联系人邮寄地址。

或者是 ContactsContract 中定义的其他 CONTENT_TYPE 值。

Intent 示例:

 1 static final int REQUEST_SELECT_PHONE_NUMBER = 1;
 2 
 3 public void selectContact() {
 4     // Start an activity for the user to pick a phone number from contacts
 5     Intent intent = new Intent(Intent.ACTION_PICK);
 6     intent.setType(CommonDataKinds.Phone.CONTENT_TYPE);
 7     if (intent.resolveActivity(getPackageManager()) != null) {
 8         startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER);
 9     }
10 }
11 
12 @Override
13 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
14     if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == RESULT_OK) {
15         // Get the URI and query the content provider for the phone number
16         Uri contactUri = data.getData();
17         String[] projection = new String[]{CommonDataKinds.Phone.NUMBER};
18         Cursor cursor = getContentResolver().query(contactUri, projection,
19                 null, null, null);
20         // If the cursor returned is valid, get the phone number
21         if (cursor != null && cursor.moveToFirst()) {
22             int numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER);
23             String number = cursor.getString(numberIndex);
24             // Do something with the phone number
25             ...
26         }
27     }
28 }

查看联系人

要显示一个已有联系人的详细信息,请使用 ACTION_VIEW ,同时在 Intent 的数据部分中用 content: 指定联系人。

获得联系人 URI 的方法主要有两种:

Action
ACTION_VIEW
数据 URI Scheme
content: < URI >
MIME 类型
无。类型可由联系人的 URI 得出。

Intent 示例:

1 public void viewContact(Uri contactUri) {
2     Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
3     if (intent.resolveActivity(getPackageManager()) != null) {
4         startActivity(intent);
5     }
6 }

编辑已有联系人

要编辑已有联系人,请使用 ACTION_EDIT ,在 Intent 的数据部分用 content: 指定 content: URI , 在 Intent 的附件部分用 ContactsContract.Intents.Insert 定义的常量给出已知联系人的信息。

获得联系人 URI 的方式主要有两种:

Action
ACTION_EDIT
数据 URI Scheme
content: < URI >
MIME 类型
从联系人 URI 中得出。
附件
ContactsContract.Intents.Insert 中给出了很多附件常量的定义,可用来声明联系人信息的各个字段。

Intent 示例:

1 public void editContact(Uri contactUri, String email) {
2     Intent intent = new Intent(Intent.ACTION_EDIT);
3     intent.setData(contactUri);
4     intent.putExtra(Intents.Insert.EMAIL, email);
5     if (intent.resolveActivity(getPackageManager()) != null) {
6         startActivity(intent);
7     }
8 }

关于编辑联系人的更多信息,请参阅 通过 Intent 修改通讯录

添加联系人

要添加一个新的联系人,请使用 ACTION_INSERT ,用 Contacts.CONTENT_TYPE 指定 MIME 类型,在附件部分用 ContactsContract.Intents.Insert 中定义的常量指定已知的联系人信息。

Action
ACTION_INSERT
数据 URI Scheme
MIME 类型
Contacts.CONTENT_TYPE
附件
一个或多个由 ContactsContract.Intents.Insert 定义的附件数据。

Intent 示例:

1 public void insertContact(String name, String email) {
2     Intent intent = new Intent(Intent.ACTION_INSERT);
3     intent.setType(Contacts.CONTENT_TYPE);
4     intent.putExtra(Intents.Insert.NAME, name);
5     intent.putExtra(Intents.Insert.EMAIL, email);
6     if (intent.resolveActivity(getPackageManager()) != null) {
7         startActivity(intent);
8     }
9 }

关于添加联系人的更多信息,请参阅 通过 Intent 修改通讯录

Email


撰写可带附件的 Email

要撰写一封 Email,请根据是否包含邮件附件来选用一种下述的 Action , 并且在 Intent 附件中用下述键值给出 Email 的详细信息,比如收件人和主题等。

Action
ACTION_SENDTO (不带邮件附件时)或
ACTION_SEND (带有一个邮件附件时)或
ACTION_SEND_MULTIPLE (带有多个邮件附件时)
数据 URI Scheme
MIME 类型
PLAIN_TEXT_TYPE ("text/plain")
"*/*"
附件
Intent.EXTRA_EMAIL
存放所有“To”收件人 Email 地址的字符串数组。
Intent.EXTRA_CC
存放所有“CC”(译者注:抄送)收件人 Email 地址的字符串数组。
Intent.EXTRA_BCC
存放所有“BCC”(译者注:暗送)收件人 Email 地址的字符串数组。
Intent.EXTRA_SUBJECT
存放 Email 主题的字符串。
Intent.EXTRA_TEXT
存放 Email 文字内容的字符串。
Intent.EXTRA_STREAM
指向邮件附件的 Uri。 如果使用 ACTION_SEND_MULTIPLE (译者注:邮件带有多个附件时),则本部分应该换用 ArrayList ,其中存放了多个 Uri 对象。

Intent 示例:

 1 public void composeEmail(String[] addresses, String subject, Uri attachment) {
 2     Intent intent = new Intent(Intent.ACTION_SEND);
 3     intent.setType("*/*");
 4     intent.putExtra(Intent.EXTRA_EMAIL, addresses);
 5     intent.putExtra(Intent.EXTRA_SUBJECT, subject);
 6     intent.putExtra(Intent.EXTRA_STREAM, attachment);
 7     if (intent.resolveActivity(getPackageManager()) != null) {
 8         startActivity(intent);
 9     }
10 }

如果要确保仅能由 Email 应用来处理 Intent (不允许其他文字信息或社交类应用进行处理), 请使用 ACTION_SENDTO ,并将数据 URI Scheme 给定为 "mailto:"。例如:

1 public void composeEmail(String[] addresses, String subject) {
2     Intent intent = new Intent(Intent.ACTION_SENDTO);
3     intent.setData(Uri.parse("mailto:")); // only email apps should handle this
4     intent.putExtra(Intent.EXTRA_EMAIL, addresses);
5     intent.putExtra(Intent.EXTRA_SUBJECT, subject);
6     if (intent.resolveActivity(getPackageManager()) != null) {
7         startActivity(intent);
8     }
9 }

Intent 过滤器示例:

 1 <activity ...>
 2     <intent-filter>
 3         <action android:name="android.intent.action.GET_CONTENT" />
 4         <data android:type="image/*" />
 5         <category android:name="android.intent.category.DEFAULT" />
 6         <!-- The OPENABLE category declares that the returned file is accessible
 7              from a content provider that supports OpenableColumns
 8              and ContentResolver.openFileDescriptor() -->
 9         <category android:name="android.intent.category.OPENABLE" />
10     </intent-filter>
11 </activity>

 

文件存储


读取指定类型的文件

要让用户选择一个文档或图片文件,并把指向该文件的引用返回给应用程序,请使用 ACTION_GET_CONTENT ,并指定所需的 MIME 类型。 用程序得到的文件引用只是暂时加入 Activity 当前的生命周期中,因此如果以后还要访问该文件,就必须复制一份。 此 Intent 还允许用户在当前进程中新建一个文件(比如,用户可以用摄像头现拍一张照片,而不是选择一张已有的照片文件)。

在返回给 onActivityResult() 方法的结果 Intent 中,数据部分即为指向目标文件的 URI 。 URI 可以为任意类型,比如 http: URI 、file: URI 或 content: URI。 不过,如果要限定可选择的文件类型只能是 Content Provider 提供的(content: URI),或者是由 openFileDescriptor() 给定的文件流,那就应该在 Intent 中增加 CATEGORY_OPENABLE 类型说明。

在 Android 4.3 (API 级别 18)及以上版本中,还可以让用户一次选择多个文件, 只要在 Intent 中增加 EXTRA_ALLOW_MULTIPLE 部分并设为 true 即可。 这样就可以在 getClipData() 返回的 ClipData 中逐个访问所选择的文件了。

Action
ACTION_GET_CONTENT
数据 URI Scheme
MIME 类型
MIME 类型与用户所选文件相对应。
附件
EXTRA_ALLOW_MULTIPLE
布尔值,标明了用户是否可以一次选择多个文件。
EXTRA_LOCAL_ONLY
布尔值,标明返回的文件是否必须在当前设备上直接可访问,而不是还要从远程服务中下载的。
类型(可选)
CATEGORY_OPENABLE
表示仅返回“可打开”的文件,也就是可用 openFileDescriptor() 来表示的文件流。

获取图片文件的 Intent 示例:

 1 static final int REQUEST_IMAGE_GET = 1;
 2 
 3 public void selectImage() {
 4     Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
 5     intent.setType("image/*");
 6     if (intent.resolveActivity(getPackageManager()) != null) {
 7         startActivityForResult(intent, REQUEST_IMAGE_GET);
 8     }
 9 }
10 
11 @Override
12 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
13     if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
14         Bitmap thumbnail = data.getParcelable("data");
15         Uri fullPhotoUri = data.getData();
16         // Do work with photo saved at fullPhotoUri
17         ...
18     }
19 }

返回图片文件的 Intent 过滤器示例:

1 <provider ...
2     android:grantUriPermissions="true"
3     android:exported="true"
4     android:permission="android.permission.MANAGE_DOCUMENTS">
5     <intent-filter>
6         <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
7     </intent-filter>
8 </provider>

 

打开指定类型的文件

在 Android 4.4 以上的版本中,应用程序可以不必把文件取回一份(通过 ACTION_GET_CONTENT ),而是通过 ACTION_OPEN_DOCUMENT 申请打开属于其他应用程序的文件,这里同时要给出 MIME 类型。 同理,用户也可以不用在当前应用中创建文件,而是换用 ACTION_CREATE_DOCUMENT 。例如,可以不必在已有的 PDF 文件中进行选择, ACTION_CREATE_DOCUMENT Intent 可以让用户自行选择在哪个应用中新建文档(在其他有权控制文件存储的应用程序中), 你的应用程序将会接收到 URI 位置,可以将新文档写入这个 URI 。

但是,在由 ACTION_GET_CONTENT 触发并传递给 onActivityResult() 的 Intent 中,可以返回任意类型的 URI , 而由 ACTION_OPEN_DOCUMENTACTION_CREATE_DOCUMENT 触发的结果 Intent 则只能将可选文件设定为 DocumentsProvider 提供的 content: URI 。 可以用 openFileDescriptor() 打开该文件,并用 DocumentsContract.Document 中定义的列名来查询其中的内容。

这里返回的 URI 授予应用程序对文件的长期读取权限(也可能带有写入权限)。 因此,如果需要在某些场合打开并编辑文件时, ACTION_OPEN_DOCUMENT 还是很有用的(取代 ACTION_GET_CONTENT )。

通过在 Intent 中添加 EXTRA_ALLOW_MULTIPLE 字段并设为 true,还可以让用户一次选择多个文件。 如果用户只选择了一个文件,那就可以用 getData() 来读取。如果用户选择了两个以上的文件,则 getData() 将会返回 null ,这时必须从 ClipData 对象读取每项信息,它由 getClipData() 返回。

注意: Intent 必须指定 MIME 类型,并且必须给出 CATEGORY_OPENABLE 声明。根据需要,还可以给出多个 MIME 类型,这通过在附件数据 EXTRA_MIME_TYPES 中添加 MIME 类型的数组即可。 如果定义了多个 MIME 类型,那么就必须把主 MIME 类型用 setType() 设为 “*/*”。

Action
ACTION_OPEN_DOCUMENT
ACTION_CREATE_DOCUMENT
数据 URI Scheme
MIME 类型
MIME 类型与用户选择的文件类型相对应。
附件
EXTRA_MIME_TYPES
MIME 类型的数组,对应于应用程序需要的文件类型。 如果使用了该附件数据,就必须把主 MIME 类型用 setType() 设为 “*/*”。
EXTRA_ALLOW_MULTIPLE
布尔值,标明用户是否可以一次选取多个文件。
EXTRA_TITLE
使用 ACTION_CREATE_DOCUMENT 时用来指定初始文件名称。
EXTRA_LOCAL_ONLY
布尔值,标明返回的文件是否可从设备直接访问,而不需要从远程服务中下载。
类型
CATEGORY_OPENABLE
表示仅返回“可打开”的文件,也就是可用 openFileDescriptor() 来表示的文件流。

读取图片文件的 Intent 示例:

 1 static final int REQUEST_IMAGE_OPEN = 1;
 2 
 3 public void selectImage() {
 4     Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
 5     intent.setType("image/*");
 6     intent.addCategory(Intent.CATEGORY_OPENABLE);
 7     // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
 8     startActivityForResult(intent, REQUEST_IMAGE_OPEN);
 9 }
10 
11 @Override
12 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
13     if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) {
14         Uri fullPhotoUri = data.getData();
15         // Do work with full size photo saved at fullPhotoUri
16         ...
17     }
18 }

其实,第三方应用无法真正响应 Action 为 ACTION_OPEN_DOCUMENT 的 Intent 。 而是由系统接收此类 Intent ,并在统一的用户界面中显示来自各个应用的所有可用文件。

为了能在这个系统界面中显示出文件,并允许其他应用程序打开这些文件,应用程序必须实现一个 DocumentsProvider 对象,其中包含了 PROVIDER_INTERFACE Intent 过滤器("android.content.action.DOCUMENTS_PROVIDER")。 例如:

1 <provider ...
2     android:grantUriPermissions="true"
3     android:exported="true"
4     android:permission="android.permission.MANAGE_DOCUMENTS">
5     <intent-filter>
6         <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
7     </intent-filter>
8 </provider>

 

关于如何让自己的文件可以被其他应用程序打开的更多信息,请参阅 存储访问架构指南。

地图


在地图上显示地理位置

要打开地图,请使用 ACTION_VIEW 并在 Intent 数据部分给出位置信息,数据的 Scheme 在下述内容中选取一个。

Action
ACTION_VIEW
数据 URI Scheme
geo:latitude,longitude
显示指定经纬度位置的地图。

例如"geo:47.6,-122.3"

geo:latitude,longitude?z=zoom
以某个缩放级别显示给定经纬度位置的地图。 放大级别为 1 表示整个地球,以给定的 latlng 为中心。 最高(最大)的放大级别为 23 。

例如:“geo:47.6,-122.3?z=11

geo:0,0?q=lat,lng(label)
显示指定经纬度位置的地图,并带有一个字符串标签。

例如:"geo:0,0?q=34.99,-106.61(Treasure)"

geo:0,0?q=my+street+address
显示由“my street address”查询出来的位置(地址或位置查询)。

例如:"geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA"

注意: geo URI 中的所有字符串必须经过转码。 例如,字符串 1st & Pike, Seattle 应该写为 1st%20%26%20Pike%2C%20Seattle。 字符串中的空格可以用 %20 转码,也可以用加号代替(+)。

MIME 类型

Intent 示例:

1 public void showMap(Uri geoLocation) {
2     Intent intent = new Intent(Intent.ACTION_VIEW);
3     intent.setData(geoLocation);
4     if (intent.resolveActivity(getPackageManager()) != null) {
5         startActivity(intent);
6     }
7 }

Intent 过滤器示例:

1 <activity ...>
2     <intent-filter>
3         <action android:name="android.intent.action.VIEW" />
4         <data android:scheme="geo" />
5         <category android:name="android.intent.category.DEFAULT" />
6     </intent-filter>
7 </activity>

 

音乐和视频


播放媒体文件

要播放音频文件,请使用 ACTION_VIEW 并在 Intent 数据部分指定文件的 URI 位置。

Action
ACTION_VIEW
数据 URI Scheme
file: < URI >
content: < URI >
http: < URL >
MIME 类型
"audio/*"
"application/ogg"
"application/x-ogg"
"application/itunes"
或其他应用程序需要用到的类型。

Intent 示例:

1 public void playMedia(Uri file) {
2     Intent intent = new Intent(Intent.ACTION_VIEW);
3     intent.setData(file);
4     if (intent.resolveActivity(getPackageManager()) != null) {
5         startActivity(intent);
6     }
7 }

Intent 过滤器示例:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:type="audio/*" />
        <data android:type="application/ogg" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

 

根据搜索请求播放音频

要根据搜索请求播放音频,请使用 INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH Intent。 在响应用户的语音命令来播放音乐时,应用程序就可以触发该类 Intent。 接收本 Intent 的应用程序会在其音乐库中进行检索,如果找到匹配的内容就会开始播放。

本类 Intent 应该包含字符串型的附件 EXTRA_MEDIA_FOCUS ,用于指定检索模式。 例如,可以指定检索艺术家名字还是歌名。

Action
INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
数据 URI Scheme
MIME 类型
附件
MediaStore.EXTRA_MEDIA_FOCUS (必填项)

指明检索模式(用户是否要查找特定的艺术家、专辑、播放列表或广播频道)。 大部分检索模式都需要给出额外的附件数据。 例如:如果用户对某首歌感兴趣, Intent 就可能包含三部分额外附件数据:歌名、艺术家和专辑名。 利用 EXTRA_MEDIA_FOCUS 键值,本 Intent 可提供以下检索模式:

任意"vnd.android.cursor.item/*"

播放任何音乐。 接收方应用将会智能选择要播放的音乐,比如用户最后一次听过的播放列表。

额外附件数据:

  • QUERY (必填项)— 空字符串。 为了保持向后兼容性,必须给出本附件数据:那些不了解本检索模式的已有应用程序可以将本类 Intent 当作非结构化检索来处理。
非结构化"vnd.android.cursor.item/*"

根据一个非结构化的检索请求播放特定的歌曲、专辑或某风格的音乐。 如果应用程序无法辨识用户需要的音乐类型,那就可以用这种搜索模式创建 Intent 。 当然,应用程序还是应该尽可能地使用更为确切的检索模式。

额外附件数据:

  • QUERY (必填项)— 包含艺术家、专辑、歌曲名称、风格或者这些条件的任意组合的字符串。
风格 - Audio.Genres.ENTRY_CONTENT_TYPE

播放指定风格的音乐。

额外附件数据:

  • "android.intent.extra.genre" (必填项)— 风格。
  • QUERY (必填项)— 风格。 为了保持向后兼容性,必须给出本附件数据:那些不了解本检索模式的已有应用程序可以将本类 Intent 当作非结构化检索来处理。
艺术家Audio.Artists.ENTRY_CONTENT_TYPE

播放指定艺术家的音乐。

额外附件数据:

  • EXTRA_MEDIA_ARTIST (必填项)— 艺术家。
  • "android.intent.extra.genre" — 艺术家。
  • QUERY (必填项)— 包含艺术家、风格或两者任意组合的字符串。 为了保持向后兼容性,必须给出本附件数据:那些不了解本检索模式的已有应用程序可以将本类 Intent 当作非结构化检索来处理。
专辑 - Audio.Albums.ENTRY_CONTENT_TYPE

播放指定专辑。

额外附件数据:

  • EXTRA_MEDIA_ALBUM (必填项) — 专辑。
  • EXTRA_MEDIA_ARTIST — 艺术家。
  • "android.intent.extra.genre" — 专辑。
  • QUERY (必填项) — 包含专辑、艺术家或两者任意组合的字符串。 为了保持向后兼容性,必须给出本附件数据:那些不了解本检索模式的已有应用程序可以将本类 Intent 当作非结构化检索来处理。
歌曲名称"vnd.android.cursor.item/audio"

播放指定歌曲。

额外附件数据:

  • EXTRA_MEDIA_ALBUM — 专辑。
  • EXTRA_MEDIA_ARTIST — 艺术家。
  • "android.intent.extra.genre" — 风格。
  • EXTRA_MEDIA_TITLE (必填项) — 歌曲名称。
  • QUERY (必填项) — 包含专辑、艺术家、风格、歌曲名称或这些条件任意组合的字符串。 为了保持向后兼容性,必须给出本附件数据:那些不了解本检索模式的已有应用程序可以将本类 Intent 当作非结构化检索来处理。
广播频道"vnd.android.cursor.item/radio"

播放指定频道广播或者匹配附件数据给定规则的频道。

额外附件数据:

  • EXTRA_MEDIA_ALBUM — 专辑。
  • EXTRA_MEDIA_ARTIST — 艺术家。
  • "android.intent.extra.genre" — 风格。
  • "android.intent.extra.radio_channel" — 广播频道。
  • EXTRA_MEDIA_TITLE — 供广播频道参考的歌曲名称。
  • QUERY (必填项) — 包含专辑、艺术家、风格、广播频道、歌曲名称或这些条件任意组合的字符串。 为了保持向后兼容性,必须给出本附件数据:那些不了解本检索模式的已有应用程序可以将本类 Intent 当作非结构化检索来处理。
播放列表Audio.Playlists.ENTRY_CONTENT_TYPE

播放指定列表或匹配附件数据给定规则的列表。

额外附件数据:

  • EXTRA_MEDIA_ALBUM — 专辑。
  • EXTRA_MEDIA_ARTIST — 艺术家。
  • "android.intent.extra.genre" — 风格。
  • "android.intent.extra.playlist" — 播放列表。
  • EXTRA_MEDIA_TITLE — 供播放列表参考的歌曲名称。
  • QUERY (必填项) — 包含专辑、艺术家、风格、播放列表、歌曲名称或这些条件任意组合的字符串。 为了保持向后兼容性,必须给出本附件数据:那些不了解本检索模式的已有应用程序可以将本类 Intent 当作非结构化检索来处理。

Intent 示例:

如果用户需要收听正在播放指定艺术家歌曲的广播电台,检索应用程序就可以创建以下 Intent:

 1 public void playSearchRadioByArtist(String artist) {
 2     Intent intent = new Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH);
 3     intent.putExtra(MediaStore.EXTRA_MEDIA_FOCUS,
 4                     "vnd.android.cursor.item/radio");
 5     intent.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist);
 6     intent.putExtra(SearchManager.QUERY, artist);
 7     if (intent.resolveActivity(getPackageManager()) != null) {
 8         startActivity(intent);
 9     }
10 }

Intent 过滤器示例:

1 <activity ...>
2     <intent-filter>
3         <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
4         <category android:name="android.intent.category.DEFAULT" />
5     </intent-filter>
6 </activity>

 

在处理该 Intent 时,为了确定检索模式, Activity 应该检查传入的 Intent 的附件值 EXTRA_MEDIA_FOCUS 。一旦 Activity 识别出了检索模式,就应该读取该模式下的额外附件数据。 利用这些信息,应用程序就可以在自己的曲库中查找并播放符合要求的音乐。 例如:

 1 protected void onCreate(Bundle savedInstanceState) { 
 2     ... 
 3     Intent intent = this.getIntent(); 
 4     if (intent.getAction().compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) { 
 5         String mediaFocus = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS); 
 6         String query = intent.getStringExtra(SearchManager.QUERY); 
 7         // 根据检索模式的不同,有些附件数据可能不可用 
 8         String album = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM); 
 9         String artist = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST); 
10         String genre = intent.getStringExtra("android.intent.extra.genre"); 
11         String playlist = intent.getStringExtra("android.intent.extra.playlist"); 
12         String rchannel = intent.getStringExtra("android.intent.extra.radio_channel"); 
13         String title = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE); 
14         // 检测搜索模式并采用相应的附件数据 
15         if (mediaFocus == null) { 
16             // “非结构化” 检索模式(向后兼容) 
17             playUnstructuredSearch(query); 
18         } else if (mediaFocus.compareTo("vnd.android.cursor.item/*") == 0) { 
19             if (query.isEmpty()) { 
20                 // “任意”检索模式 
21                 playResumeLastPlaylist(); 
22             } else { 
23                 // “非结构化” 检索模式 
24                 playUnstructuredSearch(query); 
25             } 
26         } else if (mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0) { 
27             //“风格” 检索模式 
28             playGenre(genre); 
29         } else if (mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0) { 
30             // “艺术家” 检索模式 
31             playArtist(artist, genre); 
32         } else if (mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0) { 
33             // “专辑” 检索模式 
34             playAlbum(album, artist); 
35         } else if (mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0) { 
36             // “歌曲名称” 检索模式 
37             playSong(album, artist, genre, title); 
38         } else if (mediaFocus.compareTo("vnd.android.cursor.item/radio") == 0) { 
39             // “广播频道” 检索模式
40             playRadioChannel(album, artist, genre, rchannel, title); 
41         } else if (mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0) { 
42             // “播放列表” 检索模式 
43             playPlaylist(album, artist, genre, playlist, title); 
44         } 
45     } 
46 }

电话


拨打电话

要打开电话应用并拨打一个电话号码,请使用 ACTION_DIAL 并用下述的 URI Scheme 给出电话号码。 电话应用在打开时会显示这个号码,但用户必须按下Call按钮(译者注:大部分手机的“拨打”键都是个话机图标)才会开始拨打电话。

Action
ACTION_DIAL
数据 URI Scheme
tel: < phone-number >
MIME 类型

合法的电话号码由 the IETF RFC 3966 标准定义。 示例如下:

  • tel:2125551212
  • tel:(212) 555 1212

拨号应用对于电话号码的格式识别已经很完美了。 因此在 Uri.parse() 方法中并未用到很严格的 Scheme 定义。 不过,如果某个 Scheme 没有用过或者不确定是否能被处理,则可以换用 Uri.fromParts()

Intent 示例:

1 public void dialPhoneNumber(String phoneNumber) {
2     Intent intent = new Intent(Intent.ACTION_DIAL);
3     intent.setData(Uri.parse("tel:" + phoneNumber));
4     if (intent.resolveActivity(getPackageManager()) != null) {
5         startActivity(intent);
6     }
7 }

设置


打开系统设置中的某个项目

如果要让用户修改某些设置,就要打开系统设置中的对应窗口, 请使用以下 Action 的 Intent 来完成, Action 的名称与各项设置的窗口相对应。

Action
ACTION_SETTINGS
ACTION_WIRELESS_SETTINGS
ACTION_AIRPLANE_MODE_SETTINGS
ACTION_WIFI_SETTINGS
ACTION_APN_SETTINGS
ACTION_BLUETOOTH_SETTINGS
ACTION_DATE_SETTINGS
ACTION_LOCALE_SETTINGS
ACTION_INPUT_METHOD_SETTINGS
ACTION_DISPLAY_SETTINGS
ACTION_SECURITY_SETTINGS
ACTION_LOCATION_SOURCE_SETTINGS
ACTION_INTERNAL_STORAGE_SETTINGS
ACTION_MEMORY_CARD_SETTINGS

关于其他设置窗口对应的 Action,请参阅 设置 文档。

数据 URI Scheme
MIME 类型

Intent 示例:

1 public void openWifiSettings() {
2     Intent intent = new Intent(Intent.ACTION_WIFI_SETTINGS);
3     if (intent.resolveActivity(getPackageManager()) != null) {
4         startActivity(intent);
5     }
6 }

文字短消息


撰写带有附件的 SMS/MMS 消息

要新建一条 SMS 或 MMS 消息,请使用以下 Action 的 Intent , 并利用下述的附件键值给出短消息的细节,比如电话号码、主题、消息内容等。

Action
ACTION_SENDTO
ACTION_SEND
ACTION_SEND_MULTIPLE
数据 URI Scheme
sms: < phone_number >
smsto: < phone_number >
mms: < phone_number >
mmsto: < phone_number >

这些 Scheme 是同时处理的。

MIME 类型
PLAIN_TEXT_TYPE"text/plain"
"image/*"
"video/*"
附件
"subject"
用作短信主题的字符串(通常仅用于 MMS)。
"sms_body"
用作短信内容的字符串。
EXTRA_STREAM
指向图片或视频附件的 Uri。 如果使用 ACTION_SEND_MULTIPLE ,则本 Intent 附件应该是一个由指向图片、视频的 Uri 组成的 ArrayList

Intent 示例:

1 public void composeMmsMessage(String message, Uri attachment) {
2     Intent intent = new Intent(Intent.ACTION_SEND);
3     intent.setType(HTTP.PLAIN_TEXT_TYPE);
4     intent.putExtra("sms_body", message);
5     intent.putExtra(Intent.EXTRA_STREAM, attachment);
6     if (intent.resolveActivity(getPackageManager()) != null) {
7         startActivity(intent);
8     }
9 }

如果要确保 Intent 只允许由短信应用(而不是其他 Email 或社交类应用)进行处理,请使用 ACTION_SENDTO 并将数据 Scheme 给定为 “smsto:” 。例如:

1 public void composeMmsMessage(String message, Uri attachment) {
2     Intent intent = new Intent(Intent.ACTION_SEND);
3     intent.setData(Uri.parse("smsto:"));  // This ensures only SMS apps respond
4     intent.putExtra("sms_body", message);
5     intent.putExtra(Intent.EXTRA_STREAM, attachment);
6     if (intent.resolveActivity(getPackageManager()) != null) {
7         startActivity(intent);
8     }
9 }

Intent 过滤器示例:

1 <activity ...>
2     <intent-filter>
3         <action android:name="android.intent.action.SEND" />
4         <data android:type="text/plain" />
5         <data android:type="image/*" />
6         <category android:name="android.intent.category.DEFAULT" />
7     </intent-filter>
8 </activity>

 

注意: 如果要开发一款 SMS/MMS 消息应用程序,为了在 Android 4.4 以上版本中能够被用作默认 SMS 应用, 必须为很多额外的 Action 实现 Intent 过滤器。 详情请参阅文档 Telephony

Web 浏览器


载入 Web URL

要打开一个网页,请使用 ACTION_VIEW 并在 Intent 数据部分指定 Web URL。

Action
ACTION_VIEW
数据 URI Scheme
http: < URL >
https: < URL >
MIME 类型
PLAIN_TEXT_TYPE (“text/plain”)
"text/html"
"application/xhtml+xml"
"application/vnd.wap.xhtml+xml"

Intent 示例:

1 public void openWebPage(String url) {
2     Uri webpage = Uri.parse(url);
3     Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
4     if (intent.resolveActivity(getPackageManager()) != null) {
5         startActivity(intent);
6     }
7 }

Intent 过滤器示例:

 1 <activity ...>
 2     <intent-filter>
 3         <action android:name="android.intent.action.VIEW" />
 4         <!-- Include the host attribute if you want your app to respond
 5              only to URLs with your app's domain. -->
 6         <data android:scheme="http" android:host="www.example.com" />
 7         <category android:name="android.intent.category.DEFAULT" />
 8         <!-- The BROWSABLE category is required to get links from web pages. -->
 9         <category android:name="android.intent.category.BROWSABLE" />
10     </intent-filter>
11 </activity>

 

提示: 如果你的 Android 应用的功能与你的 Web 网站类似,请为指向你的网站的 URL 声明一条 Intent 过滤器。 这样,如果用户已经安装了你的应用,则在邮件或其他网页中点击你的网站链接,就会直接打开你的 Android 应用,而不是你的网站。

执行 Web 搜索

要启动一次 Web 搜索,请使用 ACTION_WEB_SEARCH 并在附件 SearchManager.QUERY 中指定搜索字符串。

Action
ACTION_WEB_SEARCH
数据 URI Scheme
MIME 类型
附件
SearchManager.QUERY
搜索字符串

Intent 示例:

1 public void searchWeb(String query) {
2     Intent intent = new Intent(Intent.ACTION_SEARCH);
3     intent.putExtra(SearchManager.QUERY, query);
4     if (intent.resolveActivity(getPackageManager()) != null) {
5         startActivity(intent);
6     }
7 }

 

posted on 2014-07-18 12:52  呆呆大虾  阅读(1337)  评论(0编辑  收藏  举报

导航