Meminta Izin Aplikasi

Setiap aplikasi Android berjalan dalam sandbox dengan akses terbatas. Jika harus menggunakan resource atau informasi di luar sandbox miliknya, aplikasi harus meminta izin yang sesuai. Untuk mendeklarasikan bahwa aplikasi Anda memerlukan izin, cantumkan izin dalam manifes aplikasi lalu minta pengguna untuk menyetujui setiap izin saat aplikasi diluncurkan (di Android 6.0 dan yang lebih baru).

Halaman ini menjelaskan cara menggunakan Android Support Library untuk memeriksa dan meminta izin. Mulai Android 6.0 (API level 23), framework Android menyediakan metode yang mirip, tetapi dengan support library, penyediaan kompatibilitas dengan versi Android lama menjadi lebih mudah.

Menambahkan izin ke manifes

Pada semua versi Android, untuk mendeklarasikan bahwa aplikasi Anda memerlukan izin, masukkan elemen <uses-permission> dalam manifes aplikasi Anda, sebagai turunan dari elemen <manifest> level teratas. Misalnya, aplikasi yang perlu mengakses internet akan memiliki baris berikut dalam manifes:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
            package="com.example.snazzyapp">

        <uses-permission android:name="android.permission.INTERNET"/>
        <!-- other permissions go here -->

        <application ...>
            ...
        </application>
    </manifest>
    

Perilaku sistem setelah Anda mendeklarasikan izin bergantung pada seberapa sensitif izin tersebut. Beberapa izin dianggap "normal" sehingga sistem segera memberikannya setelah aplikasi diinstal. Izin lainnya dianggap "berbahaya" sehingga pengguna harus mengizinkan akses aplikasi secara eksplisit. Untuk informasi selengkapnya tentang berbagai jenis izin, lihat Tingkat perlindungan.

Memeriksa izin

Jika aplikasi membutuhkan izin berbahaya, Anda harus memeriksa apakah Anda memiliki izin tersebut setiap kali melakukan operasi yang membutuhkannya. Mulai dari Android 6.0 (API level 23), pengguna bisa mencabut izin dari aplikasi apa pun kapan saja, bahkan meskipun aplikasi menargetkan level API yang lebih rendah. Jadi, meskipun aplikasi menggunakan kamera kemarin, aplikasi tidak bisa berasumsi izin tersebut masih dimilikinya hari ini.

Untuk memeriksa apakah Anda memiliki izin, panggil metode ContextCompat.checkSelfPermission(). Sebagai contoh, cuplikan berikut menunjukkan cara memeriksa apakah aktivitas memiliki izin untuk menulis ke kalender:

Kotlin

    if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission is not granted
    }
    

Java

    if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission is not granted
    }
    

Jika aplikasi tersebut memiliki izin, metode akan menampilkan PERMISSION_GRANTED, dan aplikasi dapat melanjutkan operasinya. Jika aplikasi tidak memiliki izin, metode akan menampilkan PERMISSION_DENIED, dan aplikasi harus meminta izin kepada pengguna secara eksplisit.

Meminta izin

Saat aplikasi menerima PERMISSION_DENIED dari checkSelfPermission(), Anda harus meminta izin tersebut dari pengguna. Android menyediakan beberapa metode yang dapat Anda gunakan untuk meminta izin, misalnya requestPermissions(), seperti yang ditunjukkan dalam cuplikan kode di bawah. Memanggil metode ini akan memunculkan dialog Android standar yang tidak dapat disesuaikan.

Tampilan yang akan dilihat oleh pengguna bergantung pada versi perangkat Android serta versi target aplikasi Anda, seperti yang dijelaskan dalam Ringkasan Izin.

Menjelaskan mengapa aplikasi membutuhkan izin

Dalam situasi tertentu, bantulah pengguna untuk memahami mengapa aplikasi Anda memerlukan izin. Misalnya, jika pengguna meluncurkan aplikasi fotografi, mereka mungkin tidak akan terkejut jika aplikasi meminta izin untuk menggunakan kamera, tetapi mereka mungkin tidak paham mengapa aplikasi juga menginginkan akses ke lokasi atau kontak pengguna. Sebelum aplikasi meminta izin, Anda harus mempertimbangkan untuk memberikan penjelasan kepada pengguna. Perlu diingat bahwa Anda tidak boleh membingungkan pengguna dengan penjelasan Anda. Jika penjelasan terlalu panjang, pengguna mungkin merasa aplikasi tersebut sulit digunakan dan akan menghapusnya.

