ส่งข้อมูลอย่างง่ายไปยังแอปอื่นๆ

Android ใช้ Intent และข้อมูลเพิ่มเติมที่เกี่ยวข้องเพื่อให้ผู้ใช้แชร์ข้อมูลได้อย่างรวดเร็วและง่ายดายโดยใช้แอปโปรด

Android มี 2 วิธีให้ผู้ใช้แชร์ข้อมูลระหว่างแอป ดังนี้

  • Android Sharesheet ออกแบบมาเพื่อส่งเนื้อหาภายนอกแอปและ/หรือส่งไปยังผู้ใช้รายอื่นโดยตรง เช่น การแชร์ URL กับเพื่อน
  • ตัวแก้ไข Intent ของ Android เหมาะที่สุดสำหรับการส่งข้อมูลไปยังขั้นตอนถัดไปของงานที่กำหนดไว้อย่างชัดเจน เช่น การเปิด PDF จากแอปและให้ผู้ใช้ เลือกโปรแกรมดูที่ต้องการ

เมื่อสร้าง Intent คุณต้องระบุการดำเนินการที่ต้องการให้ Intent ทำ Android ใช้การดำเนินการ ACTION_SEND เพื่อส่งข้อมูลจากกิจกรรมหนึ่งไปยังอีกกิจกรรมหนึ่ง แม้ว่าจะอยู่ข้ามขอบเขตของกระบวนการก็ตาม คุณต้องระบุข้อมูลและประเภทของข้อมูล ระบบจะระบุกิจกรรมที่เข้ากันได้ซึ่งรับข้อมูลได้โดยอัตโนมัติและแสดงกิจกรรมเหล่านั้นแก่ผู้ใช้ ในกรณีของตัวแก้ไข Intent หากมีเพียงกิจกรรมเดียวที่จัดการ Intent ได้ กิจกรรมนั้นจะเริ่มขึ้นทันที

เหตุใดจึงควรใช้ Android Sharesheet

เราขอแนะนำให้ใช้ Android Sharesheet เพื่อสร้างความสอดคล้องให้ผู้ใช้ในแอปต่างๆ อย่าแสดงรายการเป้าหมายการแชร์ของแอปเองหรือสร้างแผ่นแชร์เวอร์ชันของคุณเอง

Android Sharesheet ช่วยให้ผู้ใช้แชร์ข้อมูลกับบุคคลที่เหมาะสม พร้อมคำแนะนำเกี่ยวกับแอปที่เกี่ยวข้องได้ด้วยการแตะเพียงครั้งเดียว แผ่นแชร์สามารถแนะนำเป้าหมายที่โซลูชันที่กำหนดเองไม่สามารถทำได้ และใช้การจัดอันดับที่สอดคล้องกัน เนื่องจากแผ่นแชร์สามารถพิจารณาข้อมูลเกี่ยวกับกิจกรรมในแอปและกิจกรรมของผู้ใช้ที่ระบบเท่านั้นเข้าถึงได้

นอกจากนี้ Android Sharesheet ยังมีฟีเจอร์ที่มีประโยชน์มากมายสำหรับนักพัฒนาแอป เช่น คุณสามารถทำสิ่งต่อไปนี้ได้

ใช้ Android Sharesheet

สำหรับการแชร์ทุกประเภท ให้สร้าง Intent และตั้งค่าการดำเนินการเป็น Intent.ACTION_SEND หากต้องการแสดง Android Sharesheet ให้เรียก Intent.createChooser(), แล้วส่งออบเจ็กต์ Intent ไปยังฟังก์ชันดังกล่าว ฟังก์ชันนี้จะแสดงผล Intent เวอร์ชันที่แสดง Android Sharesheet เสมอ

ส่งเนื้อหาข้อความ

การใช้งาน Android Sharesheet ที่ตรงไปตรงมาและพบได้บ่อยที่สุดคือการส่งเนื้อหาข้อความจากกิจกรรมหนึ่งไปยังอีกกิจกรรมหนึ่ง เช่น เบราว์เซอร์ส่วนใหญ่สามารถแชร์ URL ของหน้าที่แสดงอยู่ในปัจจุบันเป็นข้อความกับแอปอื่นได้ ซึ่งมีประโยชน์สำหรับการแชร์บทความหรือเว็บไซต์กับเพื่อนๆ ผ่านอีเมลหรือโซเชียลเน็ตเวิร์ก ตัวอย่างวิธีทำมีดังนี้

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

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

