Android - 和其他APP交互 - 获得activity的返回值
启用另一个activity不一定是单向的。也可以启用另一个activity并且获得返回值。要获得返回值的话,调用startActivityForResult()(而不是startActivity())。
比如,app可以打开相机然后接收一张照片作为返回值。或者,为了让用户选择一个联系人可以让用户启动联系人相关app,然后收到联系人详情作为结果。
当然,这个响应的activity必须设计为有返回值的。当返回的时候,它用Intent对象作为返回值。activity会在onActivityResult()回调方法中收到。
注意:用明确的和模糊的intent都可以使用startActivityForResult()。当使用自己的activity来接收结果时,需要使用一个明确的intent来保证你可以收到结果。
开始一个Activity
当启动一个activity来获取返回值时Intent对象没有什么特别的,但是需要另外传递一个integer参数给startActivityForResult()方法。
这个integer参数是一个"request code",用来标识请求。当收到Intent结果,回调时会返回同样的"request code"这样app可以很好的识别结果和决定如何处理它。
例如,这里有一个如何启动activity来让用户选择一个联系人:
1 static final int PICK_CONTACT_REQUEST = 1; // The request code 2 ... 3 private void pickContact() { 4 Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts")); 5 pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers 6 startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST); 7 }
接收返回值
当用户完成了后来activity中的操作并且返回时,系统会调用activity的onActivityResult()方法。这个方法包含三个参数:
- 在startActivityForResult()中传递的请求码。
- 第二个activity的返回码。它会时RESULT_OK如果操作成功,或者RESULT_CANCELED如果用户退回去或者操作由于某些原因失败。
- 一个带有结果数据的Intent
例如,这里是如何处理选择联系人的返回值:
1 @Override 2 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 3 // 检查返回的结果 4 if (requestCode == PICK_CONTACT_REQUEST) { 5 // 确保请求成功了 6 if (resultCode == RESULT_OK) { 7 // 用户选择了一个联系人 8 // Intent的数据Uri标识了联系人被选中了 9 10 // 用这个联系人做点什么(下面会有示例) 11 } 12 } 13 }
这个例子中,由Android联系人或其他联系人相关app返回的Intent提供了一个Uri可以标识用户选择了哪个联系人。
为了成功的处理结果,必须要了解返回的Intent的格式是什么样的。当返回值的activity是自己的activity时处理起来很简单。Android平台自带的app,对于这些结果可以根据他们提供的API来处理。例如,联系人app总是返回一个content URI来标识选中的联系人,相机app在附加数据中返回一个Bitmap(可以在Capturing Photos中查看)。
附加:读取联系人数据
上面的代码展示了如何从联系人app中获得结果但是没有详细的展示如何读结果数据,因为需要更多的关于content providers的探讨。然而,如果你好奇的话,这里由一些代码展示了如果从选择的联系人中获得电话号码:
1 @Override 2 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 3 // 查看返回的是哪个请求 4 if (requestCode == PICK_CONTACT_REQUEST) { 5 // 确保请求成功了 6 if (resultCode == RESULT_OK) { 7 // 获得指向选中联系人的URI 8 Uri contactUri = data.getData(); 9 // 我们只需要NUMBER列,因为结果中只有一行 10 String[] projection = {Phone.NUMBER}; 11 12 // 在联系人上执行查询来获得NUMBER列 13 // 我们不需要选择排序方法(只有一个结果) 14 // 注意:query()应该在另外一个线程调用,为了避免阻塞app的UI线程。(为了简单,这里就不那么做了) 15 // 用CursorLoader来执行查询 16 Cursor cursor = getContentResolver() 17 .query(contactUri, projection, null, null, null); 18 cursor.moveToFirst(); 19 20 //从NUMBER列获得电话号码 21 int column = cursor.getColumnIndex(Phone.NUMBER); 22 String number = cursor.getString(column); 23 24 //用电话号码所点什么 25 } 26 } 27 }
注意:在Android2.3(API等级9)之前,使用Contracts Provider(就像上面展示的)来查询需要app声明READ_CONTACTS权限(查看Security and Permissions)。然后,从Android2.3开始,联系人app允许app用临时权限来用Contacts Provider获得结果。这个临时权限只适用于明确的联系人请求,所以除非是由intent的Uri明确指定的联系人,其他的都不能查询,或者可以声明READ_CONTACTS权限。
上一篇:Android - 和其他APP交互 - 把用户带到其他APP
下一篇:Android - 和其他APP交互 - 让其他APP启动你的Activity