Salah satu pendekatan yang bisa Anda gunakan adalah memberikan penjelasan hanya jika pengguna menolak permintaan izin. Android menyediakan metode utilitas, shouldShowRequestPermissionRationale(), yang menampilkan true jika sebelumnya pengguna telah menolak permintaan itu, dan menampilkan false jika pengguna menolak izin dan memilih opsi Jangan tanya lagi dalam dialog permintaan izin, atau jika kebijakan perangkat melarang izin tersebut.

Jika pengguna tetap mencoba menggunakan fungsi yang memerlukan izin, tetapi terus menolak permintaan izinnya, kemungkinan mereka tidak memahami mengapa aplikasi memerlukan izin untuk menyediakan fungsionalitas tersebut. Dalam situasi seperti ini, memberikan penjelasan akan menjadi solusi yang tepat.

Saran lebih lanjut tentang cara membuat pengalaman pengguna yang baik saat meminta izin dapat dilihat di Praktik Terbaik Izin Aplikasi.

Meminta untuk menjadi pengendali default, jika diperlukan

Beberapa aplikasi bergantung pada akses ke informasi sensitif pengguna 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 waktu proses ini.

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

Meminta izin yang diperlukan

Jika belum memiliki izin yang diperlukan, aplikasi Anda harus memanggil salah satu metode requestPermissions() untuk meminta izin yang tepat. Aplikasi Anda meneruskan izin yang diperlukan dan kode permintaan integer yang Anda tentukan untuk mengidentifikasi permintaan izin ini. Metode ini berfungsi secara asinkron. Metode langsung menampilkan hasil, dan setelah pengguna merespons permintaan, sistem akan memanggil metode callback aplikasi beserta hasilnya, yang akan meneruskan kode permintaan yang sama dengan yang diteruskan oleh aplikasi ke requestPermissions().

Kode berikut ini memeriksa apakah aplikasi memiliki izin untuk membaca kontak pengguna. Jika tidak, kode akan memeriksa apakah penjelasan tentang alasan diperlukannya izin perlu ditampilkan, dan jika penjelasan tidak diperlukan, izin akan diminta:

Kotlin

    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.READ_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {

        // Permission is not granted
        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.READ_CONTACTS)) {
            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
        } else {
            // No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(thisActivity,
                    arrayOf(Manifest.permission.READ_CONTACTS),
                    MY_PERMISSIONS_REQUEST_READ_CONTACTS)

            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    } else {
        // Permission has already been granted
    }
    

Java

    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.READ_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {

        // Permission is not granted
        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.READ_CONTACTS)) {
            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
        } else {
            // No explanation needed; request the permission
            ActivityCompat.requestPermissions(thisActivity,
                    new String[]{Manifest.permission.READ_CONTACTS},
                    MY_PERMISSIONS_REQUEST_READ_CONTACTS);

            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    } else {
        // Permission has already been granted
    }
    

Permintaan yang ditampilkan oleh sistem menjelaskan grup izin yang perlu diakses oleh aplikasi Anda, bukan izin khusus.

Catatan: Saat aplikasi Anda memanggil requestPermissions(), sistem akan menampilkan kotak dialog standar kepada pengguna. Aplikasi Anda tidak dapat mengonfigurasi atau mengubah kotak dialog tersebut. Jika perlu memberikan informasi atau penjelasan kepada pengguna, Anda harus melakukannya sebelum memanggil requestPermissions(), seperti yang dijelaskan dalam Menjelaskan mengapa aplikasi memerlukan izin.

Menangani respons permintaan izin

