Skip to content

Instantly share code, notes, and snippets.

@neyogiry
Created November 3, 2020 03:52
Show Gist options
  • Save neyogiry/594c5c08b59a3151ce64a9be8a74a896 to your computer and use it in GitHub Desktop.
Save neyogiry/594c5c08b59a3151ce64a9be8a74a896 to your computer and use it in GitHub Desktop.
Android - Runtime Permission Helper class
import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.pm.PackageManager
import android.os.Build
import android.util.Log
import androidx.core.app.ActivityCompat
import androidx.fragment.app.Fragment
import pe.solera.portales.R
class RuntimePermissionHelper @JvmOverloads constructor(
private val context: Context,
private val requiredPermissions: ArrayList<String>,
private val permissionResultCallback: PermissionResultCallback,
private val fragment: Fragment? = null,
private val sdkInt: Int? = Build.VERSION_CODES.M,
private val requestCode: Int? = DEFAULT_REQUEST_CODE
) {
private var ungrantedPermissions: ArrayList<String>? = null
companion object {
private const val TAG = "RuntimePermissionHelper"
const val DEFAULT_REQUEST_CODE = 13
fun isAllPermissionsGranted(context: Context, permissions: ArrayList<String>) : Boolean {
return isAllPermissionsGranted(context, permissions, Build.VERSION_CODES.M)
}
fun isAllPermissionsGranted(context: Context, permissions: ArrayList<String>, sdkInt: Int) : Boolean {
var isAllPermissionsGranted = true
if(Build.VERSION.SDK_INT < sdkInt) return isAllPermissionsGranted
for (permission in permissions) {
if(ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
isAllPermissionsGranted = false
break
}
}
return isAllPermissionsGranted
}
}
fun checkAndRequestPermission() {
if(Build.VERSION.SDK_INT >= sdkInt!!) {
if(getUnGrantedPermissionsList().size > 0) {
requestPermissions()
}else {
Log.i(TAG, "Permissions has already been granted")
permissionResultCallback?.let { it.permissionGranted(requestCode!!) }
}
}else {
Log.i(TAG, "Permissions aren't necessary")
permissionResultCallback?.let { it.permissionGranted(requestCode!!) }
}
}
fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray) {
if(grantResults.isEmpty()) return
var pendingPermissions = ArrayList<String>()
for (i in permissions.indices) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(context as Activity, permissions[i])) {
pendingPermissions.add(permissions[i])
Log.i(TAG, "Pending permission " + permissions[i])
}
else {
Log.i(TAG, permissions[i] + " can't be request again. Go to settings and enable permission")
permissionResultCallback?.let { it.neverAskAgain(requestCode) }
return
}
}
}
if(pendingPermissions.size > 0) {
showMessageOkCancel(context.getString(R.string.permission_rationale_warning_message), pendingPermissions)
}else {
Log.i(TAG, "All of the permissions are granted")
permissionResultCallback?.let { it.permissionGranted(requestCode) }
}
}
private fun getUnGrantedPermissionsList(): ArrayList<String> {
val list = ArrayList<String>()
requiredPermissions?.let {
for (permission in it) {
val result = ActivityCompat.checkSelfPermission(context!!, permission)
if (result != PackageManager.PERMISSION_GRANTED) {
list.add(permission)
}
}
}
return list
}
private fun requestPermissions() {
ungrantedPermissions = getUnGrantedPermissionsList()
fragment?.let {
it.requestPermissions(ungrantedPermissions!!.toArray(arrayOfNulls(ungrantedPermissions!!.size)), requestCode!!)
} ?: ActivityCompat.requestPermissions(context as Activity, ungrantedPermissions!!.toArray(arrayOfNulls(ungrantedPermissions!!.size)), requestCode!!)
}
private fun showMessageOkCancel(message: String, pendingPermissions: ArrayList<String>) {
AlertDialog
.Builder(context)
.setTitle(context.getString(R.string.app_name))
.setMessage(message)
.setPositiveButton(R.string.ok, object : DialogInterface.OnClickListener {
override fun onClick(dialog: DialogInterface?, which: Int) {
requestPermissions()
}
})
.setNegativeButton(R.string.exit, object : DialogInterface.OnClickListener {
override fun onClick(dialog: DialogInterface?, which: Int) {
if(requiredPermissions?.size == pendingPermissions.size) permissionResultCallback?.permissionDenied(requestCode!!)
else permissionResultCallback?.partialPermissionGranted(requestCode!!, pendingPermissions)
}
})
.create()
.show()
}
interface PermissionResultCallback {
fun permissionGranted(requestCode: Int)
fun partialPermissionGranted(requestCode: Int, pendingPermissions: ArrayList<String>)
fun permissionDenied(requestCode: Int)
fun neverAskAgain(requestCode: Int)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment