從另一個 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。但只有當元件可以通過元件的某個過濾器時,才會將隱式意圖傳遞給元件。