Gửi dữ liệu đơn giản đến các ứng dụng khác

Android sử dụng ý định và các dữ liệu bổ sung liên quan để cho phép người dùng chia sẻ thông tin nhanh chóng và dễ dàng bằng cách sử dụng ứng dụng yêu thích.

Android cung cấp hai cách để người dùng chia sẻ dữ liệu giữa các ứng dụng:

  • Trang chia sẻ nội dung của Android chủ yếu được thiết kế để gửi nội dung ra bên ngoài ứng dụng và/hoặc gửi trực tiếp cho người dùng khác. Ví dụ: chia sẻ URL với một người bạn.
  • Trình phân giải ý định của Android là lựa chọn phù hợp nhất để truyền dữ liệu sang giai đoạn tiếp theo của một tác vụ được xác định rõ ràng. Ví dụ: mở một tệp PDF từ ứng dụng của bạn và cho phép người dùng chọn trình xem mà họ muốn.

Khi tạo một ý định, bạn sẽ chỉ định thao tác mà bạn muốn ý định đó thực hiện. Android sử dụng thao tác ACTION_SEND để gửi dữ liệu từ hoạt động này sang hoạt động khác, ngay cả khi vượt qua ranh giới của quy trình. Bạn cần chỉ định dữ liệu và loại dữ liệu. Hệ thống tự động xác định các hoạt động tương thích có thể nhận dữ liệu và hiển thị các hoạt động đó cho người dùng. Đối với trình phân giải ý định, nếu chỉ một hoạt động có thể xử lý ý định, thì hoạt động đó sẽ bắt đầu ngay lập tức.

Lý do nên sử dụng Trang chia sẻ nội dung của Android

Bạn nên sử dụng Trang chia sẻ nội dung trên Android để tạo sự nhất quán cho người dùng trên các ứng dụng. Đừng hiển thị danh sách mục tiêu chia sẻ của ứng dụng hoặc tạo các biến thể của riêng bạn trên Trang chia sẻ nội dung.

Trang chia sẻ nội dung trên Android cho phép người dùng chia sẻ thông tin với đúng người, kèm theo các đề xuất về ứng dụng phù hợp, tất cả chỉ bằng một lần nhấn. Trang chia sẻ nội dung có thể đề xuất các mục tiêu không có sẵn cho các giải pháp tuỳ chỉnh và sử dụng một thứ hạng nhất quán. Điều này là do Trang chia sẻ nội dung có thể xem xét thông tin về hoạt động của người dùng và ứng dụng chỉ có sẵn cho hệ thống.

Trang chia sẻ nội dung trên Android cũng có nhiều tính năng tiện lợi cho nhà phát triển. Ví dụ: bạn có thể làm như sau:

Sử dụng Trang chia sẻ nội dung của Android

Đối với mọi hình thức chia sẻ, hãy tạo một ý định và đặt thao tác của ý định đó thành Intent.ACTION_SEND. Để cho thấy Trang chia sẻ nội dung của Android, hãy gọi Intent.createChooser() và truyền vào đó đối tượng Intent. Phương thức này trả về một phiên bản ý định luôn cho thấy Trang chia sẻ nội dung của Android.

Gửi nội dung văn bản

Cách sử dụng đơn giản và phổ biến nhất của Trang chia sẻ nội dung Android là gửi nội dung văn bản từ hoạt động này sang hoạt động khác. Ví dụ: hầu hết các trình duyệt đều có thể chia sẻ URL của trang đang hiển thị dưới dạng văn bản với một ứng dụng khác. Việc này rất hữu ích khi chia sẻ bài viết hoặc trang web với bạn bè thông qua email hoặc mạng xã hội. Sau đây là ví dụ về cách thực hiện việc này:

Kotlin

val sendIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
    type = "text/plain"
}

val shareIntent = Intent.createChooser(sendIntent, null)
startActivity(shareIntent)

Java

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");

Intent shareIntent = Intent.createChooser(sendIntent, null);
startActivity(shareIntent);

Nếu muốn, bạn có thể thêm thông tin bổ sung, chẳng hạn như người nhận email (EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC), chủ đề email (EXTRA_SUBJECT), v.v.

