12/08/2018, 13:47

[Hướng dẫn] Lấy kết quả trả về từ một Activity.

Trong Android, việc truyền và nhận dữ liệu và kết quả giữa các Activity rất hay được sử dụng, và đây cũng là một trong những bài học cơ bản đầu tiên mà mỗi bạn khi bắt đầu tìm hiểu về lập trình Android đều cần biết. Bằng cách sử dụng startActivityForResult(Intent intent, int requestCode) thay vì ...

Trong Android, việc truyền và nhận dữ liệu và kết quả giữa các Activity rất hay được sử dụng, và đây cũng là một trong những bài học cơ bản đầu tiên mà mỗi bạn khi bắt đầu tìm hiểu về lập trình Android đều cần biết.

Bằng cách sử dụng startActivityForResult(Intent intent, int requestCode) thay vì dùng startActivity() bạn có thể start một Activity và sau đó nhận kết quả trả về từ Activity đó thông qua phương thức onActivityResult().

Trong ví dụ dưới đây, MainActivity sẽ start DetailActivity và sau đó nhận lại kết quả từ Activity đó.

MainActivity

public class MainActivity extends Activity {

    /* REQUEST_CODE là một giá trị int dùng để định danh mỗi request. Khi nhận được kết quả, hàm callback sẽ trả về cùng REQUEST_CODE này để ta có thể xác định và xử lý kết quả. */
    private static final int REQUEST_CODE_EXAMPLE = 0x9345;

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

        // Tạo một Intent để start DetailActivity
        final Intent intent = new Intent(this, DetailActivity.class);

        // Start DetailActivity với request code vừa được khai báo trước đó
        startActivityForResult(intent, REQUEST_CODE_EXAMPLE);
    }

    // Khi kết quả được trả về từ Activity khác, hàm onActivityResult sẽ được gọi.
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Kiểm tra requestCode có trùng với REQUEST_CODE vừa dùng
        if(requestCode == REQUEST_CODE_EXAMPLE) {

            // resultCode được set bởi DetailActivity
            // RESULT_OK chỉ ra rằng kết quả này đã thành công
            if(resultCode == Activity.RESULT_OK) {
                // Nhận dữ liệu từ Intent trả về
                final String result = data.getStringExtra(DetailActivity.EXTRA_DATA);

                // Sử dụng kết quả result bằng cách hiện Toast
                Toast.makeText(this, "Result: " + result, Toast.LENGTH_LONG).show();
            } else {
                // DetailActivity không thành công, không có data trả về.
            }
        }
    }
}

DetailActivity

public class DetailActivity extends Activity {

    // Biến constant được dùng để định danh dữ liệu được truyền giữa các Activity
    public static final String EXTRA_DATA = "EXTRA_DATA";

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

        final View button = findViewById(R.id.button);
        // Trả về kết quả sau khi click vào button
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Tạo một Intent mới để chứa dữ liệu trả về
                final Intent data = new Intent();

                // Truyền data vào intent
                data.putExtra(EXTRA_DATA, "Some interesting data!");

                // Đặt resultCode là Activity.RESULT_OK to
                // thể hiện đã thành công và có chứa kết quả trả về
                setResult(Activity.RESULT_OK, data);

                // gọi hàm finish() để đóng Activity hiện tại và trở về MainActivity.
                finish();
            }
        });
    }

    @Override
    public void onBackPressed() {

            // đặt resultCode là Activity.RESULT_CANCELED thể hiện
            // đã thất bại khi người dùng click vào nút Back.
            // Khi này sẽ không trả về data.
        setResult(Activity.RESULT_CANCELED);
        super.onBackPressed();
    }
}

Một số điểm cần chú ý

  • Dữ liệu chỉ có thể được trả về khi bạn gọi hàm finish(). Cần phải gọi hàm setResult() trước khi gọi finish(), nếu không kết quả sẽ không được trả về.
  • Chắc chắn rằng Activity không đặt launchMode là singleTask, khi đó Activity sẽ chạy ở một task riêng và vì thế bạn sẽ không nhận được kết quả từ Activity đó. Khi đó nó sẽ ngay lập tức gọi onActivityResult() với resultCode = Activity.RESULT_CANCELED.
  • Cần chú ý khi sử dụng launchMode là singleInstance. Trên thiết bị trước Lollipop (Android 5.0, API 21) các Activity sẽ không trả về kết quả.

Hi vọng bài viết sẽ giúp ích cho bạn đọc.

Nguồn: http://stackoverflow.com/documentation/android/103/intent/533/getting-a-result-from-another-activity#t=201608280332305710764

0