轉載自: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 過濾器。
鬧鐘
1、創建鬧鐘
要新建一個鬧鐘,請使用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 示例:
public void createAlarm(String message, int hour, int minutes) {
Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
.putExtra(AlarmClock.EXTRA_MESSAGE, message)
.putExtra(AlarmClock.EXTRA_HOUR, hour)
.putExtra(AlarmClock.EXTRA_MINUTES, minutes);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
注意:
爲了調用 ACTION_SET_ALARM Intent,應用程序必須擁有 SET_ALARM 權限:
< uses-permission android:name="com.android.alarm.permission.SET_ALARM" / >
Intent 過濾器示例:
< activity ... >
< intent-filter >
< action android:name="android.intent.action.SET_ALARM" / >
< category android:name="android.intent.category.DEFAULT" / >
< /intent-filter >
< /activity >
2、創建計時器
要創建一個倒計時的計時器,請使用 ACTION_SET_TIMER 並在附件中設定計時器的詳細參數,比如時長,如下所示。
注意:本 Intent 自 Android 4.4 (API 級別 19)開始引入。
Action
ACTION_SET_TIMER
數據 URI
無
MIME 類型
無
附件
EXTRA_LENGTH
計時器的時長,單位爲秒。
EXTRA_MESSAGE
用於標識該計時器的自定義文字信息。
EXTRA_SKIP_UI
布爾值,指明應用程序在設定計時器時是否要跳過用戶交互過程。 如果設爲 True ,則應用程序將會跳過所有的確認界面,直接設定所需的計時器。
Intent 示例:
public void startTimer(String message, int seconds) {
Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER)
.putExtra(AlarmClock.EXTRA_MESSAGE, message)
.putExtra(AlarmClock.EXTRA_LENGTH, seconds)
.putExtra(AlarmClock.EXTRA_SKIP_UI, true);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
注意:
爲了調用 ACTION_SET_TIMER Intent ,應用程序必須擁有 SET_ALARM 權限:
< uses-permission android:name="com.android.alarm.permission.SET_ALARM" / >
Intent 過濾器示例:
<activity ...>
<intent-filter>
<action android:name="android.intent.action.SET_TIMER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
3、列出所有鬧鐘
要顯示所有鬧鐘的列表,請使用 ACTION_SHOW_ALARMS
雖然用到本 Intent 的應用程序應該不會很多(主要用於系統應用), 所有當作鬧鐘使用的應用程序都必須實現本 Intent 過濾器,以便能列出當前所有的鬧鐘。
注意: 本 Intent 自 Android 4.4 (API 級別 19)開始引入。
Action
ACTION_SHOW_ALARMS
數據 URI
無
MIME 類型
無
Intent 過濾器示例:
< activity ... >
< intent-filter >
< action android:name="android.intent.action.SHOW_ALARMS" / >
< category android:name="android.intent.category.DEFAULT" / >
< /intent-filter >
< /activity >
5、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 示例:
public void addEvent(String title, String location, Calendar begin, Calendar end) {
Intent intent = new Intent(Intent.ACTION_INSERT)
.setData(Events.CONTENT_URI)
.putExtra(Events.TITLE, title)
.putExtra(Events.EVENT_LOCATION, location)
.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
Intent 過濾器示例:
< activity ... >
< intent-filter >
< action android:name="android.intent.action.INSERT" / >
< data android:mimeType="vnd.android.cursor.dir/event" / >
< category android:name="android.intent.category.DEFAULT" / >
< /intent-filter >
< /activity >
6、攝像頭
拍照或攝像並返回結果
爲了啓動攝像頭應用並接收返回的照片或視頻,請使用 ACTION_IMAGE_CAPTURE 或 ACTION_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 示例:
static final int REQUEST_IMAGE_CAPTURE = 1;
static final Uri mLocationForPhotos;
public void capturePhoto(String targetFilename) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.withAppendedPath(mLocationForPhotos, targetFilename);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bitmap thumbnail = data.getParcelable("data");
// 用 mLocationForPhotos 中的全尺寸圖片文件進行其他操作
...
}
}
關於如何通過 Intent 拍照的更多信息,包括如何爲保存文件創建合適的 Uri, 請參閱 拍照初步 和 攝像初步。
Intent 過濾器:
< activity ... >
< intent-filter >
< action android:name="android.media.action.IMAGE_CAPTURE" / >
< category android:name="android.intent.category.DEFAULT" / >
< /intent-filter >
< /activity >
在處理該 Intent 時, Activity 應該檢查傳入 Intent 的附件數據 EXTRA_OUTPUT ,然後把捕獲到的圖像或視頻保存到該其指定的位置,並用包含了縮略圖的 Intent 調用 setResult() ,縮略圖數據應存放在 Intent 附件的“data”部分。
7、通訊錄/聯繫人應用
(1)選擇聯繫人
要讓用戶選擇聯繫人並訪問其所有數據,請使用 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 示例:
static final int REQUEST_SELECT_CONTACT = 1;
public void selectContact() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_SELECT_CONTACT);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
Uri contactUri = data.getData();
// 利用 contactUri 執行某些操作
...
}
}
有了聯繫人的 URI 之後,如何讀取聯繫人詳細數據的詳細內容,請參閱 讀取聯繫人詳細數據。 請記住,用上述 Intent 訪問聯繫人 URI 時,讀取詳細信息是不需要 READ_CONTACTS 權限的。
(2)選擇聯繫人的指定信息
爲了能讓用戶選擇聯繫人的部分信息,比如電話、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 示例:
static final int REQUEST_SELECT_PHONE_NUMBER = 1;
public void selectContact() {
// 打開 Activity 讓用戶從通訊錄中選取一個電話號碼
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(CommonDataKinds.Phone.CONTENT_TYPE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == RESULT_OK) {
// 獲取 URI 並在 Content Provider 中查詢電話號碼
Uri contactUri = data.getData();
String[] projection = new String[]{CommonDataKinds.Phone.NUMBER};
Cursor cursor = getContentResolver().query(contactUri, projection,
null, null, null);
// 如果返回的遊標有效,則讀取電話號碼
if (cursor != null && cursor.moveToFirst()) {
int numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER);
String number = cursor.getString(numberIndex);
// 利用電話號碼執行某些操作
...
}
}
}
(3)查看聯繫人
要顯示一個已有聯繫人的詳細信息,請使用 ACTION_VIEW ,同時在 Intent 的數據部分中用 content: 指定聯繫人。
獲得聯繫人 URI 的方法主要有兩種:
使用上一節提到的由 ACTION_PICK 返回的 URI (這時不需要任何權限)。
直接訪問包含所有聯繫人的列表,這將在 獲取全部聯繫人的列表 中介紹(這時需要 READ_CONTACTS 權限)。
Action
ACTION_VIEW
數據 URI Scheme
content: < URI >
MIME 類型
無。類型可由聯繫人的 URI 得出。
Intent 示例:
public void viewContact(Uri contactUri) {
Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
(4)編輯已有聯繫人
要編輯已有聯繫人,請使用 ACTION_EDIT ,在 Intent 的數據部分用 content: 指定 content: URI , 在 Intent 的附件部分用 ContactsContract.Intents.Insert 定義的常量給出已知聯繫人的信息。
獲得聯繫人 URI 的方式主要有兩種:
使用上一節提到的由 ACTION_PICK 返回的 URI (這時不需要任何權限)。
直接訪問包含所有聯繫人的列表,這將在 獲取全部聯繫人的列表 中介紹(這時需要 READ_CONTACTS 權限)。
Action
ACTION_EDIT
數據 URI Scheme
content: < URI >
MIME 類型
從聯繫人 URI 中得出。
附件
在 ContactsContract.Intents.Insert 中給出了很多附件常量的定義,可用來聲明聯繫人信息的各個字段。
Intent 示例:
public void editContact(Uri contactUri, String email) {
Intent intent = new Intent(Intent.ACTION_EDIT);
intent.setData(contactUri);
intent.putExtra(Intents.Insert.EMAIL, email);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
關於編輯聯繫人的更多信息,請參閱 利用 Intent 修改通訊錄。
(5)添加聯繫人
要添加一個新的聯繫人,請使用 ACTION_INSERT ,用 Contacts.CONTENT_TYPE 指定 MIME 類型,在附件部分用 ContactsContract.Intents.Insert 中定義的常量指定已知的聯繫人信息。
Action
ACTION_INSERT
數據 URI Scheme
無
MIME 類型
Contacts.CONTENT_TYPE
附件
一個或多個由 ContactsContract.Intents.Insert 定義的附件數據。
Intent 示例:
public void insertContact(String name, String email) {
Intent intent = new Intent(Intent.ACTION_INSERT);
intent.setType(Contacts.CONTENT_TYPE);
intent.putExtra(Intents.Insert.NAME, name);
intent.putExtra(Intents.Insert.EMAIL, email);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
關於添加聯繫人的更多信息,請參閱 利用 Intent 修改通訊錄。
(6)Email
撰寫可帶附件的 Email
要撰寫一封 Email,請根據是否包含郵件附件來選用一種下述的 Action , 並且在 Intent 附件中用下述鍵值給出 Email 的詳細信息,比如收件人和主題等。
Action
ACTION_SENDTO (不帶郵件附件時)或
ACTION_SEND (帶有一個郵件附件時)或
ACTION_SEND_MULTIPLE (帶有多個郵件附件時)
數據 URI Scheme
無
MIME 類型
PLAIN_TEXT_TYPE (“text/plain”)
intent.putExtra(Intent.EXTRA_EMAIL, addresses);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_STREAM, attachment);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
如果要確保僅能由 Email 應用來處理 Intent (不允許其他文字信息或社交類應用進行處理), 請使用 ACTION_SENDTO ,並將數據 URI Scheme 給定爲 “mailto:”。例如:
public void composeEmail(String[] addresses, String subject) {
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:")); // 只允許 Email 應用來處理
intent.putExtra(Intent.EXTRA_EMAIL, addresses);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
Intent 過濾器示例:
< activity ... >
< intent-filter >
< action android:name="android.intent.action.SEND" / >
< data android:type="**”。
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 示例:
static final int REQUEST_IMAGE_OPEN = 1;
public void selectImage() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("image/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
// 只有系統能收到 ACTION_OPEN_DOCUMENT,因此不必檢測。
startActivityForResult(intent, REQUEST_IMAGE_OPEN);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) {
Uri fullPhotoUri = data.getData();
// 用 fullPhotoUri 中的全尺寸圖片文件執行某些操作
...
}
}
其實,第三方應用無法真正響應 Action 爲 ACTION_OPEN_DOCUMENT 的 Intent 。 而是由系統接收此類 Intent ,並在統一的用戶界面中顯示來自各個應用的所有可用文件。
爲了能在這個系統界面中顯示出文件,並允許其他應用程序打開這些文件,應用程序必須實現一個 DocumentsProvider 對象,其中包含了 PROVIDER_INTERFACE Intent 過濾器(”android.content.action.DOCUMENTS_PROVIDER”)。 例如:
< provider ...
android:grantUriPermissions="true"
android:exported="true"
android:permission="android.permission.MANAGE_DOCUMENTS" >
< intent-filter >
< action android:name="android.content.action.DOCUMENTS_PROVIDER" / >
< /intent-filter >
< /provider >
關於如何讓自己的文件可以被其他應用程序打開的更多信息,請參閱 存儲訪問架構指南。
8、地圖
在地圖上顯示地理位置
要打開地圖,請使用 ACTION_VIEW 並在 Intent 數據部分給出位置信息,數據的 Scheme 在下述內容中選取一個。
Action
ACTION_VIEW
數據 URI Scheme
geo:latitude,longitude
顯示指定經緯度位置的地圖。
例如”geo:47.6,-122.3”
geo:latitude,longitude?z=zoom
以某個縮放級別顯示給定經緯度位置的地圖。 放大級別爲 1 表示整個地球,以給定的 lat、lng 爲中心。 最高(最大)的放大級別爲 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,+CA”
注意: geo URI 中的所有字符串必須經過轉碼。 例如,字符串 1st & Pike, Seattle 應該寫爲 1st & Pike, Seattle。 字符串中的空格可以用 轉碼,也可以用加號代替(+)。
MIME 類型
無
Intent 示例:
public void showMap(Uri geoLocation) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(geoLocation);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
Intent 過濾器示例:
< activity ... >
< intent-filter >
< action android:name="android.intent.action.VIEW" / >
< data android:scheme="geo" / >
< category android:name="android.intent.category.DEFAULT" / >
< /intent-filter >
< /activity >
9、音樂和視頻
(1)媒體文件
要播放音頻文件,請使用 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 示例:
public void playMedia(Uri file) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(file);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
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 >
(2)根據搜索請求播放音頻
要根據搜索請求播放音頻,請使用 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:
public void playSearchRadioByArtist(String artist) {
Intent intent = new Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH);
intent.putExtra(MediaStore.EXTRA_MEDIA_FOCUS,
"vnd.android.cursor.item/radio");
intent.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist);
intent.putExtra(SearchManager.QUERY, artist);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
Intent 過濾器示例:
< activity ... >
< intent-filter >
< action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" / >
< category android:name="android.intent.category.DEFAULT" / >
< /intent-filter >
< /activity >
在處理該 Intent 時,爲了確定檢索模式, Activity 應該檢查傳入的 Intent 的附件值 EXTRA_MEDIA_FOCUS 。一旦 Activity 識別出了檢索模式,就應該讀取該模式下的額外附件數據。 利用這些信息,應用程序就可以在自己的曲庫中查找並播放符合要求的音樂。 例如:
protected void onCreate(Bundle savedInstanceState) {
...
Intent intent = this.getIntent();
if (intent.getAction().compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) {
String mediaFocus = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS);
String query = intent.getStringExtra(SearchManager.QUERY);
// 根據檢索模式的不同,有些附件數據可能不可用
String album = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM);
String artist = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST);
String genre = intent.getStringExtra("android.intent.extra.genre");
String playlist = intent.getStringExtra("android.intent.extra.playlist");
String rchannel = intent.getStringExtra("android.intent.extra.radio_channel");
String title = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE);
// 檢測搜索模式並採用相應的附件數據
if (mediaFocus == null) {
// “非結構化” 檢索模式(向後兼容)
playUnstructuredSearch(query);
} else if (mediaFocus.compareTo("vnd.android.cursor.item/*") == 0) {
if (query.isEmpty()) {
// “任意”檢索模式
playResumeLastPlaylist();
} else {
// “非結構化” 檢索模式
playUnstructuredSearch(query);
}
} else if (mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0) {
//“風格” 檢索模式
playGenre(genre);
} else if (mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0) {
// “藝術家” 檢索模式
playArtist(artist, genre);
} else if (mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0) {
// “專輯” 檢索模式
playAlbum(album, artist);
} else if (mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0) {
// “歌曲名稱” 檢索模式
playSong(album, artist, genre, title);
} else if (mediaFocus.compareTo("vnd.android.cursor.item/radio") == 0) {
// “廣播頻道” 檢索模式
playRadioChannel(album, artist, genre, rchannel, title);
} else if (mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0) {
// “播放列表” 檢索模式
playPlaylist(album, artist, genre, playlist, title);
}
}
}
10、電話
(1)撥打電話
要打開電話應用並撥打一個電話號碼,請使用 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 示例:
public void dialPhoneNumber(String phoneNumber) {
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + phoneNumber));
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
11、設置
打開系統設置中的某個項目
如果要讓用戶修改某些設置,就要打開系統設置中的對應窗口, 請使用以下 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 示例:
public void openWifiSettings() {
Intent intent = new Intent(Intent.ACTION_WIFI_SETTINGS);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
12、文字短消息
撰寫帶有附件的 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 示例:
public void composeMmsMessage(String message, Uri attachment) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType(HTTP.PLAIN_TEXT_TYPE);
intent.putExtra("sms_body", message);
intent.putExtra(Intent.EXTRA_STREAM, attachment);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
如果要確保 Intent 只允許由短信應用(而不是其他 Email 或社交類應用)進行處理,請使用 ACTION_SENDTO 並將數據 Scheme 給定爲 “smsto:” 。例如:
public void composeMmsMessage(String message, Uri attachment) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setData(Uri.parse("smsto:")); // 這就確保只有 SMS 應用才能響應
intent.putExtra("sms_body", message);
intent.putExtra(Intent.EXTRA_STREAM, attachment);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
Intent 過濾器示例:
< activity ... >
< intent-filter >
< action android:name="android.intent.action.SEND" / >
< data android:type="text/plain" / >
< data android:type="image/*" / >
< category android:name="android.intent.category.DEFAULT" / >
< /intent-filter >
< /activity >
注意: 如果要開發一款 SMS/MMS 消息應用程序,爲了在 Android 4.4 以上版本中能夠被用作默認 SMS 應用, 必須爲很多額外的 Action 實現 Intent 過濾器。 詳情請參閱文檔 Telephony 。
13、Web 瀏覽器
(1)載入 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 示例:
public void openWebPage(String url) {
Uri webpage = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
Intent 過濾器示例:
< activity ... >
< intent-filter >
< action android:name="android.intent.action.VIEW" / >
< !-- Include the host attribute if you want your app to respond
only to URLs with your app's domain. -- >
< data android:scheme="http" android:host="www.example.com" / >
< category android:name="android.intent.category.DEFAULT" / >
< !-- The BROWSABLE category is required to get links from web pages. -- >
< category android:name="android.intent.category.BROWSABLE" / >
< /intent-filter >
< /activity >
提示: 如果你的 Android 應用的功能與你的 Web 網站類似,請爲指向你的網站的 URL 聲明一條 Intent 過濾器。 這樣,如果用戶已經安裝了你的應用,則在郵件或其他網頁中點擊你的網站鏈接,就會直接打開你的 Android 應用,而不是你的網站。
(2)執行 Web 搜索
要啓動一次 Web 搜索,請使用 ACTION_WEB_SEARCH 並在附件 SearchManager.QUERY 中指定搜索字符串。
Action
ACTION_WEB_SEARCH
數據 URI Scheme
無
MIME 類型
無
附件
SearchManager.QUERY
搜索字符串
Intent 示例:
public void searchWeb(String query) {
Intent intent = new Intent(Intent.ACTION_SEARCH);
intent.putExtra(SearchManager.QUERY, query);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}