Created
August 9, 2022 18:17
-
-
Save eduardobape/8130ebb06604ccdb127272af5f735622 to your computer and use it in GitHub Desktop.
Permissions flow for all Android versions using Activity Result APIs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.edudev.livedataroomexample | |
import android.Manifest | |
import android.app.Activity | |
import android.app.AlertDialog | |
import android.content.Intent | |
import android.content.pm.PackageManager | |
import android.net.Uri | |
import android.os.Bundle | |
import android.provider.Settings | |
import android.widget.Toast | |
import androidx.activity.result.contract.ActivityResultContracts | |
import androidx.appcompat.app.AppCompatActivity | |
import androidx.core.content.ContextCompat | |
import com.edudev.livedataroomexample.databinding.ActivityMainBinding | |
class MainActivity : AppCompatActivity() { | |
private lateinit var binding: ActivityMainBinding | |
private val permissionCamera = | |
registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> | |
if (granted) { | |
// Access to the camera is allowed, open the camera | |
Toast.makeText(this, "Access to the camera is allowed", Toast.LENGTH_SHORT).show() | |
} else if (!shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) { | |
// This else-if branch is useful in two cases: | |
// 1) On Android 10 or below, if the user has chosen the option "Don't ask again" on | |
// the permission default dialog, this dialog won't be displayed anymore. | |
// This situation is detected is shouldShowRequestPermissionRationale returns false. | |
// 2) On Android 11 or higher, if the user has already denied a permission two or | |
// more times, the permission default dialog won't be displayed anymore. | |
// This situation is detected is shouldShowRequestPermissionRationale returns false. | |
// In both cases, the only possibility would be displayed a custom dialog where the user | |
// could choose an option to navigate to the app settings in order to grant a determined | |
// permission. This custom dialog should displayed the reason why the permission | |
// needs to be granted. | |
showDialogPermissionsSettings() | |
} else { | |
// This else branch is executed in different ways, depending on the Android version: | |
// 1) On Android 10 or below, this branch is executed if the user has denied a | |
// permission one or more times, but they have never chosen the option "Don't ask again". | |
// 2) On Android 11 or higher, this branch is executed only the user denies a permission | |
// for the first time. | |
// In both cases, it's recommended to show a custom dialog displaying the reason why | |
// the permission needs to be granted. If the user chooses the option to grant this | |
// permission on this custom dialog, the Android permission default dialog will be | |
// opened by Android. | |
showDialogRationaleCameraPermission() | |
} | |
} | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
binding = ActivityMainBinding.inflate(layoutInflater) | |
setContentView(binding.root) | |
handleEventNewWord() | |
handleEventOpenCamera() | |
} | |
private fun handleEventNewWord() { | |
binding.fabNewWord.setOnClickListener { | |
newWordResult.launch(Intent(this, NewWordActivity::class.java)) | |
} | |
} | |
private fun handleEventOpenCamera() { | |
binding.fabCamera.setOnClickListener { | |
when { | |
ContextCompat.checkSelfPermission(this, | |
Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED -> { | |
// Check if the user granted the camera permission | |
Toast.makeText(this, "Ya me diste permiso", Toast.LENGTH_SHORT).show() | |
} | |
shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) -> { | |
// On Android 10 or below, shouldShowRequestPermissionRationale is true if the | |
// user has already denied the permission at least once. | |
// On Android 11 or higher, shouldShowRequestPermissionRationale is true only | |
// when the user has denied the permission only once. When the user denies the | |
// permission two or more times, shouldShowRequestPermissionRationale is false | |
showDialogRationaleCameraPermission() | |
} | |
else -> { | |
// The Android permission default dialog is shown the first time the app is opened | |
permissionCamera.launch(Manifest.permission.CAMERA) | |
} | |
} | |
} | |
} | |
private fun showDialogRationaleCameraPermission() { | |
val alertDialogBuilder = AlertDialog.Builder(this) | |
with(alertDialogBuilder) { | |
setMessage("Necesito permiso para hacerte fotos please!") | |
setPositiveButton("Sí") { _, _ -> | |
permissionCamera.launch(Manifest.permission.CAMERA) | |
} | |
setNegativeButton("No") { _, _ -> | |
Toast.makeText(this@MainActivity, | |
"Has elegido No, por tanto, fotos no", | |
Toast.LENGTH_SHORT).show() | |
} | |
create().show() | |
} | |
} | |
private fun showDialogPermissionsSettings() { | |
val alertDialogBuilder = AlertDialog.Builder(this) | |
with(alertDialogBuilder) { | |
setMessage("¿Desea acceder a la configuración de la app para activar el permiso de la cámara") | |
setPositiveButton("Sí") { _, _ -> | |
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) | |
intent.data = Uri.parse("package:$packageName") | |
startActivity(intent) | |
} | |
setNegativeButton("No") { _, _ -> | |
} | |
alertDialogBuilder.create().show() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment