Menerima data sederhana dari aplikasi lain

Selain dapat mengirim, aplikasi Anda juga dapat menerima data dari aplikasi lain. Pikirkan bagaimana pengguna berinteraksi dengan aplikasi Anda dan jenis data apa yang ingin Anda terima dari aplikasi lain. Misalnya, aplikasi jaringan sosial mungkin tertarik untuk menerima konten teks, seperti URL web yang menarik, dari aplikasi lain.

Pengguna akan sering mengirim data ke aplikasi Anda melalui Android ShareSheet atau resolver intent. Semua data yang diterima memiliki jenis MIME yang ditetapkan oleh aplikasi penyedia. Ada tiga cara bagi aplikasi Anda untuk menerima data yang dikirim oleh aplikasi lain:

  • Activity dengan tag intent-filter yang cocok di manifes
  • Satu atau beberapa objek ChooserTarget yang ditampilkan oleh ChooserTargetService Anda
  • Sharing Shortcut yang dipublikasikan oleh aplikasi Anda. Ini menggantikan objek ChooserTarget. Sharing Shortcut hanya tersedia jika aplikasi Anda menjalankan Android 10 (API level 29).

Objek Sharing Shortcuts dan ChooserTarget adalah deep link Direct Share ke dalam Activity spesifik dalam aplikasi Anda. Objek tersebut sering merepresentasikan seseorang, dan Android Sharesheet menunjukkannya. Contoh, aplikasi pesan dapat menyediakan Sharing Shortcut untuk orang yang memiliki deep link langsung ke percakapan dengan orang tersebut.

Mendukung jenis MIME

Aplikasi Anda harus bisa menerima sebanyak mungkin jenis MIME. Misalnya, aplikasi pesan yang digunakan untuk mengirim teks, gambar, dan video harus mendukung penerimaan text/*, image/*, dan video/*. Berikut ini beberapa jenis MIME yang umum saat mengirim data sederhana di Android.

  • text/*, pengirim akan sering mengirim text/plain, text/rtf, text/html, text/json
  • image/*, pengirim akan sering mengirim image/jpg, image/png, image/gif
  • video/*, pengirim akan sering mengirim video/mp4, video/3gp
  • penerima harus mendaftar untuk ekstensi file yang didukung, pengirim akan sering mengirim application/pdf

Lihat registry resmi IANA untuk jenis media MIME. Anda dapat menerima jenis MIME */*, tetapi hal ini sangat tidak dianjurkan kecuali jika Anda mampu menangani setiap jenis konten yang masuk.

Membuat target berbagi yang baik

Saat pengguna mengetuk target berbagi yang terkait dengan aktivitas tertentu, mereka harus dapat mengonfirmasi dan mengedit konten yang dibagikan itu sebelum menggunakannya. Hal ini sangat penting untuk data teks.

Mengetuk sembarang target Direct Share harus mengarahkan pengguna ke antarmuka di mana tindakan dapat dijalankan langsung pada subjek target. Hindari menunjukkan dialog disambiguitas kepada pengguna atau menempatkan mereka pada antarmuka yang tidak terkait dengan target yang diketuk. Secara khusus, jangan arahkan pengguna ke antarmuka disambiguitas kontak yang mengharuskan mereka mengonfirmasi atau memilih kembali kontak yang akan diajak berbagi, karena mereka sudah melakukan itu dengan mengetuk target di Android ShareSheet. Misalnya, dalam aplikasi pesan, mengetuk target Direct Share harus mengarahkan pengguna ke tampilan percakapan dengan orang yang dipilihnya. Keyboard harus terlihat dan pesan harus terisi sebelumnya dengan data yang dibagikan.

Menerima data dengan aktivitas

Mengupdate manifes Anda

