啟動另外一個Activity並不都是單向的,你也可以啟動另外一個Activity,並接受被啟動的Activity所返回的結果,這需要調用startActivityForResult()方法,而不是startActivity()方法。
例如,你的應用程序可以啟動一個Camera應用程序,並把該應用程序拍攝的照片作為結果來接收。或者為了讓用戶選擇聯系人,你可以啟動People應用程序,並且把聯系人細節作為結果來接收。
當然,響應請求的Activity必須要比設計成能夠返回一個結果。在返回結果時,它會把結果作為一個Intent對象來發送。你的Activity在onActivityResult()回調方法中接收這個對象。
注意:在調用startActivityForResult()方法時,你可以使用明確的或隱含的Intent對象。當你要啟動的Activity是你自己的定義Activity時,你應該使用明確的Intent對象,以便確保你能夠接收到期望的結果。
啟動Activity
有關用於能夠啟動返回結果的Activity的Intent對象,沒有特殊的要求,但是你需要把一個附加的整數參數傳遞給startActivityForResult()方法。
這個整數參數是一個標識你的請求的請求代碼。當你接收到Intent對象時,回調方法會提供相同的請求代碼,以便你的應用程序能夠正確識別結果,並判定如何處理它。
例如,以下代碼啟動了一個允許用戶選擇聯系人的Activity:
staticfinalint PICK_CONTACT_REQUEST =1; // The request code
...
private void pickContact() {
Intent pickContactIntent = new Intent(Intent.ACTION_PICK, new Uri("content://contacts"));
pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}
接收結果
當用戶使用完被啟動的Activity並返回時,系統會調用你的Activity的onActivityResult()方法,這個方法包括三個參數:
1. 你傳遞給startActivityForResult()方法的請求代碼;
2. 由第二個Activity指定的結果代碼。如果操作成功,它是RESULT_OK,如果用戶退出或因為某些原因讓操作失敗,則是RESULT_CANCELED.
3. 一個攜帶結果數據的Intent對象。
例如,以下代碼處理選取聯系人Intent對象的結果:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which contact was selected.
// Do something with the contact here (bigger example below)
}
}
}
在這個例子中,從Android的Contacts或People應用程序中返回的Intent對象提供了一個標識用戶選擇的聯系人的內容Uri。
為了能夠成功的處理返回結果,你必須了解被返回的Intent對象的格式。當返回的結果是有你自己的Activity提供的時候,做這件事就很容易。Android平台的應用程序都提供了它們自己的API來從返回的Intent對象中獲取具體的結果數據。例如,People應用程序(某些較舊版本上的Contacts應用程序)總是返回標識用戶選擇的聯系人的內容URI,並且Camera應用會在“data”附加字段中返回一個Bitmap對象。
讀取聯系人數據
以上代碼介紹了如何獲取來自People應用程序的返回結果,但沒有詳細的介紹如何從返回結果中讀取數據,因為它需要討論一些更高級的有關content Providers的話題。以下代碼會告訴你如何查詢結果數據,從而獲取用戶選擇的聯系人的電話號碼:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request it is that we're responding to
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// Get the URI that points to the selected contact
Uri contactUri = data.getData();
// We only need the NUMBER column, because there will be only one row in the result
String[] projection = {Phone.NUMBER};
// Perform the query on the contact to get the NUMBER column
// We don't need a selection or sort order (there's only one result for the given URI)
// CAUTION: The query() method should be called from a separate thread to avoid blocking
// your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
// Consider using CursorLoader to perform the query.
Cursor cursor = getContentResolver()
.query(contactUri, projection, null, null, null);
cursor.moveToFirst();
// Retrieve the phone number from the NUMBER column
int column = cursor.getColumnIndex(Phone.NUMBER);
String number = cursor.getString(column);
// Do something with the phone number...
}
}
}
注意:在Android2.3(API Level 9)之前,執行基於Contacts提供器的查詢,會要求你的應用程序聲明READ_CONTACTS權限。但是,從Android2.3開始,Contacts/People應用程序會給你的應用程序授予一個臨時權限,以便能夠從Contacts提供器中獲取被返回的數據。這個臨時權限僅適用於具體的請求的聯系人,因此你不能使用這個返回結果來查詢由Intent的Uri指定的聯系人以外的數據,除非你聲明了READ_CONTACTS權限