Meminta izin runtime

Setiap aplikasi Android berjalan dalam sandbox dengan akses terbatas. Jika aplikasi perlu menggunakan resource atau informasi di luar sandbox-nya sendiri, Anda dapat mendeklarasikan izin runtime dan menyiapkan permintaan izin yang menyediakan akses ini. Langkah-langkah ini adalah bagian dari alur kerja untuk menggunakan izin.

Jika Anda mendeklarasikan izin berbahaya dan jika aplikasi diinstal pada perangkat yang menjalankan Android 6.0 (API level 23) atau yang lebih tinggi, Anda harus meminta izin berbahaya saat runtime dengan mengikuti langkah-langkah dalam panduan ini.

Jika Anda tidak mendeklarasikan izin berbahaya, atau jika aplikasi diinstal di perangkat yang menjalankan Android 5.1 (API level 22) atau lebih rendah, izin akan diberikan secara otomatis, dan Anda tidak perlu menyelesaikan langkah-langkah lainnya di halaman ini.

Prinsip dasar

Prinsip dasar untuk meminta izin saat runtime adalah sebagai berikut:

  • Minta izin dalam konteks, saat pengguna mulai berinteraksi dengan fitur yang memerlukan izin.
  • Jangan blokir pengguna. Selalu berikan opsi untuk membatalkan alur UI edukatif, seperti alur yang menjelaskan alasan untuk meminta izin.
  • Jika pengguna menolak atau mencabut izin yang diperlukan suatu fitur, turunkan versi aplikasi Anda dengan baik sehingga pengguna dapat terus menggunakan aplikasi Anda, mungkin bisa dilakukan dengan menonaktifkan fitur yang memerlukan izin tersebut.
  • Jangan asumsikan perilaku sistem apa pun. Misalnya, jangan berasumsi bahwa izin muncul dalam grup izin yang sama. Grup izin hanya membantu sistem meminimalkan jumlah dialog sistem yang ditampilkan kepada pengguna saat aplikasi meminta izin yang terkait erat.

Alur kerja untuk meminta izin

Sebelum mendeklarasikan dan meminta izin runtime di aplikasi, evaluasi apakah aplikasi Anda perlu melakukannya. Anda dapat memenuhi banyak kasus penggunaan di aplikasi, seperti mengambil foto, menjeda pemutaran media, dan menampilkan iklan yang relevan, tanpa perlu mendeklarasikan izin apa pun.

Jika Anda menyimpulkan bahwa aplikasi perlu mendeklarasikan dan meminta izin runtime, selesaikan langkah-langkah berikut:

  1. Dalam file manifes aplikasi, deklarasikan izin yang mungkin perlu diminta aplikasi Anda.
  2. Rancang UX aplikasi Anda agar tindakan tertentu dalam aplikasi dikaitkan dengan izin runtime tertentu. Beri tahu pengguna tindakan yang mungkin mengharuskan mereka memberikan izin bagi aplikasi Anda untuk mengakses data pribadi pengguna.
  3. Tunggu pengguna untuk memanggil tugas atau tindakan di aplikasi Anda yang memerlukan akses ke data pribadi pengguna tertentu. Pada saat itu, aplikasi Anda dapat meminta izin runtime yang diperlukan untuk mengakses data tersebut.
  4. Periksa apakah pengguna telah memberikan izin runtime yang diperlukan aplikasi Anda. Jika telah ada, aplikasi Anda dapat mengakses data pribadi pengguna. Jika belum, lanjutkan ke langkah berikutnya.

    Anda harus memeriksa apakah Anda memiliki izin tersebut setiap kali melakukan operasi yang memerlukan izin tersebut.

  5. Periksa apakah aplikasi Anda harus menampilkan alasan kepada pengguna, yang menjelaskan alasan pengguna harus memberikan izin runtime tertentu untuk aplikasi Anda. Jika sistem menentukan bahwa aplikasi Anda seharusnya tidak menampilkan alasan, lanjutkan langsung ke langkah berikutnya, tanpa menampilkan elemen UI.

    Namun, jika sistem menentukan bahwa aplikasi Anda harus menampilkan alasan, tampilkan alasan kepada pengguna dalam elemen UI. Dalam alasan ini, uraikan dengan jelas data yang dicoba diakses oleh aplikasi Anda, dan manfaat yang dapat aplikasi berikan kepada pengguna jika mereka memberikan izin runtime. Setelah pengguna mengonfirmasi alasannya, lanjutkan ke langkah berikutnya.

  6. Minta izin runtime yang diperlukan aplikasi Anda untuk mengakses data pribadi pengguna. Sistem menampilkan permintaan izin runtime, seperti yang ditampilkan pada halaman ringkasan izin.

  7. Periksa respons pengguna—apakah mereka memilih untuk memberikan atau menolak izin runtime.

  8. Jika pengguna memberikan izin untuk aplikasi, Anda dapat mengakses data pribadi pengguna. Jika pengguna menolak izin, turunkan pengalaman aplikasi Anda secara halus agar aplikasi menyediakan fungsi bagi pengguna, tanpa informasi yang dilindungi oleh izin tersebut.