Lưu ý: Một số ứng dụng email, chẳng hạn như Gmail, sẽ có String[] cho các tính năng bổ sung như EXTRA_EMAILEXTRA_CC. Sử dụng putExtra(String, String[]) để thêm các đối tượng này vào ý định của bạn.

Gửi nội dung nhị phân

Chia sẻ dữ liệu nhị phân bằng thao tác ACTION_SEND. Đặt loại MIME thích hợp và đặt URI cho dữ liệu trong EXTRA_STREAM bổ sung, như trong ví dụ sau. Loại tệp này thường dùng để chia sẻ hình ảnh nhưng có thể dùng để chia sẻ bất kỳ loại nội dung nhị phân nào.

Kotlin

val shareIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    // Example: content://com.google.android.apps.photos.contentprovider/...
    putExtra(Intent.EXTRA_STREAM, uriToImage)
    type = "image/jpeg"
}
startActivity(Intent.createChooser(shareIntent, null))

Java

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
// Example: content://com.google.android.apps.photos.contentprovider/...
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, null));

Ứng dụng nhận cần có quyền truy cập vào dữ liệu mà Uri trỏ đến. Có 2 cách được đề xuất để thực hiện việc này:

  • Lưu trữ dữ liệu trong ContentProvider của riêng bạn, đảm bảo rằng các ứng dụng khác có quyền phù hợp để truy cập vào nhà cung cấp của bạn. Cơ chế ưu tiên để cấp quyền truy cập là sử dụng quyền trên mỗi URI. Đây là quyền tạm thời và chỉ cấp quyền truy cập vào ứng dụng nhận. Một cách dễ dàng để tạo ContentProvider như thế này là sử dụng lớp trợ giúp FileProvider.
  • Sử dụng hệ thống MediaStore. MediaStore chủ yếu dành cho loại MIME video, âm thanh và hình ảnh. Tuy nhiên, kể từ Android 3.0 (API cấp 11), SDK này cũng có thể lưu trữ các loại nội dung không phải phương tiện. Để biết thêm thông tin, hãy xem MediaStore.Files. Bạn có thể chèn tệp vào MediaStore bằng scanFile(), sau đó một Uri kiểu content:// phù hợp để chia sẻ sẽ được truyền đến lệnh gọi lại onScanCompleted() đã cung cấp. Xin lưu ý rằng sau khi được thêm vào hệ thống MediaStore, mọi ứng dụng trên thiết bị đều có thể truy cập vào nội dung.

Dùng đúng loại MIME

Cung cấp loại MIME cụ thể nhất có sẵn cho dữ liệu mà bạn đang gửi. Ví dụ: sử dụng text/plain khi chia sẻ văn bản thuần tuý. Dưới đây là một số loại MIME phổ biến khi gửi dữ liệu đơn giản trong Android:

Người nhận đăng ký Người gửi gửi
text/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
`image/*`
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
Đuôi tệp được hỗ trợ application/pdf

Để biết thêm thông tin về các loại MIME, hãy xem sổ đăng ký chính thức về IANA về các loại nội dung đa phương tiện MIME.

Trang chia sẻ nội dung trên Android có thể cho thấy bản xem trước nội dung, tuỳ thuộc vào loại MIME được cung cấp. Một số tính năng xem trước chỉ áp dụng cho một số loại cụ thể.

Chia sẻ nhiều nội dung

Để chia sẻ nhiều phần nội dung, hãy sử dụng thao tác ACTION_SEND_MULTIPLE cùng với danh sách URI trỏ đến nội dung. Loại MIME sẽ thay đổi tuỳ theo tổ hợp nội dung mà bạn đang chia sẻ. Ví dụ: nếu chia sẻ 3 hình ảnh JPEG, bạn sẽ sử dụng loại "image/jpg". Đối với kết hợp các loại hình ảnh, hãy sử dụng "image/*" để khớp với một hoạt động xử lý mọi loại hình ảnh. Mặc dù có thể chia sẻ kết hợp nhiều loại, nhưng chúng tôi không khuyến khích việc này vì người nhận không biết rõ nội dung sẽ được gửi. Nếu cần gửi nhiều loại, hãy sử dụng "*/*". Ứng dụng nhận có trách nhiệm phân tích cú pháp và xử lý dữ liệu của bạn. Ví dụ:

