Memenuhi kasus penggunaan umum sekaligus memiliki visibilitas paket terbatas

Dokumen ini menampilkan beberapa kasus penggunaan umum saat aplikasi berinteraksi dengan aplikasi lain. Setiap bagian memberikan panduan tentang cara menyelesaikan fungsi aplikasi dengan visibilitas paket terbatas, yang harus Anda pertimbangkan jika aplikasi menargetkan Android 11 (level API 30) atau yang lebih tinggi.

Saat aplikasi yang menargetkan Android 11 atau versi yang lebih tinggi menggunakan intent untuk memulai aktivitas di aplikasi lain, pendekatan yang paling mudah adalah memanggil intent dan menangani pengecualian ActivityNotFoundException jika tidak ada aplikasi yang tersedia.

Jika sebagian aplikasi Anda bergantung pada mengetahui apakah panggilan ke startActivity() dapat berhasil, seperti menampilkan UI, tambahkan elemen ke elemen <queries> manifes aplikasi Anda. Biasanya, ini adalah elemen <intent>.

Membuka URL

Bagian ini menjelaskan berbagai cara untuk membuka URL di aplikasi yang menargetkan Android 11 atau yang lebih tinggi.

Membuka URL di browser atau aplikasi lain

Untuk membuka URL, gunakan intent yang berisi tindakan intent ACTION_VIEW, seperti yang dijelaskan dalam panduan untuk memuat URL web. Setelah Anda memanggil startActivity() menggunakan intent ini, salah satu hal berikut akan terjadi:

  • URL akan terbuka di aplikasi browser web.
  • URL akan terbuka di aplikasi yang mendukung URL sebagai deep link.
  • Dialog disambiguasi muncul, yang memungkinkan pengguna memilih aplikasi yang membuka URL.
  • ActivityNotFoundException terjadi karena tidak ada aplikasi yang diinstal di perangkat yang dapat membuka URL. (Ini tidak biasa.)

    Sebaiknya aplikasi Anda menangkap dan menangani ActivityNotFoundException jika terjadi.

Karena metode startActivity() tidak memerlukan visibilitas paket untuk memulai aktivitas aplikasi lain, Anda tidak perlu menambahkan elemen <queries> ke manifes aplikasi atau membuat perubahan pada elemen <queries> yang ada. Hal ini berlaku untuk intent implisit dan eksplisit yang membuka URL.

Memeriksa apakah browser tersedia

Dalam beberapa kasus, aplikasi Anda mungkin ingin memverifikasi bahwa setidaknya ada satu browser yang tersedia di perangkat, atau bahwa browser tertentu adalah browser default, sebelum berupaya membuka URL. Dalam kasus tersebut, sertakan elemen <intent> berikut sebagai bagian dari elemen <queries> dalam manifes Anda:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data android:scheme="https" />
</intent>

Saat Anda memanggil queryIntentActivities() dan meneruskan intent web sebagai argumen, daftar yang ditampilkan akan menyertakan aplikasi browser yang tersedia dalam beberapa kasus. Daftar tersebut tidak menyertakan aplikasi browser jika pengguna secara default telah mengonfigurasi URL agar terbuka di aplikasi non-browser.

Membuka URL di Tab Khusus

Tab Khusus memungkinkan aplikasi menyesuaikan tampilan dan nuansa browser. Anda dapat membuka URL di Tab Khusus tanpa perlu menambahkan atau mengubah elemen <queries> dalam manifes aplikasi.

Namun, Anda mungkin ingin memeriksa apakah perangkat memiliki browser yang mendukung Tab Khusus atau memilih browser tertentu untuk diluncurkan dengan Tab Khusus menggunakan CustomTabsClient.getPackageName(). Dalam kasus tersebut, sertakan elemen <intent> berikut sebagai bagian dari elemen <queries> dalam manifes Anda:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>

Mengizinkan aplikasi non-browser menangani URL

Meskipun aplikasi dapat membuka URL menggunakan Tab Khusus, sebaiknya Anda mengizinkan aplikasi non-browser membuka URL jika memungkinkan. Untuk menyediakan kemampuan ini di aplikasi Anda, coba lakukan panggilan ke startActivity() menggunakan intent yang menetapkan tanda intent FLAG_ACTIVITY_REQUIRE_NON_BROWSER. Jika sistem memunculkan ActivityNotFoundException, aplikasi Anda dapat membuka URL di Tab Khusus.

Jika intent menyertakan tanda ini, panggilan ke startActivity() menyebabkan ActivityNotFoundException ditampilkan saat salah satu kondisi berikut terjadi:

  • Panggilan ini akan meluncurkan aplikasi browser secara langsung.
  • Panggilan tersebut akan menampilkan dialog disambiguasi kepada pengguna dengan satu-satunya opsi adalah aplikasi browser.

Cuplikan kode berikut menunjukkan cara memperbarui logika Anda untuk menggunakan tanda intent FLAG_ACTIVITY_REQUIRE_NON_BROWSER:

Kotlin

try {
    val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
        // The URL should either launch directly in a non-browser app (if it's
        // the default) or in the disambiguation dialog.
        addCategory(CATEGORY_BROWSABLE)
        flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER
    }
    startActivity(intent)
} catch (e: ActivityNotFoundException) {
    // Only browser apps are available, or a browser is the default.
    // So you can open the URL directly in your app, for example in a
    // Custom Tab.
    openInCustomTabs(url)
}

Java

try {
    Intent intent = new Intent(ACTION_VIEW, Uri.parse(url));
    // The URL should either launch directly in a non-browser app (if it's the
    // default) or in the disambiguation dialog.
    intent.addCategory(CATEGORY_BROWSABLE);
    intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER);
    startActivity(intent);
} catch (ActivityNotFoundException e) {
    // Only browser apps are available, or a browser is the default.
    // So you can open the URL directly in your app, for example in a
    // Custom Tab.
    openInCustomTabs(url);
}

Menghindari dialog disambiguisasi

Jika Anda tidak ingin menampilkan dialog disambiguisasi yang mungkin dilihat pengguna saat mereka membuka URL, dan lebih memilih untuk menangani URL sendiri dalam situasi ini, Anda dapat menggunakan intent yang menetapkan tanda intent FLAG_ACTIVITY_REQUIRE_DEFAULT.

Jika intent menyertakan tanda ini, panggilan ke startActivity() akan menyebabkan ActivityNotFoundException ditampilkan saat panggilan itu akan menampilkan dialog disambiguisasi kepada pengguna.

Jika intent menyertakan tanda ini dan tanda intent FLAG_ACTIVITY_REQUIRE_NON_BROWSER, panggilan ke startActivity() menyebabkan ActivityNotFoundException ditampilkan saat salah satu kondisi berikut terjadi:

  • Panggilan ini akan meluncurkan aplikasi browser secara langsung.
  • Panggilan tersebut akan menampilkan dialog disambiguisasi kepada pengguna.

Cuplikan kode berikut menunjukkan cara menggunakan tanda FLAG_ACTIVITY_REQUIRE_NON_BROWSER dan FLAG_ACTIVITY_REQUIRE_DEFAULT secara bersamaan:

Kotlin

val url = URL_TO_LOAD
try {
    // For this intent to be invoked, the system must directly launch a
    // non-browser app.
    val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
        addCategory(CATEGORY_BROWSABLE)
        flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER or
                FLAG_ACTIVITY_REQUIRE_DEFAULT
    }
    startActivity(intent)
} catch (e: ActivityNotFoundException) {
    // This code executes in one of the following cases:
    // 1. Only browser apps can handle the intent.
    // 2. The user has set a browser app as the default app.
    // 3. The user hasn't set any app as the default for handling this URL.
    openInCustomTabs(url)
}

Java

String url = URL_TO_LOAD;
try {
    // For this intent to be invoked, the system must directly launch a
    // non-browser app.
    Intent intent = new Intent(ACTION_VIEW, Uri.parse(url));
    intent.addCategory(CATEGORY_BROWSABLE);
    intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER |
            FLAG_ACTIVITY_REQUIRE_DEFAULT);
    startActivity(intent);
} catch (ActivityNotFoundException e) {
    // This code executes in one of the following cases:
    // 1. Only browser apps can handle the intent.
    // 2. The user has set a browser app as the default app.
    // 3. The user hasn't set any app as the default for handling this URL.
    openInCustomTabs(url);
}

Membuka file

Jika aplikasi Anda menangani file atau lampiran, seperti memeriksa apakah perangkat dapat membuka file tertentu, biasanya paling mudah untuk mencoba memulai aktivitas yang dapat menangani file tersebut. Untuk melakukannya, gunakan intent yang menyertakan tindakan intent ACTION_VIEW dan URI yang merepresentasikan file tertentu. Jika tidak ada aplikasi yang tersedia di perangkat, aplikasi Anda dapat menangkap ActivityNotFoundException. Dalam logika penanganan pengecualian, Anda dapat menampilkan error atau mencoba menangani file sendiri.

Jika aplikasi Anda harus mengetahui terlebih dahulu apakah aplikasi lain dapat membuka file tertentu, sertakan elemen <intent> dalam cuplikan kode berikut sebagai bagian dari elemen <queries> dalam manifes Anda. Sertakan jenis file jika Anda sudah mengetahui jenis file tersebut pada waktu kompilasi.

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.VIEW" />
  <!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". -->
  <data android:mimeType="application/pdf" />
</intent>

Selanjutnya, Anda dapat memeriksa apakah aplikasi tersedia dengan memanggil resolveActivity() menggunakan intent Anda.

Memberikan akses URI

Catatan: Mendeklarasikan izin akses URI seperti yang dijelaskan di bagian ini diperlukan untuk aplikasi yang menargetkan Android 11 (level API 30) atau yang lebih tinggi dan direkomendasikan untuk semua aplikasi, terlepas dari target SDK-nya dan apakah mereka mengekspor penyedia konten mereka atau tidak.

Untuk aplikasi yang menargetkan Android 11 atau versi yang lebih tinggi untuk mengakses URI konten, intent aplikasi Anda harus mendeklarasikanIzin akses URI dengan menetapkan salah satu atau kedua flag intent berikut:FLAG_GRANT_READ_URI_PERMISSION dan FLAG_GRANT_WRITE_URI_PERMISSION.

Pada Android 11 dan yang lebih tinggi, izin akses URI memberikan kemampuan berikut kepada aplikasi yang menerima intent:

  • Membaca dari, atau menulis ke, data yang diwakili URI konten, bergantung pada izin URI yang diberikan.
  • Mendapatkan visibilitas ke dalam aplikasi yang berisi penyedia konten yang cocok dengan otoritas URI. Aplikasi yang berisi penyedia konten mungkin berbeda dari aplikasi yang mengirimkan intent.

Cuplikan kode berikut menunjukkan cara menambahkan tanda intent izin URI sehingga aplikasi lain yang menargetkan Android 11 atau yang lebih tinggi dapat melihat data di URI konten:

Kotlin

val shareIntent = Intent(Intent.ACTION_VIEW).apply {
    flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
    data = CONTENT_URI_TO_SHARE_WITH_OTHER_APP
}

Java

Intent shareIntent = new Intent(Intent.ACTION_VIEW);
shareIntent.setFlags(FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setData(CONTENT_URI_TO_SHARE_WITH_OTHER_APP);

Menghubungkan ke layanan

Jika aplikasi perlu berinteraksi dengan layanan yang tidak otomatis terlihat, Anda dapat mendeklarasikan tindakan intent yang sesuai dalam elemen <queries>. Bagian berikut memberikan contoh penggunaan layanan yang sering diakses.

Menghubungkan ke mesin text-to-speech

Jika aplikasi Anda berinteraksi dengan mesin text-to-speech (TTS), sertakan elemen <intent> berikut sebagai bagian dari elemen <queries> dalam manifes Anda:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.TTS_SERVICE" />
</intent>

Menghubungkan ke layanan pengenalan ucapan

Jika aplikasi berinteraksi dengan layanan pengenalan ucapan, termasuk elemen <intent> berikut sebagai bagian dari elemen <queries> di manifes Anda:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.speech.RecognitionService" />
</intent>

Menghubungkan ke layanan browser media

Jika aplikasi Anda adalah aplikasi browser media klien, sertakan elemen <intent> berikut sebagai bagian dari elemen <queries> dalam manifes Anda:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.media.browse.MediaBrowserService" />
</intent>

Memberikan fungsi kustom

Jika Anda perlu melakukan tindakan yang dapat disesuaikan atau menampilkan informasi yang dapat disesuaikan berdasarkan interaksinya dengan aplikasi lain, Anda dapat menampilkan perilaku kustom tersebut menggunakan tanda tangan filter intent sebagai bagian dari elemen <queries> dalam manifes Anda. Bagian berikut memberikan panduan mendetail untuk beberapa skenario umum.

Kueri untuk aplikasi SMS

Jika aplikasi Anda memerlukan informasi kumpulan aplikasi SMS yang diinstal di perangkat, misalnya untuk memeriksa aplikasi mana yang merupakan pengendali SMS default perangkat, sertakan elemen <intent> berikut sebagai bagian dari elemen <queries> dalam manifes Anda:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.SENDTO"/>
  <data android:scheme="smsto" android:host="*" />
</intent>

Membuat sharesheet kustom

Jika memungkinkan, gunakan sharesheet yang disediakan oleh sistem. Atau, sertakan elemen <intent> berikut sebagai bagian dari elemen <queries> dalam manifes Anda:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.SEND" />
  <!-- Replace with the MIME type that your app works with, if needed. -->
  <data android:mimeType="image/jpeg" />
</intent>

Jika tidak, proses pembuatan sharesheet dalam logika aplikasi Anda, seperti panggilan ke queryIntentActivities(), tidak akan berubah dibandingkan dengan versi Android sebelum Android 11.

Menampilkan tindakan pemilihan teks kustom

Saat pengguna memilih teks di aplikasi Anda, toolbar pemilihan teks menampilkan kumpulan operasi yang mungkin dilakukan pada teks yang dipilih. Jika toolbar ini menampilkan tindakan kustom dari aplikasi lain, sertakan elemen <intent> berikut sebagai bagian dari elemen <queries> dalam manifes Anda:

<!-- Place inside the <queries> element. -->
<intent>
  <action android:name="android.intent.action.PROCESS_TEXT" />
  <data android:mimeType="text/plain" />
</intent>

Menampilkan baris data kustom untuk kontak

Aplikasi dapat menambahkan baris data kustom ke Penyedia Kontak. Agar aplikasi kontak dapat menampilkan data kustom ini, aplikasi harus dapat melakukan hal berikut:

  1. Membaca file contacts.xml dari aplikasi lain.
  2. Memuat ikon yang sesuai dengan jenis MIME kustom.

Jika aplikasi Anda adalah aplikasi kontak, sertakan elemen <intent> berikut sebagai bagian dari elemen <queries> dalam manifes Anda:

<!-- Place inside the <queries> element. -->
<!-- Lets the app read the contacts.xml file from other apps. -->
<intent>
  <action android:name="android.accounts.AccountAuthenticator" />
</intent>
<!-- Lets the app load an icon corresponding to the custom MIME type. -->
<intent>
  <action android:name="android.intent.action.VIEW" />
  <data android:scheme="content" android:host="com.android.contacts"
        android:mimeType="vnd.android.cursor.item/*" />
</intent>