Gambar 1 menggambarkan alur kerja dan kumpulan keputusan terkait proses ini:

Gambar 1. Diagram yang menunjukkan alur kerja untuk mendeklarasikan dan meminta izin runtime di Android.

Menentukan apakah aplikasi sudah diberi izin

Untuk memastikan apakah pengguna sudah memberikan izin tertentu untuk aplikasi Anda, teruskan izin tersebut ke metode ContextCompat.checkSelfPermission(). Metode ini menampilkan PERMISSION_GRANTED atau PERMISSION_DENIED, tergantung apakah aplikasi Anda memiliki izin atau tidak.

Menjelaskan alasan aplikasi memerlukan izin

Dialog izin yang ditampilkan oleh sistem ketika Anda memanggil requestPermissions() menunjukkan jenis izin yang diperlukan aplikasi, tetapi tidak menyebutkan alasannya. Pada beberapa kasus, hal ini mungkin membingungkan pengguna. Sebaiknya jelaskan kepada pengguna alasan aplikasi Anda memerlukan izin sebelum memanggil requestPermissions().

Penelitian menunjukkan bahwa pengguna jauh lebih nyaman dengan permintaan izin jika mereka tahu alasan aplikasi membutuhkannya, seperti apakah izin diperlukan untuk mendukung fitur inti aplikasi atau untuk iklan. Akibatnya, jika Anda hanya menggunakan sebagian kecil panggilan API yang termasuk dalam sebuah grup izin, sebaiknya cantumkan secara eksplisit manakah dari izin tersebut yang Anda gunakan, dan apa alasannya. Misalnya, jika Anda hanya menggunakan lokasi sementara, beritahukan hal ini kepada pengguna dalam deskripsi aplikasi atau artikel bantuan aplikasi Anda.

Dalam kondisi tertentu, ada baiknya juga memberi tahu pengguna tentang akses data sensitif secara real time. Misalnya, jika Anda mengakses kamera atau mikrofon, sebaiknya beri tahu pengguna melalui ikon notifikasi di suatu tempat dalam aplikasi Anda, atau dalam tray notifikasi (jika aplikasi berjalan di latar belakang), sehingga tidak tampak seperti Anda mengumpulkan data secara diam-diam.

Bagian terakhir, jika Anda perlu meminta izin agar sesuatu dalam aplikasi Anda dapat berjalan tetapi alasannya tidak jelas bagi pengguna, temukan cara agar pengguna memahami mengapa Anda memerlukan izin paling sensitif tersebut.

Jika metode ContextCompat.checkSelfPermission() menampilkan PERMISSION_DENIED, panggil shouldShowRequestPermissionRationale(). Jika metode ini menampilkan true, tampilkan UI edukasi kepada pengguna. Pada UI ini, jelaskan alasan fitur yang ingin diaktifkan pengguna memerlukan izin tertentu.

Selain itu, jika aplikasi Anda meminta izin terkait lokasi, mikrofon, atau kamera, pertimbangkan penjelasan mengapa aplikasi Anda memerlukan akses untuk informasi ini.

Meminta izin

Setelah pengguna melihat UI edukasi, atau nilai hasil shouldShowRequestPermissionRationale() menunjukkan bahwa Anda tidak perlu menampilkan UI edukasi, minta izin. Pengguna akan melihat dialog izin sistem, ketika mereka dapat memilih apakah akan memberikan izin tertentu ke aplikasi Anda atau tidak.