Kotlin

val imageUris: ArrayList<Uri> = arrayListOf(
        // Add your image URIs here
        imageUri1,
        imageUri2
)

val shareIntent = Intent().apply {
    action = Intent.ACTION_SEND_MULTIPLE
    putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris)
    type = "image/*"
}
startActivity(Intent.createChooser(shareIntent, null))

Java

ArrayList<Uri> imageUris = new ArrayList<Uri>();
imageUris.add(imageUri1); // Add your image URIs here
imageUris.add(imageUri2);

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
shareIntent.setType("image/*");
startActivity(Intent.createChooser(shareIntent, null));

Hãy đảm bảo các đối tượng Uri được cung cấp trỏ đến dữ liệu mà ứng dụng nhận có thể truy cập.

Thêm nội dung đa dạng thức vào bản xem trước văn bản

Kể từ Android 10 (API cấp 29), Android Sharesheet sẽ hiển thị bản xem trước của văn bản đang được chia sẻ. Trong một số trường hợp, văn bản được chia sẻ có thể khó hiểu. Hãy cân nhắc chia sẻ một URL phức tạp như https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4. Bản xem trước phong phú hơn có thể giúp người dùng yên tâm về nội dung đang được chia sẻ.

Nếu đang xem trước văn bản, bạn có thể đặt tiêu đề, hình thu nhỏ hoặc cả hai. Thêm nội dung mô tả vào Intent.EXTRA_TITLE trước khi gọi Intent.createChooser() và thêm hình thu nhỏ phù hợp bằng ClipData.

Lưu ý: URI nội dung hình ảnh được cung cấp từ FileProvider, thường là từ <cache-path> đã định cấu hình. Để biết thêm thông tin, hãy xem bài viết Chia sẻ tệp. Hãy nhớ cấp cho Trang chia sẻ quyền thích hợp để đọc mọi hình ảnh mà bạn muốn dùng làm hình thu nhỏ. Để biết thêm thông tin, hãy xem Intent.FLAG_GRANT_READ_URI_PERMISSION.

Ví dụ:

Kotlin

 val share = Intent.createChooser(Intent().apply {
      action = Intent.ACTION_SEND
      putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/")

      // (Optional) Here you're setting the title of the content
      putExtra(Intent.EXTRA_TITLE, "Introducing content previews")

      // (Optional) Here you're passing a content URI to an image to be displayed
      data = contentUri
      flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
  }, null)
  startActivity(share)

Java

Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/");

// (Optional) Here you're setting the title of the content
sendIntent.putExtra(Intent.EXTRA_TITLE, "Introducing content previews");

// (Optional) Here you're passing a content URI to an image to be displayed
sendIntent.setData(contentUri);
sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

// Show the Sharesheet
startActivity(Intent.createChooser(sendIntent, null));

Bản xem trước sẽ có dạng như sau:

Thêm hành động tuỳ chỉnh vào trang chia sẻ nội dung

Ảnh chụp màn hình các thao tác tuỳ chỉnh trên Trang chia sẻ nội dung Android.

Trên Android 14 (API cấp 34) trở lên, ứng dụng có thể thêm thao tác tuỳ chỉnh vào Trang chia sẻ nội dung của Android. Các thao tác tuỳ chỉnh được hiển thị dưới dạng biểu tượng thao tác nhỏ ở đầu Trang chia sẻ nội dung Android và các ứng dụng có thể chỉ định bất kỳ Intent nào là thao tác được gọi khi người dùng nhấp vào biểu tượng.

Để thêm thao tác tuỳ chỉnh trên Trang chia sẻ nội dung Android, trước tiên, hãy tạo ChooserAction bằng ChooserAction.Builder. Bạn có thể chỉ định PendingIntent khi hành động được gọi khi người dùng nhấp vào biểu tượng. Tạo một mảng chứa tất cả các thao tác tuỳ chỉnh và chỉ định mảng đó là EXTRA_CHOOSER_CUSTOM_ACTIONS của Intent dùng chung.

Kotlin

val sendIntent = Intent(Intent.ACTION_SEND)
    .setType("text/plain")
    .putExtra(Intent.EXTRA_TEXT, text)
val shareIntent = Intent.createChooser(sendIntent, null)
val customActions = arrayOf(
    ChooserAction.Builder(
        Icon.createWithResource(context, R.drawable.ic_custom_action),
        "Custom",
        PendingIntent.getBroadcast(
            context,
            1,
            Intent(Intent.ACTION_VIEW),
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
        )
    ).build()
)
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions)
context.startActivity(shareIntent)

Java

Intent sendIntent = new Intent(Intent.ACTION_SEND)
        .setType("text.plain")
        .putExtra(Intent.EXTRA_TEXT, text);
Intent shareIntent = Intent.createChooser(sendIntent, null);
ChooserAction[] actions = new ChooserAction[]{
        new ChooserAction.Builder(
                Icon.createWithResource(context, R.drawable.ic_custom_action),
                "Custom",
                PendingIntent.getBroadcast(
                        context,
                        1,
                        new Intent(Intent.ACTION_VIEW),
                        PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT
                )
        ).build()
};
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions);
context.startActivity(shareIntent);

Thêm mục tiêu tuỳ chỉnh

Trang chia sẻ nội dung trên Android cho phép bạn chỉ định tối đa 2 đối tượng ChooserTarget hiển thị trước lối tắt chia sẻ và mục tiêu trình chọn được tải từ ChooserTargetServices. Bạn cũng có thể chỉ định tối đa 2 ý định trỏ đến các hoạt động được liệt kê trước các đề xuất về ứng dụng:

Thêm Intent.EXTRA_CHOOSER_TARGETSIntent.EXTRA_INITIAL_INTENTS vào Ý định chia sẻ sau khi gọi Intent.createChooser():

Kotlin

val share = Intent.createChooser(myShareIntent, null).apply {
    putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray)
    putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray)
}

Java

Intent shareIntent = Intent.createChooser(sendIntent, null);
share.putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray);
share.putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray);

Hãy cẩn trọng khi dùng tính năng này. Mỗi IntentChooserTarget tuỳ chỉnh mà bạn thêm sẽ làm giảm số lượng hệ thống đề xuất. Nói chung, bạn không nên thêm mục tiêu tuỳ chỉnh. Một ví dụ thích hợp phổ biến về việc thêm Intent.EXTRA_INITIAL_INTENTS là để cung cấp thêm các thao tác mà người dùng có thể thực hiện đối với nội dung được chia sẻ. Ví dụ: một người dùng chia sẻ hình ảnh và Intent.EXTRA_INITIAL_INTENTS được dùng để cho phép họ gửi đường liên kết. Một ví dụ thích hợp phổ biến về việc thêm Intent.EXTRA_CHOOSER_TARGETS là để hiển thị những người hoặc thiết bị liên quan mà ứng dụng của bạn cung cấp.

Loại trừ các mục tiêu cụ thể theo thành phần

Bạn có thể loại trừ các mục tiêu cụ thể bằng cách cung cấp Intent.EXTRA_EXCLUDE_COMPONENTS. Chỉ thực hiện thao tác này để xóa các mục tiêu mà bạn có quyền kiểm soát. Một trường hợp sử dụng phổ biến là ẩn mục tiêu chia sẻ của ứng dụng khi người dùng chia sẻ từ bên trong ứng dụng, vì ý định của họ có thể chia sẻ bên ngoài ứng dụng.

Thêm Intent.EXTRA_EXCLUDE_COMPONENTS vào ý định của bạn sau khi gọi Intent.createChooser():

Kotlin

  val share = Intent.createChooser(Intent(), null).apply {
    // Only use for components you have control over
    val excludedComponentNames = arrayOf(ComponentName("com.example.android", "ExampleClass"))
    putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames)
  }

Java

  Intent shareIntent = Intent.createChooser(new Intent(), null);
  // Only use for components you have control over
  ComponentName[] excludedComponentNames = {
          new ComponentName("com.example.android", "ExampleClass")
  };
  shareIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames);

Nhận thông tin về cách chia sẻ

Bạn nên biết khi nào người dùng của mình chia sẻ và họ chọn mục tiêu nào. Trang chia sẻ nội dung của Android giúp bạn lấy thông tin này bằng cách cung cấp ComponentName của các mục tiêu mà người dùng chọn thông qua IntentSender.

