【Android基础】利用Intent在Activity之间传递数据

前言:

上一篇文章给大家聊了Intent的用法,如何用Intent启动Activity和隐式Intent,这一篇文章给大家聊聊如何利用Intent在Activity之间进行沟通。

从一个Activity获取返回结果:

启动一个Activity不仅仅是startActivity(Intent intent)一种方法,你也可以通过startActivityForResult()启动一个Activity并且在它退出的时候收到一个返回结果。

比如,你可以调用系统相机在你的应用中,拍了一张照片,然后返回到你的Activity,这个时候就可以通过这种方法把照片作为结果返回给你的Activity。再比如,你可以通过这种方法启动系统联系人应用,然后获取一个人的详细联系方式。

注意:在调用startActivityForResult()时你可以利用显示Intent或者隐式Intent,但是在你能够利用显式Intent的时候尽量利用显式Intent,这样能够保证返回的结果是你期待的正确结果。

启动一个Activity:

在用startActivityForResult()来启动一个Activity时,Intent的写法与startActivity()是一样的,没有任何区别,只是你需要传递一个额外的Integer的变量作为启动参数,当启动的那个Activity退出时这个参数会被作为回调函数的一个参数,用来区分返回结果,也就是说你启动Activity时传递的参数(requestCode)和返回结果时的那个参数(requestCode)是一致的。

下面是一个调用startActivityForResult()获取联系人的例子:

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);
}

startActivityForResult()函数在Activity源码中是这样的:

 /**
     * Same as calling {@link #startActivityForResult(Intent, int, Bundle)}
     * with no options.
     *
     * @param intent The intent to start.
     * @param requestCode If >= 0, this code will be returned in
     *                    onActivityResult() when the activity exits.
     *
     * @throws android.content.ActivityNotFoundException
     *
     * @see #startActivity
     */
    public void startActivityForResult(Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);
    }

这个方法在Activity中进行了重载,startActivityForResult(intent, requestCode, null);方法就不贴出来了。但是对于这个方法使用时的注意事项我给大家翻译一下:

  • 这个方法只能用来启动一个带有返回结果的Activity,Intent的参数设定需要注意一下,你不能启动一个Activity使用singleTask的launch mode,用singleTask启动Activity,那个Activity在另外的一个Activity栈中,你会立刻收到RESULT_CANCELED消息;
  • 不能在Activity生命周期函数onResume之前调用startActivityForResult()方法,如果你在onResume之前调用了,那么所在的Activity就无法显示,直到启动的那个Activity退出然后返回结果,这是为了避免在重新定向到另外Activity时窗口闪烁;

接收返回结果:

当startActivityForResult()启动的Activity完成任务退出时,系统会回调你调用Activity的onActivityResult()方法,这个方法有三个参数:

  • resquestCode : 启动Activity时传递的requestCode;
  • resultCode: 表示调用成功或者失败的变量,值为下面二者之一; /** Standard activity result: operation canceled. */ public static final int RESULT_CANCELED = 0; /** Standard activity result: operation succeeded. */ public static final int RESULT_OK = -1;
  • 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结果,你需要清楚的了解Intent返回结果的格式。如果是你自己写的Intent作为返回结果你会很清楚,但是如果是调用的系统APP(相机,联系人等),那么Intent返回结果格式你应该清楚的知道。比如:联系人应用是返回的联系人URI,相机返回的是Bitmap数据。

处理返回结果:

下面的代码是如何处理获取联系人的结果:

@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... 
        } 
    } 
}

下面的代码是处理调用系统相机返回的结果:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bundle extras = data.getExtras();
        Bitmap imageBitmap = (Bitmap) extras.get("data");
        mImageView.setImageBitmap(imageBitmap);
    } 
}

获取启动Intent:

在被启动的Activity中你可以接收启动这个Activity的Intent,在生命周期范围内都能调用getIntent()来获取这个Intent,但是一般都是在onCreat和onStart函数中获取,下面就是一个获取Intent的例子:

@Override 
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 
    setContentView(R.layout.main);
 
    // Get the intent that started this activity 
    Intent intent = getIntent();
    Uri data = intent.getData();
 
    // Figure out what to do based on the intent type 
    if (intent.getType().indexOf("image/") != -1) {
        // Handle intents with image data ... 
    } else if (intent.getType().equals("text/plain")) {
        // Handle intents with text ... 
    } 
}

设置返回Intent:

上面介绍了怎么在onActivityResult()中处理Intent,但是怎么在你的应用中设置这个返回Intent呢?如果你想给调用你的Activity返回一个结果可以通过调用setResult()设置返回内容,然后结束这个Activity。下面的代码是一个示例:

// Create intent to deliver some kind of result data 
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");
setResult(Activity.RESULT_OK, result);
finish();

以上就是使用Intent在不同Activity进行信息传递和沟通的讲解,到此Intent系列文章完结,前两篇文章是关于Intent详解和Intent使用的文章,有什么不明白的请留言,大家共同学习,共同进步,谢谢!

原文发布于微信公众号 - 程序员互动联盟(coder_online)

原文发表时间:2015-08-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏iOS 开发杂谈

浅谈 NSUserDefaults

每次程序启动的时候调用 registerDefaults: 方法都是安全的,完全可以将这个方法的调用放到 applicationDidFinishLaunchi...

19960
来自专栏潇涧技术专栏

Android Development Code Snippets

8810
来自专栏项勇

笔记71 | Intent分享内容(文本,图片,视频)

21870
来自专栏Android先生

Android各大手机品牌手机跳转到权限管理界面

最近项目中遇到这样个需求场景:<br > 当我们的用户使用App时不小心拒绝了某项必要权限,而导致无法正常使用。这时候希望重新去打开该权限,那么问题来了,And...

29710
来自专栏MelonTeam专栏

XCode LLDB调试小技巧基础篇提高篇汇编篇

导语 记录平时用到的XCode LLDB调试小技巧 工欲善其事必先利其器,介绍一些LLDB调试的命令和小技巧~ 基础篇 1.print命令 p 输...

1.5K80
来自专栏everhad

安卓Task和Back Stack

概述 一个Activity允许用户完成一些操作,甚至,Android中设计Activity为组件的形式,这样,多个Activity——甚至是其它App的Acti...

21090
来自专栏分享达人秀

Intent 属性详解(下)

上一期学习了Intent的前三个属性,本期接着学习其余四个属性,以及Android系统常用内置组件的启动。 四、Data和Type属性 Dat...

26550
来自专栏上善若水

009android初级篇之APP中使用系统相机相册等集成应用

这是第一种方式 在启动相机前先指定好图片的文件位置,通知intent,同时也保留在成员变量中。然后在函数中,可以直接打开该文件

15340
来自专栏酷玩时刻

Android极速开发之Apk安装

安装之前判断是否有root权限,如果有root权限就静默安转,如果没有就利用意图进行安装。源码参考地址

13030
来自专栏非著名程序员

WebView 的 input 上传照片的兼容问题

问题 前几天接到的一个需求,是关于第三方理财产品的 H5 上传照片问题。 对方说他们的新的需求,需要接入方配合上传资产照片的需求,测试之后发现我们这边的 ap...

40950

扫码关注云+社区

领取腾讯云代金券