Untuk melakukannya, gunakan kontrak RequestPermission, yang disertakan dalam library AndroidX, tempat Anda mengizinkan sistem mengelola kode permintaan izin untuk Anda. Karena menggunakan kontrak RequestPermission akan menyederhanakan logika Anda, solusi ini direkomendasikan jika memungkinkan. Namun, jika diperlukan, Anda juga dapat mengelola sendiri kode permintaan sebagai bagian dari permintaan izin dan menyertakan kode permintaan ini dalam logika callback izin Anda.

Mengizinkan sistem mengelola kode permintaan izin

Untuk mengizinkan sistem mengelola kode permintaan yang terkait dengan permintaan izin, tambahkan dependensi pada library berikut di file build.gradle modul Anda:

Kemudian, Anda dapat menggunakan salah satu class berikut:

Langkah-langkah berikut menunjukkan cara menggunakan kontrak RequestPermission. Prosesnya hampir sama untuk kontrak RequestMultiplePermissions.

  1. Dalam logika inisialisasi aktivitas atau fragmen, teruskan implementasi ActivityResultCallback ke dalam panggilan ke registerForActivityResult(). ActivityResultCallback menentukan cara aplikasi Anda menangani respons pengguna terhadap permintaan izin.

    Simpan referensi ke nilai hasil registerForActivityResult(), yang berjenis ActivityResultLauncher.

  2. Untuk menampilkan dialog izin sistem saat diperlukan, panggil metode launch() pada instance ActivityResultLauncher yang Anda simpan pada langkah sebelumnya.

    Setelah launch() dipanggil, dialog izin sistem akan muncul. Saat pengguna menentukan pilihan, sistem akan memanggil implementasi ActivityResultCallback secara asinkron, yang telah Anda tentukan pada langkah sebelumnya.

    Catatan: Aplikasi Anda tidak dapat menyesuaikan dialog yang muncul saat Anda memanggil launch(). Untuk memberikan lebih banyak informasi atau konteks kepada pengguna, ubah UI aplikasi Anda agar lebih mudah bagi pengguna untuk memahami alasan fitur dalam aplikasi Anda memerlukan izin tertentu. Misalnya, Anda dapat mengubah teks di tombol yang mengaktifkan fitur tersebut.

    Selain itu, teks dalam dialog izin sistem merujuk ke grup izin yang terkait dengan izin yang Anda minta. Pengelompokan izin ini dirancang untuk kemudahan penggunaan sistem, dan aplikasi Anda tidak boleh mengandalkan izin yang ada di dalam atau di luar grup izin tertentu.

Cuplikan kode berikut menunjukkan cara menangani respons izin:

Kotlin

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher. You can use either a val, as shown in this snippet,
// or a lateinit var in your onAttach() or onCreate() method.
val requestPermissionLauncher =
    registerForActivityResult(RequestPermission()
    ) { isGranted: Boolean ->
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your
            // app.
        } else {
            // Explain to the user that the feature is unavailable because the
            // feature requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        }
    }

Java

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher, as an instance variable.
private ActivityResultLauncher<String> requestPermissionLauncher =
    registerForActivityResult(new RequestPermission(), isGranted -> {
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your
            // app.
        } else {
            // Explain to the user that the feature is unavailable because the
            // feature requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        }
    });

Dan cuplikan kode ini menunjukkan proses yang direkomendasikan untuk memeriksa izin dan meminta izin dari pengguna jika diperlukan:

Kotlin

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.REQUESTED_PERMISSION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
    }
    ActivityCompat.shouldShowRequestPermissionRationale(
            this, Manifest.permission.REQUESTED_PERMISSION) -> {
        // In an educational UI, explain to the user why your app requires this
        // permission for a specific feature to behave as expected, and what
        // features are disabled if it's declined. In this UI, include a
        // "cancel" or "no thanks" button that lets the user continue
        // using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // You can directly ask for the permission.
        // The registered ActivityResultCallback gets the result of this request.
        requestPermissionLauncher.launch(
                Manifest.permission.REQUESTED_PERMISSION)
    }
}

Java

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) {
    // You can use the API that requires the permission.
    performAction(...);
} else if (ActivityCompat.shouldShowRequestPermissionRationale(
        this, Manifest.permission.REQUESTED_PERMISSION)) {
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected, and what
    // features are disabled if it's declined. In this UI, include a
    // "cancel" or "no thanks" button that lets the user continue
    // using your app without granting the permission.
    showInContextUI(...);
} else {
    // You can directly ask for the permission.
    // The registered ActivityResultCallback gets the result of this request.
    requestPermissionLauncher.launch(
            Manifest.permission.REQUESTED_PERMISSION);
}

Kelola sendiri kode permintaan izin

Sebagai alternatif untuk mengizinkan sistem mengelola kode permintaan izin, Anda dapat mengelola sendiri kode permintaan izin. Untuk melakukannya, sertakan kode permintaan dalam panggilan ke requestPermissions().

Cuplikan kode berikut menunjukkan cara meminta izin menggunakan kode permintaan:

Kotlin

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.REQUESTED_PERMISSION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
        performAction(...)
    }
    ActivityCompat.shouldShowRequestPermissionRationale(
            this, Manifest.permission.REQUESTED_PERMISSION) -> {
        // In an educational UI, explain to the user why your app requires this
        // permission for a specific feature to behave as expected, and what
        // features are disabled if it's declined. In this UI, include a
        // "cancel" or "no thanks" button that lets the user continue
        // using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // You can directly ask for the permission.
        requestPermissions(CONTEXT,
                arrayOf(Manifest.permission.REQUESTED_PERMISSION),
                REQUEST_CODE)
    }
}

Java

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) {
    // You can use the API that requires the permission.
    performAction(...);
} else if (ActivityCompat.shouldShowRequestPermissionRationale(
        this, Manifest.permission.REQUESTED_PERMISSION)) {
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected, and what
    // features are disabled if it's declined. In this UI, include a
    // "cancel" or "no thanks" button that lets the user continue
    // using your app without granting the permission.
    showInContextUI(...);
} else {
    // You can directly ask for the permission.
    requestPermissions(CONTEXT,
            new String[] { Manifest.permission.REQUESTED_PERMISSION },
            REQUEST_CODE);
}

Setelah pengguna merespons dialog izin sistem, sistem akan memanggil implementasi onRequestPermissionsResult() aplikasi Anda. Sistem meneruskan respons pengguna ke dialog izin serta kode permintaan yang Anda tentukan, seperti yang ditunjukkan dalam cuplikan kode berikut:

Kotlin

override fun onRequestPermissionsResult(requestCode: Int,
        permissions: Array<String>, grantResults: IntArray) {
    when (requestCode) {
        PERMISSION_REQUEST_CODE -> {
            // If request is cancelled, the result arrays are empty.
            if ((grantResults.isNotEmpty() &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                // Permission is granted. Continue the action or workflow
                // in your app.
            } else {
                // Explain to the user that the feature is unavailable because
                // the feature requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            }
            return
        }

        // Add other 'when' lines to check for other
        // permissions this app might request.
        else -> {
            // Ignore all other requests.
        }
    }
}

Java

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
        int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission is granted. Continue the action or workflow
                // in your app.
            }  else {
                // Explain to the user that the feature is unavailable because
                // the feature requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            }
            return;
        }
        // Other 'case' lines to check for other
        // permissions this app might request.
    }
}

Meminta izin akses lokasi

Saat Anda meminta izin akses lokasi, ikuti praktik terbaik yang sama seperti izin runtime lainnya. Satu perbedaan penting mengenai izin akses lokasi adalah bahwa sistem tidak hanya memiliki satu izin saja yang terkait dengan lokasi, melainkan beberapa. Izin mana yang Anda minta, dan cara memintanya, bergantung pada persyaratan lokasi untuk kasus penggunaan aplikasi Anda.

Lokasi latar depan

Jika aplikasi Anda berisi fitur yang membagikan atau menerima informasi lokasi satu kali saja atau selama jangka waktu yang ditentukan, maka fitur tersebut memerlukan akses lokasi latar depan. Berikut beberapa contohnya:

  • Pada aplikasi navigasi, suatu fitur memungkinkan pengguna mendapatkan petunjuk arah belokan demi belokan.
  • Dalam aplikasi pesan, suatu fitur memungkinkan pengguna berbagi lokasinya saat ini dengan pengguna lain.