Trước tiên, hãy tạo PendingIntent cho BroadcastReceiver và cung cấp IntentSender của nó trong Intent.createChooser():

Kotlin

var share = Intent(Intent.ACTION_SEND)
// ...
val pi = PendingIntent.getBroadcast(
    myContext, requestCode,
    Intent(myContext, MyBroadcastReceiver::class.java),
    PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
share = Intent.createChooser(share, null, pi.intentSender)

Java

Intent share = new Intent(ACTION_SEND);
...
PendingIntent pi = PendingIntent.getBroadcast(myContext, requestCode,
        new Intent(myContext, MyBroadcastReceiver.class),
        PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
share = Intent.createChooser(share, null, pi.getIntentSender());

Nhận lệnh gọi lại trong MyBroadcastReceiver và tìm trong Intent.EXTRA_CHOSEN_COMPONENT:

Kotlin

override fun onReceive(context: Context, intent: Intent) {
  ...
  val clickedComponent : ComponentName = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
}

Java

@Override public void onReceive(Context context, Intent intent) {
  ...
  ComponentName clickedComponent = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
}

Thêm hành động tuỳ chỉnh vào trang chia sẻ nội dung

Trên Android 14 (API cấp 34) trở lên, ứng dụng có thể thêm thao tác tuỳ chỉnh vào Trang chia sẻ nội dung của Android. Tạo ChooserAction bằng ChooserAction.Builder. Bạn có thể chỉ định PendingIntent khi hành động được gọi khi người dùng nhấp vào biểu tượng. Tạo một mảng chứa tất cả các thao tác tuỳ chỉnh và chỉ định mảng đó là EXTRA_CHOOSER_CUSTOM_ACTIONS của Intent dùng chung.

Kotlin

val sendIntent = Intent(Intent.ACTION_SEND)
    .setType("text/plain")
    .putExtra(Intent.EXTRA_TEXT, text)
val shareIntent = Intent.createChooser(sendIntent, null)
val customActions = arrayOf(
    ChooserAction.Builder(
        Icon.createWithResource(context, R.drawable.ic_custom_action),
        "Custom",
        PendingIntent.getBroadcast(
            context,
            1,
            Intent(Intent.ACTION_VIEW),
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
        )
    ).build()
)
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions)
context.startActivity(shareIntent)

Java

Intent sendIntent = new Intent(Intent.ACTION_SEND)
        .setType("text.plain")
        .putExtra(Intent.EXTRA_TEXT, text);
Intent shareIntent = Intent.createChooser(sendIntent, null);
ChooserAction[] actions = new ChooserAction[]{
        new ChooserAction.Builder(
                Icon.createWithResource(context, R.drawable.ic_custom_action),
                "Custom",
                PendingIntent.getBroadcast(
                        context,
                        1,
                        new Intent(Intent.ACTION_VIEW),
                        PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT
                )
        ).build()
};
shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions);
context.startActivity(shareIntent);

Sử dụng trình phân giải ý định trên Android

Ảnh chụp màn hình trình phân giải ý định ACTION_SEND.

Trình phân giải ý định của Android phù hợp nhất khi gửi dữ liệu đến một ứng dụng khác trong luồng tác vụ được xác định rõ.

Để sử dụng trình phân giải ý định trên Android, hãy tạo một ý định và thêm các ứng dụng khác như cách bạn gọi Trang chia sẻ nội dung trong Android. Tuy nhiên, đừng gọi Intent.createChooser().

Nếu có nhiều ứng dụng đã cài đặt có bộ lọc khớp với ACTION_SEND và loại MIME, hệ thống sẽ hiển thị hộp thoại phân định có tên là trình phân giải ý định cho phép người dùng chọn một mục tiêu để chia sẻ. Nếu một ứng dụng khớp, ứng dụng đó sẽ chạy.

Dưới đây là ví dụ về cách sử dụng trình phân giải ý định trên Android để gửi văn bản:

Kotlin

val sendIntent: Intent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
    type = "text/plain"
}
startActivity(sendIntent)

Java

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);

Tìm hiểu thêm

Để biết thêm thông tin về cách gửi dữ liệu, hãy xem bài viết Ý định và bộ lọc ý định.