Google berkomitmen untuk mendorong terwujudnya keadilan rasial bagi komunitas Kulit Hitam. Lihat caranya.

Kasus penggunaan untuk visibilitas paket di Android 11

Dokumen ini memberikan beberapa contoh kasus penggunaan umum saat aplikasi berinteraksi dengan aplikasi lain. Setiap bagian menyediakan panduan tentang cara mengupdate aplikasi agar kompatibel dengan perubahan perilaku visibilitas paket yang terjadi di Android 11.

Saat aplikasi Anda menargetkan Android 11 dan menggunakan intent implisit untuk memulai aktivitas di aplikasi lain, pendekatan yang paling mudah adalah memanggil intent tersebut dan menangani pengecualian ActivityNotFoundException jika tidak ada aplikasi.

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

Membuka URL

Bagian ini menjelaskan cara membuka URL di aplikasi yang menargetkan Android 11. Ikuti salah satu contoh dalam subbagian berikut, bergantung pada cara aplikasi Anda membuka URL.

Membuka URL di browser atau aplikasi lain

Untuk membuka URL, gunakan intent yang berisi tindakan intent ACTION_VIEW, seperti yang dijelaskan di bagian tentang cara 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 disambiguisasi muncul, yang memungkinkan pengguna memilih aplikasi mana 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 aplikasi Anda menggunakan intent implisit untuk membuka URL, Anda tidak perlu menambahkan elemen <queries> ke manifes aplikasi.

Periksa 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 hal ini, 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>

Kemudian, saat Anda memanggil queryIntentActivities() dan meneruskan intent web sebagai argumen, daftar yang ditampilkan akan menyertakan aplikasi browser yang tersedia.

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 Anda dapat membuka URL menggunakan Tab Khusus, sebaiknya Anda mengizinkan aplikasi non-browser untuk membuka URL tertentu 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 disambiguisasi kepada pengguna, ketika 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 {
    // In order 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 {
    // In order 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.

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 sebelumnya.

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 browser media

Di 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>

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. -->
<!-- Allows the app to read the "contacts.xml" file from the other apps. -->
<intent>
  <action android:name="android.accounts.AccountAuthenticator" />
</intent>
<!-- Allows the app to 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>

Mendeklarasikan kebutuhan visibilitas paket dalam library

Jika Anda mengembangkan library Android, Anda dapat mendeklarasikan kebutuhan visibilitas paket dengan menambahkan elemen <queries> di file manifes AAR. Elemen <queries> ini memiliki fungsionalitas yang sama seperti elemen yang dapat dideklarasikan oleh aplikasi dalam manifesnya sendiri.

Jika library Anda melibatkan komunikasi dengan aplikasi "host", seperti menggunakan layanan terikat, sertakan elemen <package> yang menentukan nama paket aplikasi host:

<!-- Place inside the <queries> element. -->
<package android:name=PACKAGE_NAME />

Dengan menyertakan deklarasi ini, Anda dapat memeriksa apakah aplikasi host sudah diinstal dan berinteraksi dengannya, misalnya dengan memanggil bindService(). Aplikasi pemanggil yang menggunakan library Anda otomatis dapat dilihat oleh aplikasi host sebagai hasil dari interaksi ini.