从另一个 Activity 获取结果

通过使用 startActivityForResult(Intent intent, int requestCode) 你可以启动另一个 Activity ,然后在 onActivityResult(int requestCode, int resultCode, Intent data) 方法中从 Activity 接收结果。结果将作为 Intent 返回。意图可以通过 Bundle 包含数据

在这个例子中,MainActivity 将启动一个 DetailActivity 然后期望它的结果。每个请求类型都应该有自己的 int 请求代码,这样在 MainActivity重写的 onActivityResult(int requestCode, int resultCode, Intent data) 方法中,可以通过比较 requestCodeREQUEST_CODE_EXAMPLE 的值来确定处理哪个请求(尽管在这个例子中,只有一个)。

主要活动:

public class MainActivity extends Activity {

    // Use a unique request code for each use case 
    private static final int REQUEST_CODE_EXAMPLE = 0x9345; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create a new instance of Intent to start DetailActivity
        final Intent intent = new Intent(this, DetailActivity.class);

        // Start DetailActivity with the request code
        startActivityForResult(intent, REQUEST_CODE_EXAMPLE);
    }

    // onActivityResult only get called 
    // when the other Activity previously started using startActivityForResult
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // First we need to check if the requestCode matches the one we used.
        if(requestCode == REQUEST_CODE_EXAMPLE) {

            // The resultCode is set by the DetailActivity
            // By convention RESULT_OK means that whatever
            // DetailActivity did was executed successfully
            if(resultCode == Activity.RESULT_OK) {
                // Get the result from the returned Intent
                final String result = data.getStringExtra(DetailActivity.EXTRA_DATA);

                // Use the data - in this case, display it in a Toast.
                Toast.makeText(this, "Result: " + result, Toast.LENGTH_LONG).show();
            } else {
                // setResult wasn't successfully executed by DetailActivity 
                // Due to some error or flow of control. No data to retrieve.
            }
        }
    }
}

DetailActivity:

public class DetailActivity extends Activity {

    // Constant used to identify data sent between Activities.
    public static final String EXTRA_DATA = "EXTRA_DATA";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);

        final Button button = (Button) findViewById(R.id.button);
        // When this button is clicked we want to return a result
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Create a new Intent object as container for the result
                final Intent data = new Intent();

                // Add the required data to be returned to the MainActivity
                data.putExtra(EXTRA_DATA, "Some interesting data!");
                
                // Set the resultCode as Activity.RESULT_OK to 
                // indicate a success and attach the Intent
                // which contains our result data
                setResult(Activity.RESULT_OK, data); 

                // With finish() we close the DetailActivity to 
                // return back to MainActivity
                finish();
            }
        });
    }

    @Override
    public void onBackPressed() {
        // When the user hits the back button set the resultCode 
        // as Activity.RESULT_CANCELED to indicate a failure
        setResult(Activity.RESULT_CANCELED);
        super.onBackPressed();
    }
}

你需要注意的一些事项:

  • 只有在你拨打 finish() 时才会返回数据。你需要在致电 finish() 之前致电 setResult(),否则将不会返回任何结果。

  • 确保你的 Activity 没有使用 android:launchMode="singleTask",否则会导致 Activity 在一个单独的任务中运行,因此你不会收到它的结果。如果你的 Activity 使用 singleTask 作为启动模式,它将立即调用 onActivityResult(),结果代码为 Activity.RESULT_CANCELED

  • 使用 android:launchMode="singleInstance" 时要小心。在 Lollipop 之前的设备上(Android 5.0,API Level 21),活动不会返回结果。

  • 调用 startActivityForResult() 时,可以使用显式隐式意图。在启动你自己的某个活动以接收结果时,你应该使用明确的意图来确保你收到预期的结果。无论它包含什么,明确的 intent 总是传递给它的目标; 没有咨询 filter。但只有当组件可以通过组件的某个过滤器时,才会将隐式意图传递给组件。