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

 

posted @ 2013-06-19 14:14  fengquanwang  阅读(3737)  评论(0编辑  收藏  举报