与其他APP通信(2)--从一个Activity得到结果
启动另一个activity不必总是单向的。你也可以启动另一个activity,然后获得一个返回结果。为了获得一个结果,调用startActivityForResult()(代替startActivity())。
例如,你可以启动一个相机应用,然后获得作为结果的照片。或者,你可以为了让用户选择一个联系人而启动了一个联系人应用,你将会获得作为结果的联系人细节信息。
当然了,目标activity必须设计成可以返回结果。当要返回时,它把结果作为另一个Intent对象发送出去。你的activity在onActivityResult()中收到结果。
注意:你可以使用显式或者隐式intent调用startActivityForResult()。当为了获得一个结果,你启动了自己的某个activity,那么你应该使用显式的intent,这样能确保你获得想要的结果。
启动Activity
当你为了一个结果而启动一个activity时,对于你要使用的intent并没有什么特别之处,但是你需要在调用startActivityForResult()方法时传递一个额外的整型参数。
这个整型参数就是“请求代码”即用来识别你的请求的。当你收到这个结果Intent的时候,这个回调提供了同一个请求代码,这样你的应用就可以识别这个结果然后决定如何处理。
例如,这里展示了如何启动一个activity来让用户选择一个联系人:
static final int PICK_CONTACT_REQUEST = 1; // The request code
...
private void pickContact() {
Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}
获得结果
当用户通过使用一系列activity后完成了操作并返回,系统会调用你的activity的onActivityResult()方法。这个方法包含3个参数:
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)
}
}
}
在这个例子中,安卓的联系人应用返回的结果Intent中包含一个内容Uri,标志了用户选择的联系人。
为了能够成功处理结果,你必须理解结果Intent的内容格式。当返回结果的activity是你自己的activity时,很容易做到。安卓平台上的应用为你期望的特定结果数据提供了他们自己的API。例如,联系人应用总是返回一个内容URI标志选择的联系人,相机应用在额外的”data”里返回一个Bitmap。
红利:读取联系人数据
上面的例子展示了如何从联系人应用中获得一个结果,但是并没有深入细节如何真正从结果中读取数据,因为这个需要更高级的关于”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)
// 警告: query()方法应该在另一个线程中执行,否则会妨碍UI线程 // (为了简单,本例子是直接在主线程中调用.)
//请考虑使用 CursorLoader 去执行查询.
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...
}
}
}