Sejak Android 6.0 Marshmallow, Android menggunakan model izin yang menyederhanakan proses penginstalan dan update otomatis aplikasi. Izin diminta saat runtime, bukan sebelum penginstalan aplikasi. Selain itu, pengguna dapat memilih untuk menolak izin tertentu. Untuk memberi pengguna fleksibilitas ini, Anda harus memastikan bahwa aplikasi berperilaku seperti yang diharapkan saat pengguna mengaktifkan atau menonaktifkan izin tertentu.
Layanan Google Play itu sendiri memiliki izin runtime yang dapat ditolak secara terpisah oleh pengguna dari izin yang secara khusus diminta oleh aplikasi Anda. Layanan Google Play otomatis mendapatkan semua izin yang diperlukan untuk mendukung API-nya. Namun, aplikasi Anda tetap harus memeriksa dan meminta izin runtime sesuai kebutuhan dan menangani error dengan tepat jika pengguna telah menolak izin yang diperlukan untuk API yang digunakan aplikasi Anda dari layanan Google Play.
Sebaiknya kelola ekspektasi pengguna dalam menetapkan izin yang mungkin diperlukan runtime. Praktik terbaik berikut akan membantu Anda menghindari potensi masalah.
Prasyarat
Anda harus mendeklarasikan izin dalam file AndroidManifest.xml
.
Contoh:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Panduan
Memverifikasi izin sebelum memanggil API
Setelah mendeklarasikan API yang ingin digunakan dalam file AndroidManifest.xml
, pastikan Anda memiliki izin yang diperlukan sebelum memanggil API. Hal ini
dapat dilakukan menggunakan metode checkSelfPermission
ActivityCompat
atau ContextCompat
.
Jika panggilan menampilkan nilai salah (false), artinya izin tidak diberikan dan Anda
harus menggunakan requestPermissions
untuk memintanya. Respons untuk hal ini
akan ditampilkan dalam callback yang akan Anda lihat di langkah berikutnya.
Contoh:
Kotlin
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Request Permissions Now ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_LOCATION_PERMISSION_CODE) } else { // permission has been granted, continue as usual val locationResult = LocationServices .getFusedLocationProviderClient(this /* Context */) .lastLocation }
Java
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Request Permissions Now ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION_CODE); } else { // permission has been granted, continue as usual TasklocationResult = LocationServices .getFusedLocationProviderClient(this /** Context */) .getLastLocation(); }
Menerapkan callback permintaan izin
Jika izin yang diperlukan aplikasi Anda belum diberikan oleh pengguna, metode
requestPermissions
harus dipanggil untuk meminta
pengguna memberikannya. Respons dari pengguna diambil dalam callback
onRequestPermissionsResult
. Aplikasi Anda harus
menerapkan ini dan selalu memeriksa nilai yang ditampilkan karena permintaan dapat
ditolak atau dibatalkan. Anda juga dapat meminta dan memeriksa beberapa izin sekaligus. Contoh berikut hanya memeriksa satu izin.
Kotlin
fun onRequestPermissionsResult( requestCode: Int, permissions: Array, grantResults: IntArray ) { if (requestCode == REQUEST_LOCATION_PERMISSION_CODE) { if (grantResults.singleOrNull() == PackageManager.PERMISSION_GRANTED) { // We can now safely use the API we requested access to val locationResult: Task = LocationServices .getFusedLocationProviderClient(this /* Context */) .lastLocation // Request the last known location. } else { // Permission was denied or request was cancelled } } }
Java
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == REQUEST_LOCATION_PERMISSION_CODE) { if(grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // We can now safely use the API we requested access to TasklocationResult = LocationServices .getFusedLocationProviderClient(this /** Context */) .getLastLocation(); // Request the last known location. } else { // Permission was denied or request was cancelled } } }
Menampilkan alasan izin
Jika izin yang diminta aplikasi Anda diperlukan untuk fitur inti aplikasi dan pengguna sebelumnya telah menolak permintaan izin, aplikasi Anda harus menampilkan penjelasan tambahan sebelum meminta izin lagi. Pengguna lebih cenderung memberikan izin jika mereka memahami alasan izin diperlukan dan manfaat langsung bagi mereka.
Dalam hal ini, sebelum memanggil requestPermissions
, Anda harus memanggil
shouldShowRequestPermissionRationale
. Jika menampilkan
true, Anda harus membuat beberapa UI untuk menampilkan konteks tambahan untuk
izin.
Misalnya, kode Anda mungkin terlihat seperti ini:
Kotlin
private const val REQUEST_LOCATION_PERMISSION_CODE = 2 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Check Permissions Now if ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.ACCESS_FINE_LOCATION ) { // Display UI and wait for user interaction } else { ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_LOCATION_PERMISSION_CODE) } } else { // Permission has already been granted, continue as usual val locationResult: Task= LocationServices .getFusedLocationProviderClient(this /* Context */) .lastLocation }
Java
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Check Permissions Now private static final int REQUEST_LOCATION_PERMISSION_CODE = 2; if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) { // Display UI and wait for user interaction } else { ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.LOCATION_FINE}, REQUEST_LOCATION_PERMISSION_CODE); } } else { // permission has been granted, continue as usual TasklocationResult = LocationServices .getFusedLocationProviderClient(this /** Context */) .getLastLocation(); }
Panggilan API layanan Google Play akan otomatis menampilkan dialog (jika
klien dibuat instance-nya dengan Activity
) atau notifikasi baki sistem (jika
klien dibuat instance-nya dengan Context
) yang dapat diketuk pengguna untuk memulai
intent resolusi izin. Panggilan akan dimasukkan ke antrean dan dicoba lagi setelah izin diberikan.