Sistem menganggap aplikasi Anda menggunakan lokasi latar depan jika fitur aplikasi Anda mengakses lokasi perangkat saat ini dalam salah satu situasi berikut:

  • Aktivitas berasal dari aplikasi Anda terlihat.
  • Aplikasi Anda menjalankan layanan latar depan. Saat layanan latar depan berjalan, sistem akan membuat pengguna menyadarinya dengan menampilkan notifikasi persisten. Aplikasi Anda terus memiliki akses jika ditempatkan di latar belakang, seperti saat pengguna menekan tombol Layar utama di perangkat atau menonaktifkan layar perangkatnya.

    Di Android 10 (API level 29) dan yang lebih tinggi, Anda harus mendeklarasikan jenis layanan latar depan location, seperti yang ditunjukkan dalam cuplikan kode berikut. Pada versi Android yang lebih lama, sebaiknya Anda mendeklarasikan jenis layanan latar depan ini.

    <!-- Recommended for Android 9 (API level 28) and lower. -->
    <!-- Required for Android 10 (API level 29) and higher. -->
    <service
        android:name="MyNavigationService"
        android:foregroundServiceType="location" ... >
        <!-- Any inner elements go here. -->
    </service>

Anda mendeklarasikan kebutuhan untuk lokasi latar depan saat aplikasi meminta izin ACCESS_COARSE_LOCATION atau izin ACCESS_FINE_LOCATION, seperti yang ditunjukkan dalam cuplikan berikut:

<manifest ... >
  <!-- Include this permission any time your app needs location information. -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  <!-- Include only if your app benefits from precise location access. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

Lokasi latar belakang

Aplikasi memerlukan akses lokasi latar belakang jika suatu fitur dalam aplikasi terus-menerus berbagi lokasi dengan pengguna lain atau menggunakan Geofencing API. Beberapa contohnya meliputi:

  • Dalam aplikasi berbagi lokasi keluarga, suatu fitur memungkinkan pengguna untuk terus berbagi lokasi dengan anggota keluarga.
  • Dalam aplikasi IoT, suatu fitur memungkinkan pengguna untuk mengonfigurasi perangkat smart home mereka, sehingga perangkat akan nonaktif ketika pengguna meninggalkan rumah dan aktif kembali ketika pengguna kembali ke rumah.

Sistem menganggap aplikasi Anda menggunakan lokasi latar belakang jika mengakses lokasi perangkat saat ini dalam situasi apa pun selain yang dijelaskan di bagian lokasi latar depan. Akurasi lokasi latar belakang sama dengan akurasi lokasi latar depan, yang bergantung pada izin akses lokasi yang dideklarasikan aplikasi Anda.

Di Android 10 (API level 29) dan yang lebih tinggi, Anda harus mendeklarasikan izin ACCESS_BACKGROUND_LOCATION dalam manifes aplikasi untuk meminta akses lokasi latar belakang pada runtime. Pada versi Android yang lebih lama, jika aplikasi Anda menerima akses lokasi latar depan, aplikasi juga otomatis menerima akses lokasi latar belakang.

<manifest ... >
  <!-- Required only when requesting background location access on
       Android 10 (API level 29) and higher. -->
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

Menangani penolakan izin

Jika pengguna menolak permintaan izin, aplikasi Anda harus membantu pengguna memahami implikasi atas penolakan izin tersebut. Secara khusus, aplikasi Anda harus membuat pengguna mengetahui fitur yang tidak berfungsi karena tidak adanya izin. Saat Anda melakukannya, ingatlah praktik terbaik berikut:

  • Arahkan perhatian pengguna. Perjelas bagian tertentu UI aplikasi Anda yang memiliki fungsi terbatas karena aplikasi Anda tidak memiliki izin yang diperlukan. Beberapa contoh yang dapat Anda lakukan meliputi hal-hal berikut:

    • Menampilkan pesan di tempat hasil atau data fitur akan muncul.
    • Menampilkan tombol lain yang berisi ikon dan warna error.
  • Jadilah spesifik. Jangan tampilkan pesan umum. Sebagai gantinya, jelaskan fitur mana yang tidak tersedia karena aplikasi Anda tidak memiliki izin yang diperlukan.

  • Jangan tutupi antarmuka pengguna. Dengan kata lain, jangan tampilkan pesan peringatan layar penuh yang mencegah pengguna melanjutkan penggunaan aplikasi Anda.