Ketika pengguna merespons permintaan izin aplikasi, sistem akan memanggil metode onRequestPermissionsResult() aplikasi Anda, yang meneruskan respons pengguna kepadanya. Aplikasi Anda harus mengganti metode tersebut untuk mengetahui apakah izin telah diberikan. Callback dikirimi kode permintaan yang sama dengan yang Anda teruskan ke requestPermissions(). Misalnya, jika sebuah aplikasi meminta akses READ_CONTACTS, aplikasi tersebut mungkin memiliki metode callback sebagai berikut:

Kotlin

    override fun onRequestPermissionsResult(requestCode: Int,
            permissions: Array<String>, grantResults: IntArray) {
        when (requestCode) {
            MY_PERMISSIONS_REQUEST_READ_CONTACTS -> {
                // If request is cancelled, the result arrays are empty.
                if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
                } else {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                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 MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
                } else {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request.
        }
    }
    

Kotak dialog yang ditampilkan oleh sistem menjelaskan grup izin yang perlu diakses aplikasi Anda; izin khususnya tidak dicantumkan. Misalnya, jika Anda meminta izin READ_CONTACTS, kotak dialog sistem hanya akan mengatakan bahwa aplikasi Anda memerlukan akses ke kontak perangkat. Pengguna hanya perlu memberikan izin satu kali untuk setiap grup izin. Jika aplikasi Anda meminta izin lain dalam grup tersebut (yang tercantum dalam manifes aplikasi), sistem akan otomatis memberikannya. Ketika Anda meminta izin itu, sistem akan memanggil metode callback onRequestPermissionsResult() dan meneruskan PERMISSION_GRANTED dengan cara yang sama seperti jika pengguna telah mengizinkan permintaan secara eksplisit melalui kotak dialog sistem.

Catatan: Aplikasi Anda tetap harus meminta setiap izin yang diperlukan secara eksplisit, meskipun pengguna telah memberikan izin lain dalam grup yang sama. Selain itu, pengelompokan izin ke dalam grup dapat berubah dalam rilis Android mendatang. Kode tidak boleh mengandalkan asumsi bahwa izin tertentu ada atau tidak ada dalam grup yang sama.

Misalnya, anggaplah Anda mencantumkan READ_CONTACTS dan WRITE_CONTACTS dalam manifes aplikasi Anda. Jika Anda meminta READ_CONTACTS dan pengguna memberikan izinnya, kemudian Anda meminta WRITE_CONTACTS, sistem akan langsung memberikan izin tanpa berinteraksi dengan pengguna.

Jika pengguna menolak permintaan izin, aplikasi Anda harus melakukan tindakan yang tepat. Misalnya, aplikasi mungkin menampilkan dialog yang menjelaskan mengapa tindakan yang diminta pengguna tidak bisa dilakukan karena membutuhkan izin tersebut.

Ketika sistem meminta pengguna untuk memberikan izin, pengguna memiliki opsi untuk memberi tahu sistem agar tidak meminta izin itu lagi. Dalam kasus ini, setiap kali aplikasi menggunakan requestPermissions() untuk meminta izin itu lagi, sistem akan langsung menolak permintaan. Sistem memanggil metode callback onRequestPermissionsResult() dan meneruskan PERMISSION_DENIED, dengan cara yang sama seperti ketika pengguna menolak permintaan Anda secara eksplisit. Metode ini juga akan menampilkan false jika kebijakan perangkat melarang aplikasi memiliki izin tersebut. Ini berarti bahwa ketika Anda memanggil requestPermissions(), Anda tidak dapat berasumsi bahwa telah terjadi interaksi langsung dengan pengguna.

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

Mendeklarasikan izin berdasarkan level API

Untuk mendeklarasikan izin hanya pada perangkat yang mendukung izin waktu proses, yaitu perangkat yang menjalankan Android 6.0 (API level 23) atau yang lebih tinggi, sertakan tag uses- permission-sdk-23, bukan tag uses-permission.

Saat menggunakan salah satu tag ini, Anda dapat menyetel atribut maxSdkVersion untuk menetapkan bahwa, pada perangkat yang menjalankan versi lebih tinggi, izin tertentu tidak diperlukan.

Referensi lainnya

Untuk informasi tambahan tentang izin, baca artikel berikut:

Untuk mempelajari lebih lanjut cara meminta izin, download sampel aplikasi berikut: