Cho phép các ứng dụng khác bắt đầu hoạt động của bạn

Nếu ứng dụng của bạn có thể thực hiện một thao tác hữu ích cho một ứng dụng khác, hãy chuẩn bị ứng dụng đó để phản hồi các yêu cầu thao tác bằng cách chỉ định bộ lọc ý định phù hợp trong hoạt động của bạn.

Ví dụ: nếu tạo một ứng dụng mạng xã hội có thể chia sẻ tin nhắn hoặc ảnh với bạn bè của người dùng, bạn nên hỗ trợ ý định ACTION_SEND. Sau đó, khi người dùng bắt đầu thao tác "chia sẻ" từ một ứng dụng khác, ứng dụng của bạn sẽ xuất hiện dưới dạng một tuỳ chọn trong hộp thoại bộ chọn (còn gọi là hộp thoại phân định), như minh hoạ trong hình 1.

Hình 1. Hộp thoại bộ chọn.

Để cho phép ứng dụng khác bắt đầu hoạt động của bạn theo cách này, bạn cần thêm phần tử <intent-filter> trong tệp kê khai cho phần tử <activity> tương ứng.

Khi ứng dụng của bạn được cài đặt trên một thiết bị, hệ thống sẽ xác định bộ lọc ý định và thêm thông tin vào danh mục nội bộ gồm các ý định được tất cả các ứng dụng đã cài đặt hỗ trợ. Khi một ứng dụng gọi startActivity() hoặc startActivityForResult() với ý định ngầm ẩn, hệ thống sẽ kiểm tra các hoạt động có thể phản hồi ý định đó.

Thêm bộ lọc ý định

Để xác định đúng ý định mà hoạt động có thể xử lý, hãy thêm mỗi bộ lọc ý định theo cách cụ thể nhất có thể về loại thao tác và dữ liệu mà hoạt động chấp nhận.

Hệ thống có thể gửi Intent nhất định đến một hoạt động nếu hoạt động đó có bộ lọc ý định đáp ứng các tiêu chí sau đây của đối tượng Intent:

Hành động
Một chuỗi đặt tên cho thao tác cần thực hiện. Thường là một trong những giá trị do nền tảng xác định, chẳng hạn như ACTION_SEND hoặc ACTION_VIEW.

Chỉ định dữ liệu này trong bộ lọc ý định bằng phần tử <action>. Giá trị bạn chỉ định trong phần tử này phải là tên chuỗi đầy đủ cho thao tác, thay vì hằng số API, như trong các ví dụ trên trang này.

Dữ liệu
Nội dung mô tả dữ liệu liên kết với ý định.

Chỉ định dữ liệu này trong bộ lọc ý định bằng phần tử <data>. Khi sử dụng một hoặc nhiều thuộc tính trong phần tử này, bạn có thể chỉ định chỉ loại MIME, tiền tố URI, lược đồ URI, hay tổ hợp các thuộc tính này và các thuộc tính khác cho biết loại dữ liệu được chấp nhận.

Lưu ý: Nếu không cần khai báo thông tin cụ thể về dữ liệu Uri (chẳng hạn như khi hoạt động của bạn xử lý loại dữ liệu "bổ sung" khác, thay vì URI), thì bạn chỉ nên chỉ định thuộc tính android:mimeType để khai báo loại dữ liệu mà hoạt động của bạn xử lý, chẳng hạn như text/plain hoặc image/jpeg.

Danh mục
Bổ sung một cách khác để mô tả hoạt động xử lý ý định, thường liên quan đến cử chỉ hoặc vị trí mà người dùng bắt đầu. Có nhiều danh mục được hệ thống hỗ trợ, nhưng hầu hết hiếm khi được sử dụng. Tuy nhiên, tất cả các ý định ngầm ẩn đều được xác định bằng CATEGORY_DEFAULT theo mặc định.

Chỉ định danh mục này trong bộ lọc ý định bằng phần tử <category>.

Trong bộ lọc ý định, bạn có thể khai báo tiêu chí mà hoạt động chấp nhận bằng cách khai báo từng tiêu chí với phần tử XML tương ứng được lồng trong phần tử <intent-filter>.

Ví dụ: đây là một hoạt động có bộ lọc ý định xử lý ý định ACTION_SEND khi loại dữ liệu là văn bản hoặc hình ảnh:

<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
        <data android:mimeType="image/*"/>
    </intent-filter>
</activity>

Mẹo: Nếu bạn muốn biểu tượng trong hộp thoại bộ chọn khác với biểu tượng mặc định cho hoạt động của bạn, hãy thêm android:icon trong phần tử <intent-filter>.

Mỗi ý định được chia sẻ chỉ định một thao tác và loại dữ liệu, nhưng bạn có thể khai báo nhiều thực thể của <action>, <category> và phần tử <data> trong mỗi <intent-filter>.

Nếu hai cặp thao tác và dữ liệu bất kỳ loại trừ lẫn nhau trong các hành vi của chúng, hãy tạo các bộ lọc ý định riêng biệt để chỉ định hành động nào được chấp nhận khi ghép nối với loại dữ liệu nào.

Ví dụ: giả sử hoạt động của bạn xử lý cả văn bản và hình ảnh cho cả ý định ACTION_SENDACTION_SENDTO. Trong trường hợp này, bạn phải xác định 2 bộ lọc ý định riêng biệt cho 2 thao tác vì ý định ACTION_SENDTO phải sử dụng dữ liệu Uri để chỉ định địa chỉ của người nhận bằng lược đồ URI send hoặc sendto. Lệnh này được minh hoạ trong ví dụ sau:

<activity android:name="ShareActivity">
    <!-- Filter for sending text; accepts SENDTO action with sms URI schemes -->
    <intent-filter>
        <action android:name="android.intent.action.SENDTO"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="sms" />
        <data android:scheme="smsto" />
    </intent-filter>
    <!-- Filter for sending text or images; accepts SEND action and text or image data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

Lưu ý: Để nhận ý định ngầm ẩn, bạn phải đưa danh mục CATEGORY_DEFAULT vào bộ lọc ý định. Các phương thức startActivity()startActivityForResult() xử lý mọi ý định như thể chúng đã khai báo danh mục CATEGORY_DEFAULT. Nếu bạn không khai báo danh mục đó trong bộ lọc ý định, thì sẽ không có ý định ngầm ẩn nào được phân giải cho hoạt động của bạn.

Để biết thêm thông tin về việc gửi và nhận ý định ACTION_SEND thực hiện hành vi chia sẻ qua mạng xã hội, hãy xem bài viết Nhận dữ liệu đơn giản từ các ứng dụng khác. Bạn cũng có thể tìm thấy thông tin hữu ích về cách chia sẻ dữ liệu trong phần Chia sẻ dữ liệu đơn giảnChia sẻ tệp.

Xử lý ý định trong hoạt động của bạn

Để quyết định hành động nào cần thực hiện trong hoạt động, hãy đọc Intent dùng để bắt đầu hành động đó.

Khi hoạt động của bạn bắt đầu, hãy gọi getIntent() để truy xuất Intent mà đã khởi động hoạt động. Bạn có thể thực hiện việc này bất cứ lúc nào trong suốt vòng đời của hoạt động, nhưng thường thì bạn nên thực hiện trong các lệnh gọi lại sớm như onCreate() hoặc onStart().

Lệnh này được minh hoạ trong ví dụ sau:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.main)

    val data: Uri? = intent?.data

    // Figure out what to do based on the intent type
    if (intent?.type?.startsWith("image/") == true) {
        // Handle intents with image data
    } else if (intent?.type == "text/plain") {
        // Handle intents with text
    }
}

Java

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

Trả về kết quả

Nếu muốn trả về một kết quả cho hoạt động đã gọi hoạt động của bạn, chỉ cần gọi setResult() để chỉ định mã kết quả và kết quả Intent. Khi hoàn tất thao tác và người dùng quay lại hoạt động gốc, gọi finish() để đóng (và huỷ) hoạt động của bạn. Lệnh này được minh hoạ trong ví dụ sau:

Kotlin

// Create intent to deliver some kind of result data
Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")).also { result ->
    setResult(Activity.RESULT_OK, result)
}
finish()

Java

// 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();

Bạn phải luôn chỉ định mã kết quả cùng với kết quả. Nói chung, đó là RESULT_OK hoặc RESULT_CANCELED. Sau đó, bạn có thể cung cấp thêm dữ liệu bằng một Intent nếu cần.

Lưu ý: Theo mặc định, kết quả được đặt thành RESULT_CANCELED. Vì vậy, nếu người dùng nhấn nút Quay lại trước khi hoàn thành thao tác và trước khi bạn đặt kết quả, hoạt động gốc sẽ nhận được kết quả là "đã huỷ".

Nếu chỉ cần trả về một số nguyên cho biết một trong vài tuỳ chọn kết quả, bạn có thể đặt mã kết quả thành bất kỳ giá trị nào lớn hơn 0. Nếu bạn sử dụng mã kết quả để cung cấp một số nguyên và không cần bao gồm Intent, thì bạn có thể gọi setResult() và chỉ chuyển mã kết quả:

Kotlin

setResult(RESULT_COLOR_RED)
finish()

Java

setResult(RESULT_COLOR_RED);
finish();

Trong trường hợp này, có lẽ chỉ có một vài kết quả khả dĩ, để cho mã kết quả là một số nguyên được xác định cục bộ (lớn hơn 0). Điều này rất hiệu quả khi bạn trả về một kết quả cho một hoạt động trong ứng dụng của riêng bạn, vì hoạt động mà nhận được kết quả có thể tham chiếu đến hằng số công khai để xác định giá trị của mã kết quả.

Lưu ý: Không cần kiểm tra liệu hoạt động của bạn có được bắt đầu bằng startActivity() hay startActivityForResult() hay không. Chỉ cần gọi setResult() nếu ý định để khởi động hoạt động của bạn có thể trông đợi một kết quả. Nếu hoạt động gốc có tên là startActivityForResult(), thì hệ thống sẽ mang đến cho hoạt động đó kết quả mà bạn cung cấp cho setResult(); nếu không, kết quả sẽ bị bỏ qua.