คุณเลือกเพิ่มข้อมูลเพิ่มเติมได้ เช่น ผู้รับอีเมล (EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC), หัวเรื่องอีเมล (EXTRA_SUBJECT) และอื่นๆ

หมายเหตุ: แอปอีเมลบางแอป เช่น Gmail คาดหวัง String[] สำหรับข้อมูลเพิ่มเติม เช่น EXTRA_EMAIL และ EXTRA_CC ให้ใช้ putExtra(String, String[]) เพื่อเพิ่มข้อมูลเหล่านี้ลงใน Intent

ส่งเนื้อหาไบนารี

แชร์ข้อมูลไบนารีโดยใช้การดำเนินการ ACTION_SEND ตั้งค่าประเภท MIME ที่เหมาะสมและวาง URI ของข้อมูลในข้อมูลเพิ่มเติม EXTRA_STREAM ดังที่แสดงในตัวอย่างต่อไปนี้ โดยทั่วไปจะใช้เพื่อแชร์รูปภาพ แต่ก็ใช้เพื่อแชร์เนื้อหาไบนารีประเภทอื่นๆ ได้ด้วย

fun shareBinaryContent(context: Context) {
    val shareIntent: Intent = Intent().apply {
        action = ACTION_SEND
        // Example: content://com.google.android.apps.photos.contentprovider/...
        val imageUri: Uri =
            Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/1")
        putExtra(Intent.EXTRA_STREAM, imageUri)
        type = "image/jpeg"
    }
    context.startActivity(Intent.createChooser(shareIntent, null))
}

แอปพลิเคชันที่รับต้องมีสิทธิ์เข้าถึงข้อมูลที่ Uri ชี้ไป เราขอแนะนำให้ทำตามวิธีต่อไปนี้

  • จัดเก็บข้อมูลไว้ใน ContentProvider ของคุณเอง โดยตรวจสอบว่าแอปอื่นๆ มีสิทธิ์ที่ถูกต้องในการเข้าถึงผู้ให้บริการของคุณ กลไกที่แนะนำสำหรับการให้สิทธิ์เข้าถึงคือการใช้ สิทธิ์ต่อ URI ซึ่งเป็นสิทธิ์ชั่วคราวและให้สิทธิ์เข้าถึงแก่แอปพลิเคชันที่รับเท่านั้น วิธีง่ายๆ ในการสร้าง ContentProvider เช่นนี้คือการใช้คลาสตัวช่วย FileProvider
  • ใช้ MediaStore ของระบบ MediaStore เหมาะสำหรับประเภท MIME ของวิดีโอ เสียง และรูปภาพเป็นหลัก อย่างไรก็ตาม ตั้งแต่ Android 3.0 (API ระดับ 11) เป็นต้นไป ก็สามารถจัดเก็บประเภทที่ไม่ใช่สื่อได้ด้วย ดูข้อมูลเพิ่มเติมได้ที่ MediaStore.Files คุณสามารถแทรกไฟล์ลงใน MediaStore โดยใช้ scanFile() หลังจากนั้นระบบจะส่ง Uri ในรูปแบบ content:// ที่เหมาะสำหรับการแชร์ไปยังการเรียกกลับ onScanCompleted() ที่ระบุ โปรดทราบว่าเมื่อเพิ่มลงใน MediaStore ของระบบแล้ว แอปใดก็ตามในอุปกรณ์จะเข้าถึงเนื้อหาได้

ใช้ประเภท MIME ที่เหมาะสม

ระบุประเภท MIME ที่เฉพาะเจาะจงที่สุดสำหรับข้อมูลที่คุณส่ง เช่น ใช้ text/plain เมื่อแชร์ข้อความธรรมดา ต่อไปนี้คือประเภท MIME ทั่วไปบางประเภทเมื่อส่งข้อมูลอย่างง่ายใน Android

ผู้รับลงทะเบียนสำหรับ ผู้ส่งส่ง
text/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
`image/*`
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
นามสกุลไฟล์ที่รองรับ application/pdf

ดูข้อมูลเพิ่มเติมเกี่ยวกับประเภท MIME ได้ที่ รีจิสทรีอย่างเป็นทางการของประเภทสื่อ MIME ของ IANA

Android Sharesheet อาจแสดงตัวอย่างเนื้อหา ทั้งนี้ขึ้นอยู่กับประเภท MIME ที่ระบุ ฟีเจอร์ตัวอย่างบางรายการ ใช้ได้กับบางประเภทเท่านั้น

แชร์เนื้อหาหลายรายการ

หากต้องการแชร์เนื้อหาหลายรายการ ให้ใช้การดำเนินการ ACTION_SEND_MULTIPLE ร่วมกับรายการ URI ที่ชี้ไปยังเนื้อหา ประเภท MIME จะแตกต่างกันไปตามเนื้อหาที่คุณแชร์ เช่น หากคุณแชร์รูปภาพ JPEG 3 รูป ให้ใช้ประเภท "image/jpg" หากแชร์รูปภาพหลายประเภท ให้ใช้ "image/*" เพื่อจับคู่กับกิจกรรมที่จัดการรูปภาพทุกประเภท แม้ว่าคุณจะแชร์เนื้อหาหลายประเภทได้ แต่เราไม่แนะนำให้ทำเช่นนั้นเนื่องจากผู้รับจะไม่ทราบว่าคุณต้องการส่งเนื้อหาประเภทใด หากจำเป็นต้องส่งเนื้อหาหลายประเภท ให้ใช้ "*/*" แอปพลิเคชันที่รับมีหน้าที่แยกวิเคราะห์และประมวลผลข้อมูลของคุณ ตัวอย่าง

fun shareMultiple(context: Context) {
    val imageUris: ArrayList<Uri> = arrayListOf(
        Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/1"),
        Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/2")
    )

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

ตรวจสอบว่าออบเจ็กต์ Uri ที่ระบุชี้ไปยังข้อมูลที่แอปพลิเคชันที่รับเข้าถึงได้

เพิ่มข้อมูลอย่างละเอียดลงในตัวอย่างข้อความ

ตั้งแต่ Android 10 (ระดับ API 29) เป็นต้นไป Android Sharesheet จะแสดงตัวอย่างข้อความที่แชร์ ในบางกรณี ข้อความที่แชร์อาจเข้าใจยาก เช่น การแชร์ URL ที่ซับซ้อนอย่าง https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4 ตัวอย่างที่ละเอียดมากขึ้นจะช่วยให้ผู้ใช้มั่นใจได้ว่าคุณกำลังแชร์อะไร

หากแสดงตัวอย่างข้อความ คุณสามารถตั้งค่าชื่อ รูปภาพขนาดย่อ หรือทั้ง 2 อย่าง เพิ่มคำอธิบายลงใน Intent.EXTRA_TITLE ก่อนเรียก Intent.createChooser() และเพิ่มรูปภาพขนาดย่อที่เกี่ยวข้องโดยใช้ ClipData

หมายเหตุ: ระบบจะระบุ URI เนื้อหาของรูปภาพจาก FileProvider ซึ่งโดยปกติจะมาจาก <cache-path> ที่กำหนดค่าไว้ ดูข้อมูลเพิ่มเติมได้ที่การแชร์ไฟล์ อย่าลืมให้สิทธิ์ที่เหมาะสมแก่ Sharesheet เพื่ออ่านรูปภาพที่คุณต้องการใช้เป็นภาพขนาดย่อ ดูข้อมูลเพิ่มเติมได้ที่ Intent.FLAG_GRANT_READ_URI_PERMISSION

ตัวอย่าง

fun richContentToTextPreviewShares(context: Context) {
    val share = Intent.createChooser(
        Intent().apply {
            action = ACTION_SEND
            putExtra(Intent.EXTRA_TEXT, "https://da.cyanowen.top/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 =
                Uri.parse("content://com.google.android.apps.photos.contentprovider/0/1/mediakey/A123456789")
            flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
        },
        null
    )
    context.startActivity(share)
}

ตัวอย่างจะมีลักษณะดังนี้

เพิ่มการดำเนินการที่กำหนดเองลงในแผ่นแชร์

ภาพหน้าจอของการดำเนินการที่กำหนดเองใน Android Sharesheet

ใน Android 14 (ระดับ API 34) ขึ้นไป แอปสามารถเพิ่มการดำเนินการที่กำหนดเองลงใน Android Sharesheet ได้ การดำเนินการที่กำหนดเองจะแสดงเป็นไอคอนการดำเนินการขนาดเล็กที่ด้านบนของ Android Sharesheet และแอปสามารถระบุ Intent ใดก็ได้เป็นการดำเนินการที่จะเรียกใช้เมื่อมีการคลิกไอคอน

หากต้องการเพิ่มการดำเนินการที่กำหนดเองใน Android Sharesheet ให้สร้าง ChooserAction ด้วย ChooserAction.Builderก่อน คุณสามารถระบุ PendingIntent เป็นการดำเนินการที่จะเรียกใช้เมื่อมีการคลิกไอคอน สร้างอาร์เรย์ที่มีการดำเนินการที่กำหนดเองทั้งหมดและระบุอาร์เรย์ดังกล่าวเป็น EXTRA_CHOOSER_CUSTOM_ACTIONS ของ Intent การแชร์

fun sharesheetCustomActions(context: Context, previewText: String) {
    val sendIntent = Intent(ACTION_SEND)
        .setType("text/plain")
        .putExtra(Intent.EXTRA_TEXT, previewText)
    val shareIntent = Intent.createChooser(sendIntent, null)
    val customActions = arrayOf(
        ChooserAction.Builder(
            Icon.createWithResource(context, R.drawable.ic_logo),
            "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)
}

เพิ่มเป้าหมายที่กำหนดเอง

Android Sharesheet ช่วยให้คุณระบุออบเจ็กต์ ChooserTarget ได้สูงสุด 2 รายการ ซึ่งจะแสดงก่อนทางลัดการแชร์และเป้าหมายตัวเลือกที่โหลดจาก ChooserTargetServices นอกจากนี้ คุณยังระบุ Intent ได้สูงสุด 2 รายการที่ชี้ไปยังกิจกรรมซึ่งแสดงก่อนคำแนะนำเกี่ยวกับแอป ดังนี้

เพิ่ม Intent.EXTRA_CHOOSER_TARGETS และ Intent.EXTRA_INITIAL_INTENTS ลงใน Intent การแชร์ หลังจาก เรียก Intent.createChooser() ดังนี้

val share = Intent.createChooser(shareIntent, null).apply {
    putExtra(
        Intent.EXTRA_CHOOSER_TARGETS,
        arrayOf(chooserTargetJessica, chooserTargetSpyros)
    )
    putExtra(
        Intent.EXTRA_INITIAL_INTENTS,
        arrayOf(intentTargetNearbyShare, intentTargetMaps)
    )
}

ใช้ฟีเจอร์นี้ด้วยความระมัดระวัง Intent และ ChooserTarget ที่กำหนดเองทุกรายการที่คุณเพิ่มจะลดจำนวนที่ระบบแนะนำ โดยทั่วไปเราไม่แนะนำให้เพิ่มเป้าหมายที่กำหนดเอง ตัวอย่างที่เหมาะสมและพบได้บ่อยในการเพิ่ม Intent.EXTRA_INITIAL_INTENTS คือการระบุการดำเนินการเพิ่มเติมที่ผู้ใช้ทำได้กับเนื้อหาที่แชร์ เช่น ผู้ใช้แชร์รูปภาพและระบบใช้ Intent.EXTRA_INITIAL_INTENTS เพื่อให้ผู้ใช้ส่งลิงก์แทน ตัวอย่างที่เหมาะสมและพบได้บ่อยในการเพิ่ม Intent.EXTRA_CHOOSER_TARGETS คือการแสดงบุคคลหรืออุปกรณ์ที่เกี่ยวข้องซึ่งแอปของคุณมี

ยกเว้นเป้าหมายที่เฉพาะเจาะจงตามคอมโพเนนต์

คุณสามารถยกเว้นเป้าหมายที่เฉพาะเจาะจงได้โดยระบุ Intent.EXTRA_EXCLUDE_COMPONENTS ให้ทำเช่นนี้เพื่อนำเป้าหมายที่คุณควบคุมได้ออกเท่านั้น กรณีการใช้งานที่พบได้บ่อยคือการซ่อนเป้าหมายการแชร์ของแอปเมื่อผู้ใช้แชร์จากภายในแอป เนื่องจากผู้ใช้มีแนวโน้มที่จะแชร์ภายนอกแอป

เพิ่ม Intent.EXTRA_EXCLUDE_COMPONENTS ลงใน Intent หลังจากเรียก Intent.createChooser() ดังนี้

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

รับข้อมูลเกี่ยวกับการแชร์

การทราบว่าผู้ใช้แชร์เมื่อใดและเลือกเป้าหมายใดอาจเป็นประโยชน์ แผ่นแชร์ของ Android ช่วยให้คุณรับข้อมูลนี้ได้โดยระบุ ComponentName ของเป้าหมายที่ผู้ใช้เลือกโดยใช้ IntentSender

ขั้นแรก ให้สร้าง PendingIntent สำหรับ BroadcastReceiver และระบุ IntentSender ใน Intent.createChooser() ดังนี้

fun infoAboutSharing(context: Context, requestCode: Int) {
    var share = Intent(ACTION_SEND)
    // ...
    val pi = PendingIntent.getBroadcast(
        context, requestCode,
        Intent(context, ShareBroadcastReceiver::class.java),
        PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
    )
    share = Intent.createChooser(share, null, pi.intentSender)
    context.startActivity(share)
}

รับการเรียกกลับใน MyBroadcastReceiver และดูใน Intent.EXTRA_CHOOSER_RESULT ดังนี้

override fun onReceive(context: Context?, intent: Intent) {
    val TAG = ShareBroadcastReceiver::class.simpleName
    val chooserResult: ChooserResult? = IntentCompat.getParcelableExtra(
        intent,
        Intent.EXTRA_CHOOSER_RESULT,
        ChooserResult::class.java,
    )
    chooserResult?.let {
        Log.i(TAG,
            "Share callback: isShortcut: ${it.isShortcut}, type: ${typeToString(it.type)}, componentName: ${it.selectedComponent}",
        )
    } ?: Log.i(TAG, "chooserResult is null")
}
ดูข้อมูลเพิ่มเติมได้ที่ตัวอย่างการแชร์แพลตฟอร์ม

เพิ่มการดำเนินการที่กำหนดเองลงในแผ่นแชร์

ใน Android 14 (ระดับ API 34) ขึ้นไป แอปสามารถเพิ่มการดำเนินการที่กำหนดเองลงใน Android Sharesheet ได้ สร้าง ChooserAction ด้วย ChooserAction.Builder. คุณสามารถระบุ PendingIntent เป็นการดำเนินการที่จะเรียกใช้เมื่อมีการคลิกไอคอน สร้างอาร์เรย์ที่มีการดำเนินการที่กำหนดเองทั้งหมดและระบุอาร์เรย์ดังกล่าวเป็น EXTRA_CHOOSER_CUSTOM_ACTIONS ของ Intent การแชร์

fun customActions(context: Context, text: String) {
    val sendIntent = 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_logo),
            "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)
}

ใช้ตัวแก้ไข Intent ของ Android

ภาพหน้าจอของตัวแก้ไข Intent ACTION_SEND

ตัวแก้ไข Intent ของ Android เหมาะที่สุดเมื่อส่งข้อมูลไปยังแอปอื่นซึ่งเป็นส่วนหนึ่งของโฟลว์งานที่กำหนดไว้อย่างชัดเจน

หากต้องการใช้ตัวแก้ไข Intent ของ Android ให้สร้าง Intent และเพิ่มข้อมูลเพิ่มเติมเหมือนกับที่คุณทำเพื่อเรียก Android Sharesheet แต่ อย่า เรียก Intent.createChooser()

หากมีแอปพลิเคชันที่ติดตั้งไว้หลายแอปที่มีตัวกรองที่ตรงกับ ACTION_SEND และประเภท MIME ระบบจะแสดงกล่องโต้ตอบการแยกความกำกวมที่เรียกว่า ตัวแก้ไข Intent ซึ่งช่วยให้ผู้ใช้เลือกเป้าหมายที่จะแชร์ได้ หากมีแอปพลิเคชันเดียวที่ตรงกัน ระบบจะเรียกใช้แอปพลิเคชันนั้น

ตัวอย่างวิธีใช้ตัวแก้ไข Intent ของ Android เพื่อส่งข้อความ

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

ดูข้อมูลเพิ่มเติม

ดูข้อมูลเพิ่มเติมเกี่ยวกับการส่งข้อมูลได้ที่ Intent และตัวกรอง Intent