Filter intent memberi tahu sistem intent apa saja yang dapat diterima oleh sebuah komponen aplikasi. Serupa dengan saat Anda membuat intent dengan tindakan ACTION_SEND dalam tutorial Mengirimkan Data Sederhana ke Aplikasi Lain, Anda membuat filter intent agar dapat menerima intent dengan tindakan ini. Anda menentukan filter intent dalam manifes, menggunakan elemen <intent-filter>. Misalnya, jika aplikasi Anda menangani penerimaan konten teks, satu image dengan jenis apa pun, atau banyak image dengan jenis apa pun, manifes Anda akan terlihat seperti ini:

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

Saat aplikasi lain mencoba berbagi konten berikut ini dengan membuat intent dan meneruskannya ke startActivity(), aplikasi Anda akan tercantum sebagai opsi dalam Android Sharesheet atau resolver intent. Jika pengguna memilih aplikasi Anda, aktivitas yang terkait (.ui.MyActivity dalam contoh di atas) akan dimulai. Selanjutnya, Andalah yang harus menangani konten tersebut dengan benar dalam kode dan UI Anda.

Catatan: Untuk informasi selengkapnya tentang filter intent dan resolusi intent, baca Intent dan Filter Intent

Menangani konten yang masuk

Untuk menangani konten yang dikirim oleh Intent, panggil getIntent() untuk mendapatkan objek Intent. Setelah mendapatkan objek ini, Anda dapat memeriksa isinya untuk menentukan langkah selanjutnya. Selalu ingat bahwa jika aktivitas ini dapat dimulai dari bagian lain pada sistem, misalnya peluncur, maka Anda perlu mempertimbangkan hal ini saat memeriksa intent tersebut.

Harap berhati-hati saat memeriksa data yang masuk, Anda tidak mengetahui data apa yang dikirim oleh aplikasi lain. Misalnya, jenis MIME yang ditetapkan mungkin salah, atau gambar yang dikirim mungkin sangat besar. Juga ingat untuk memproses data biner dalam thread tersendiri, bukan di thread utama ("UI").

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    when {
        intent?.action == Intent.ACTION_SEND -> {
            if ("text/plain" == intent.type) {
                handleSendText(intent) // Handle text being sent
            } else if (intent.type?.startsWith("image/") == true) {
                handleSendImage(intent) // Handle single image being sent
            }
        }
        intent?.action == Intent.ACTION_SEND_MULTIPLE
                && intent.type?.startsWith("image/") == true -> {
                handleSendMultipleImages(intent) // Handle multiple images being sent
        }
        else -> {
            // Handle other intents, such as being started from the home screen
        }
    }
    ...
}

private fun handleSendText(intent: Intent) {
    intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
        // Update UI to reflect text being shared
    }
}

private fun handleSendImage(intent: Intent) {
    (intent.getParcelableExtra<Parcelable>(Intent.EXTRA_STREAM) as? Uri)?.let {
        // Update UI to reflect image being shared
    }
}

private fun handleSendMultipleImages(intent: Intent) {
    intent.getParcelableArrayListExtra<Parcelable>(Intent.EXTRA_STREAM)?.let {
        // Update UI to reflect multiple images being shared
    }
}

Java

void onCreate (Bundle savedInstanceState) {
    ...
    // Get intent, action and MIME type
    Intent intent = getIntent();
    String action = intent.getAction();
    String type = intent.getType();

    if (Intent.ACTION_SEND.equals(action) && type != null) {
        if ("text/plain".equals(type)) {
            handleSendText(intent); // Handle text being sent
        } else if (type.startsWith("image/")) {
            handleSendImage(intent); // Handle single image being sent
        }
    } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
        if (type.startsWith("image/")) {
            handleSendMultipleImages(intent); // Handle multiple images being sent
        }
    } else {
        // Handle other intents, such as being started from the home screen
    }
    ...
}

void handleSendText(Intent intent) {
    String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
    if (sharedText != null) {
        // Update UI to reflect text being shared
    }
}

void handleSendImage(Intent intent) {
    Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
    if (imageUri != null) {
        // Update UI to reflect image being shared
    }
}

void handleSendMultipleImages(Intent intent) {
    ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
    if (imageUris != null) {
        // Update UI to reflect multiple images being shared
    }
}

Mengupdate UI setelah menerima data dapat sesederhana mengisi EditText, atau lebih rumit seperti menerapkan filter foto yang menarik ke sebuah gambar. Aplikasi Anda dapat memilih tindakan apa yang akan dilakukan selanjutnya.

Memastikan pengguna mengenali aplikasi Anda

Aplikasi Anda direpresentasikan oleh ikon dan label di Android ShareSheet dan resolver intent. Keduanya didefinisikan dalam manifes. Anda dapat menetapkan label aktivitas atau filter intent untuk memberikan lebih banyak konteks.

Pada Android 10 (API level 29), Android Sharesheet hanya akan menggunakan ikon yang ditetapkan dalam manifes pada tag application Anda. Ikon yang ditetapkan pada tag intent-filter dan activity akan diabaikan.

Catatan: Target berbagi terbaik tidak memerlukan label dan ikon pada aktivitas atau filter intent terkaitnya. Nama dan ikon aplikasi penerima saja sudah cukup bagi pengguna untuk memahami apa yang terjadi ketika berbagi.

Menyediakan target Direct Share

Direct Share diperkenalkan di Android 6.0 (API level 23) yang memungkinkan aplikasi menyediakan objek ChooserTarget melalui ChooserTargetService. Hasil diambil secara reaktif berdasarkan permintaan, yang berakibat pada waktu pemuatan target yang lambat.

Di Android 10 (API level 29), ChooserTargetService Direct Share API diganti dengan Sharing Shortcuts API yang baru. Sharing Shortcuts API memungkinkan aplikasi memublikasikan target direct share lebih awal, bukan mengambil hasil secara reaktif sesuai permintaan. Mekanisme ChooserTargetService Direct Share akan tetap berfungsi, tetapi target yang disediakan dengan cara ini akan diberi peringkat yang lebih rendah daripada target yang menggunakan Sharing Shortcuts API.

ShortcutManagerCompat adalah AndroidX API yang menyediakan Sharing Shortcut yang memiliki kompatibilitas mundur dengan ChooserTargetService DirectShare API yang lama. Ini adalah cara yang lebih sering digunakan untuk memublikasikan Sharing Shortcut dan ChooserTargets. Lihat petunjuk di bawah.

Memublikasikan target Direct Share

Anda hanya dapat menggunakan pintasan dinamis untuk memublikasikan target Direct Share. Ikuti langkah berikut untuk memublikasikan target direct share menggunakan API baru:

  1. Deklarasikan elemen target berbagi dalam file resource XML aplikasi. Untuk selengkapnya, lihat Deklarasikan target berbagi di bawah ini.
  2. Publikasikan pintasan dinamis beserta kategori yang cocok ke target berbagi yang dideklarasikan. Pintasan dapat ditambahkan, diakses, diperbarui, dan dihapus menggunakan ShortcutManager atau ShortcutManagerCompat di AndroidX. Penggunaan library kompatibilitas di AndroidX merupakan metode yang lebih baik karena menyediakan kompatibilitas mundur pada versi Android lama.

Sharing Shortcuts API

ShortcutInfo.Builder mencakup metode baru dan disempurnakan yang memberikan info tambahan tentang target berbagi:

setCategories()
Ini bukan metode baru, tetapi sekarang kategori baru juga digunakan untuk memfilter pintasan yang dapat menangani tindakan atau intent berbagi. Lihat Mendeklarasikan target berbagi untuk penjelasan selengkapnya. Kolom ini wajib ada untuk pintasan yang ingin digunakan sebagai target berbagi.
setLongLived()

Menentukan apakah pintasan valid atau tidak setelah pintasan tersebut batal dipublikasikan atau dibuat tidak terlihat oleh aplikasi (sebagai pintasan dinamis atau pintasan yang dipasangi pin). Pintasan yang sudah lama dapat dimasukkan ke dalam cache oleh berbagai layanan sistem, bahkan setelah pintasan tersebut tidak dipublikasikan sebagai pintasan dinamis.

Membuat pintasan bertahan lama dapat meningkatkan peringkatnya. Lihat Mendapatkan peringkat terbaik untuk mengetahui penjelasan selengkapnya.

setPerson(), setPersons()

Mengaitkan satu atau beberapa objek Person dengan pintasan. Cara ini dapat digunakan untuk memahami perilaku pengguna di berbagai aplikasi dengan lebih baik, dan membantu layanan prediksi potensial pada framework untuk memberikan saran yang lebih baik di ShareSheet. Penambahan info Person ke pintasan bersifat opsional, tetapi sangat direkomendasikan jika target berbagi dapat dikaitkan dengan orang. Perhatikan bahwa beberapa target berbagi, seperti cloud, tidak dapat dikaitkan dengan orang.

Menyertakan objek Person tertentu dengan kunci unik dalam target berbagi dan notifikasi terkait dapat meningkatkan peringkatnya. Lihat Mendapatkan peringkat terbaik untuk mengetahui penjelasan selengkapnya.

Untuk aplikasi pesan biasa, pintasan terpisah harus dipublikasikan untuk setiap kontak, dan kolom Person harus berisi info kontak. Jika target dapat dikaitkan dengan beberapa orang (seperti chat grup), tambahkan beberapa objek Person ke satu target berbagi.

Saat memublikasikan pintasan ke seseorang, sertakan nama lengkapnya di setLongLabel() dan nama pendek apa pun, misalnya nama panggilan atau nama depan, di setShortLabel()

Untuk contoh publikasi Sharing Shortcut, lihat Contoh kode Sharing Shortcut.

Mendapatkan peringkat terbaik

Android ShareSheet menunjukkan jumlah pasti target Direct Share. Saran ini diurutkan berdasarkan peringkat. Anda dapat meningkatkan peringkat pintasan dengan melakukan langkah berikut:

  • Pastikan semua shortcutId unik dan tidak pernah digunakan kembali untuk target berbeda.
  • Pastikan pintasan bertahan lama dengan memanggil setLongLived(true).
  • Berikan peringkat yang dapat digunakan untuk membandingkan pintasan dari aplikasi Anda jika data pelatihan tidak ada. Lihat setRank(). Peringkat yang lebih rendah menunjukkan pintasan yang lebih penting.

Untuk memperbaiki peringkat lebih lanjut, aplikasi sosial sebaiknya melakukan semua saran di atas dan:

  • Menyediakan objek Person yang relevan dengan set kunci di pintasan Anda, lihat setPerson(), setPersons(), dan setKey()
  • Menautkan pintasan Anda ke notifikasi yang relevan dari orang yang sama atau beberapa orang, lihat setShortcutId().. ShortcutId mungkin disetel untuk semua pintasan yang sebelumnya dipublikasikan dengan setLongLived(true).

Untuk memperbaiki peringkat secara maksimal, aplikasi sosial dapat melakukan semua saran di atas dan:

  • Dalam objek Person yang disediakan, memasukkan URI valid ke kontak terkait di perangkat, lihat setUri()

Berikut ini contoh pintasan dengan semua potensi perbaikan peringkat.

Kotlin

val person = Person.Builder()
  ...
  .setName(fullName)
  .setKey(staticPersonIdentifier)
  .setUri("tel:$phoneNumber") // alternatively "mailto:$email" or CONTENT_LOOKUP_URI
  .build()

val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticPersonIdentifier)
  ...
  .setShortLabel(firstName)
  .setLongLabel(fullName)
  .setPerson(person)
  .setLongLived(true)
  .setRank(personRank)
  .build()

Java

Person person = Person.Builder()
  ...
  .setName(fullName)
  .setKey(staticPersonIdentifier)
  .setUri("tel:"+phoneNumber) // alternatively "mailto:"+email or CONTENT_LOOKUP_URI
  .build();

ShortcutInfoCompat shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticPersonIdentifier)
  ...
  .setShortLabel(firstName)
  .setLongLabel(fullName)
  .setPerson(person)
  .setLongLived(true)
  .setRank(personRank)
  .build();

Kotlin

val notif = NotificationCompat.Builder(myContext, channelId)
  ...
  .setShortcutId(staticPersonIdentifier)
  .build()

Java

Notification notif = NotificationCompat.Builder(myContext, channelId)
  ...
  .setShortcutId(staticPersonIdentifier)
  .build();

Menyediakan gambar pintasan

Untuk membuat Sharing Shortcut, Anda harus menambahkan gambar melalui setIcon().

Sharing Shortcut dapat muncul di berbagai permukaan sistem dan dapat dibentuk ulang. Untuk memastikan pintasan Anda terlihat sebagaimana mestinya, sediakan bitmap adaptif melalui IconCompat.createWithAdaptiveBitmap().

Bitmap adaptif harus mengikuti panduan dan dimensi yang sama dengan yang ditetapkan untuk ikon adaptif. Cara paling umum untuk mencapai hal ini adalah dengan menskalakan bitmap persegi yang dimaksudkan ke 72x72 dp di tengah-tengah kanvas transparan 108x108 dp.

Jangan berikan gambar yang diberi mask sesuai dengan bentuk tertentu. Misalnya, sebelum Android 10 (API level 29), umumnya Anda dapat memberikan avatar pengguna untuk Direct Share ChooserTarget yang diberi mask sehingga berbentuk lingkaran. Android ShareSheet dan permukaan sistem lainnya di Android 10 sekarang dapat mengatur bentuk dan tema gambar pintasan. Metode yang dipilih untuk menyediakan Sharing Shortcut, melalui ShortcutManagerCompat, akan otomatis mengatur ChooserTarget Direct Share dengan kompatibilitas mundur agar berbentuk lingkaran untuk Anda.

Mendeklarasikan target berbagi

Target berbagi harus dideklarasikan dalam file resource aplikasi, sama seperti definisi pintasan statis. Tambahkan definisi target berbagi di dalam elemen root <shortcuts> dalam file resource, bersama dengan definisi pintasan statis lainnya. Setiap elemen <share-targets> berisi informasi tentang jenis data yang dibagikan, kategori yang cocok, dan class target yang akan menangani intent berbagi. Kode XML-nya terlihat seperti ini:

<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
  <share-target android:targetClass="com.example.android.sharingshortcuts.SendMessageActivity">
    <data android:mimeType="text/plain" />
    <category android:name="com.example.android.sharingshortcuts.category.TEXT_SHARE_TARGET" />
  </share-target>
</shortcuts>

Elemen data dalam target berbagi mirip dengan spesifikasi data dalam filter intent. Setiap target berbagi dapat memiliki beberapa kategori, yang hanya digunakan untuk mencocokkan pintasan aplikasi yang dipublikasikan dengan definisi target berbaginya. Kategori dapat memiliki sembarang nilai yang ditentukan aplikasi.

Jika pengguna memilih Sharing Shortcut di Android ShareSheet yang cocok dengan contoh target berbagi di atas, aplikasi akan mendapatkan intent berbagi berikut:

Action: Intent.ACTION_SEND
ComponentName: {com.example.android.sharingshortcuts /
                com.example.android.sharingshortcuts.SendMessageActivity}
Data: Uri to the shared content
EXTRA_SHORTCUT_ID: <ID of the selected shortcut>

Jika pengguna membuka target berbagi dari pintasan peluncur, aplikasi akan mendapatkan intent yang telah dibuat saat menambahkan pintasan berbagi ke ShortcutManagerCompat. Karena intent berbeda, Intent.EXTRA_SHORTCUT_ID tidak akan tersedia, dan Anda harus meneruskan ID secara manual jika memerlukannya.

Menggunakan AndroidX untuk menyediakan Sharing Shortcut dan ChooserTargets

Agar dapat digunakan dengan library kompatibilitas AndroidX, manifes aplikasi harus memuat set filter intent dan layanan target pemilih metadata. Lihat ChooserTargetService Direct Share API saat ini.

Layanan ini sudah dideklarasikan dalam library kompatibilitas, sehingga pengguna tidak perlu mendeklarasikan layanan tersebut dalam manifes aplikasi. Namun, link dari aktivitas berbagi ke layanan ini harus dianggap sebagai sebuah penyedia target pemilih (chooser target provider).

Pada contoh berikut, implementasi ChooserTargetService adalah androidx.core.content.pm.ChooserTargetServiceCompat, yang telah didefinisikan di AndroidX:

<activity
    android:name=".SendMessageActivity"
    android:label="@string/app_name"
    android:theme="@style/SharingShortcutsDialogTheme">
    <!-- This activity can respond to Intents of type SEND -->
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
    <!-- Only needed if you import the sharetarget AndroidX library that
         provides backwards compatibility with the old DirectShare API.
         The activity that receives the Sharing Shortcut intent needs to be
         taken into account with this chooser target provider. -->
    <meta-data
        android:name="android.service.chooser.chooser_target_service"
        android:value="androidx.sharetarget.ChooserTargetServiceCompat" />
</activity>

FAQ Sharing Shortcut

Apa perbedaan utama antara Sharing Shortcuts API saat ini dan ChooserTargetService Direct Share API lama?

Sharing Shortcuts API menggunakan model push, dibandingkan dengan model pull yang digunakan di Direct Share API lama. Hal ini membuat proses pengambilan target direct share jauh lebih cepat saat menyiapkan ShareSheet. Dari sudut pandang developer aplikasi, jika API baru digunakan, aplikasi perlu menyediakan daftar target direct share di awal, dan kemungkinan harus memperbarui daftar pintasan setiap kali status internal aplikasi berubah (misalnya, jika kontak baru ditambahkan ke aplikasi pesan).

Apa yang terjadi jika saya tidak berpindah untuk menggunakan Sharing Shortcuts API?

Pada Android 10 (API level 29) dan yang lebih baru, Android ShareSheet akan memberikan prioritas yang lebih tinggi pada target berbagi yang disediakan melalui ShortcutManager menggunakan Sharing Shortcuts API. Akibatnya, target berbagi yang telah Anda publikasikan mungkin akan tertimpa oleh target berbagi aplikasi lain dan berpotensi tidak pernah muncul saat berbagi.

Bolehkah saya menggunakan ChooserTargetService dan Sharing Shortcuts DirectShare API di aplikasi saya untuk kompatibilitas mundur?

Jangan lakukan itu! Sebaliknya, gunakan ShortcutManagerCompat API support library yang disediakan. Menggabungkan kedua set API ini dapat mengakibatkan perilaku yang tidak diinginkan/tidak terduga saat mengambil target berbagi.

Apa perbedaan antara pintasan yang dipublikasikan untuk target berbagi dengan pintasan peluncur (penggunaan umum pintasan saat ikon aplikasi pada peluncur ditekan lama)?

Semua pintasan yang dipublikasikan untuk keperluan "target berbagi" juga merupakan pintasan peluncur, dan akan ditampilkan pada menu ketika ikon aplikasi ditekan lama. Batas jumlah pintasan maksimum per aktivitas juga berlaku untuk jumlah total pintasan yang dipublikasikan aplikasi (gabungan pintasan peluncur lama dan target berbagi).