Pada saat yang sama, aplikasi Anda harus mematuhi keputusan pengguna untuk menolak izin. Mulai Android 11 (API level 30), jika pengguna mengetuk Tolak untuk izin tertentu lebih dari satu kali selama masa aktif aplikasi diinstal di perangkat, pengguna tidak akan melihat dialog izin sistem jika aplikasi Anda meminta izin tersebut lagi. Tindakan pengguna menyiratkan "jangan tanya lagi". Pada versi sebelumnya, pengguna melihat dialog izin sistem setiap kali aplikasi Anda meminta izin, kecuali jika pengguna telah terlebih dahulu memilih kotak centang atau opsi "jangan tanya lagi".

Jika pengguna menolak permintaan izin lebih dari sekali, hal ini dianggap sebagai penolakan permanen. Sangat penting untuk hanya meminta izin kepada pengguna saat mereka memerlukan akses ke fitur tertentu. Jika tidak, Anda mungkin tidak sengaja kehilangan kemampuan untuk meminta ulang izin.

Dalam situasi tertentu, izin mungkin ditolak secara otomatis, tanpa pengguna melakukan tindakan apa pun. (Suatu izin mungkin diberikan secara otomatis juga.) Penting untuk tidak mengasumsikan apa pun tentang perilaku otomatis. Setiap kali aplikasi Anda perlu mengakses fungsionalitas yang memerlukan izin, pastikan aplikasi Anda masih diberi izin tersebut.

Untuk memberikan pengalaman pengguna terbaik saat meminta izin aplikasi, lihat juga Praktik terbaik izin aplikasi.

Memeriksa status penolakan saat pengujian dan proses debug

Untuk mengidentifikasi apakah izin aplikasi telah ditolak secara permanen (untuk tujuan proses debug dan pengujian), gunakan perintah berikut:

adb shell dumpsys package PACKAGE_NAME

Dengan PACKAGE_NAME adalah nama paket yang akan diperiksa.

Output perintah berisi bagian yang terlihat seperti ini:

...
runtime permissions:
  android.permission.POST_NOTIFICATIONS: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
  android.permission.ACCESS_FINE_LOCATION: granted=false, flags=[ USER_SET|USER_FIXED|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
  android.permission.BLUETOOTH_CONNECT: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
...

Izin yang telah ditolak sekali oleh pengguna ditandai oleh USER_SET. Izin yang telah ditolak secara permanen dengan memilih Tolak dua kali ditandai oleh USER_FIXED.

Untuk memastikan penguji melihat dialog permintaan selama pengujian, reset tanda ini setelah Anda selesai men-debug aplikasi. Untuk melakukannya, gunakan perintah:

adb shell pm clear-permission-flags PACKAGE_NAME PERMISSION_NAME user-set user-fixed

PERMISSION_NAME adalah nama izin yang ingin Anda reset.

Untuk melihat daftar lengkap izin aplikasi Android, kunjungi halaman referensi API izin.

Izin satu kali

Opsi yang disebut &#39;Hanya kali ini&#39; adalah yang kedua dari tiga tombol dalam
    dialog.
Gambar 2. Dialog sistem yang muncul saat aplikasi meminta izin satu kali.

Mulai Android 11 (API level 30), setiap kali aplikasi meminta izin terkait lokasi, mikrofon, atau kamera, dialog izin yang ditampilkan kepada pengguna akan berisi opsi yang disebut Hanya kali ini, sebagaimana ditunjukkan dalam gambar 2. Jika pengguna memilih opsi ini dalam dialog, aplikasi Anda akan diberi izin satu kali untuk sementara.

Aplikasi Anda kemudian dapat mengakses data terkait untuk waktu tertentu yang bergantung pada perilaku aplikasi dan tindakan pengguna:

  • Saat aktivitas aplikasi terlihat, aplikasi Anda dapat mengakses data.
  • Jika pengguna mengirim aplikasi Anda ke latar belakang, aplikasi dapat terus mengakses data dalam waktu singkat.
  • Jika Anda meluncurkan layanan latar depan saat aktivitas terlihat, lalu pengguna memindahkan aplikasi ke latar belakang, aplikasi Anda dapat terus mengakses data sampai layanan latar depan berhenti.

Proses aplikasi berakhir saat izin dicabut

Jika pengguna mencabut izin satu kali, seperti di setelan sistem, aplikasi Anda tidak dapat mengakses data, meskipun Anda meluncurkan layanan latar depan atau pun tidak. Seperti halnya izin apa pun, jika pengguna mencabut izin satu kali aplikasi Anda, proses aplikasi akan dihentikan.

Saat pengguna membuka aplikasi Anda lagi dan fitur dalam aplikasi Anda meminta akses ke lokasi, mikrofon, atau kamera, pengguna akan dimintai izin kembali.

Mereset izin yang tidak digunakan

Android menyediakan beberapa cara untuk mereset izin runtime yang tidak digunakan ke status default dan ditolak:

Menghapus akses aplikasi

Di Android 13 (API level 33) dan yang lebih tinggi, Anda dapat menghapus akses aplikasi ke izin runtime yang tidak diperlukan lagi oleh aplikasi. Saat mengupdate aplikasi, lakukan langkah ini agar pengguna lebih cenderung memahami alasan aplikasi Anda terus meminta izin tertentu. Pengetahuan ini akan membantu membangun kepercayaan pengguna pada aplikasi Anda.

Untuk menghapus akses ke izin runtime, teruskan nama izin tersebut ke revokeSelfPermissionOnKill(). Untuk menghapus akses ke grup izin runtime secara bersamaan, teruskan kumpulan nama izin ke revokeSelfPermissionsOnKill(). Proses penghapusan izin terjadi secara asinkron dan menghentikan semua proses yang terkait dengan UID aplikasi Anda.

Agar sistem dapat menghapus akses aplikasi Anda ke izin, semua proses yang terkait dengan aplikasi Anda harus dihentikan. Saat Anda memanggil API, sistem akan menentukan kapan waktu yang aman untuk menghentikan proses ini. Biasanya, sistem akan menunggu hingga aplikasi Anda menghabiskan banyak waktu untuk berjalan di latar belakang, bukan di latar depan.

Untuk memberi tahu pengguna bahwa aplikasi Anda tidak lagi memerlukan akses ke izin runtime tertentu, tampilkan dialog saat pengguna meluncurkan aplikasi Anda lagi. Dialog ini dapat menyertakan daftar izin.

Secara otomatis mereset izin aplikasi yang tidak digunakan

Jika aplikasi Anda menargetkan Android 11 (level API 30) atau yang lebih baru dan tidak digunakan selama beberapa bulan, sistem akan melindungi data pengguna dengan mereset secara otomatis izin runtime sensitif yang telah diberikan pengguna aplikasi Anda. Pelajari lebih lanjut dalam panduan tentang hibernasi aplikasi.

Meminta untuk menjadi pengendali default, jika diperlukan

Beberapa aplikasi bergantung pada akses ke informasi pengguna sensitif yang terkait dengan log panggilan dan pesan SMS. Jika ingin meminta izin khusus untuk log panggilan dan pesan SMS serta memublikasikan aplikasi ke Play Store, Anda harus meminta pengguna menetapkan aplikasi Anda sebagai pengendali default untuk fungsi sistem inti sebelum meminta izin runtime ini.

Untuk mengetahui informasi selengkapnya tentang pengendali default, termasuk cara menampilkan permintaan pengendali default kepada pengguna, lihat panduan tentang izin yang hanya digunakan dalam pengendali default.

Memberikan semua izin runtime untuk tujuan pengujian

Untuk otomatis memberikan semua izin runtime saat Anda menginstal aplikasi di emulator atau perangkat uji, gunakan opsi -g untuk perintah adb shell install, seperti yang ditunjukkan dalam cuplikan kode berikut:

adb shell install -g PATH_TO_APK_FILE

Referensi lainnya

Untuk informasi tambahan tentang izin, baca artikel berikut:

Untuk mempelajari lebih lanjut cara meminta izin, tinjau contoh izin

Anda juga dapat menyelesaikan codelab yang menunjukkan praktik terbaik privasi.