Skip to content Skip to sidebar Skip to footer

Android Marshmallow Request Permission?

I am currently working on an application that requires several 'dangerous' permissions. So I tried adding 'ask for permission' as required in Android Marshmallow(API Level 23), but

Solution 1:

Open a Dialog using the code below:

 ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    1);

Get the Activity result as below:

@OverridepublicvoidonRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case1: {

          // 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.
                Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
            }
            return;
        }

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

More info: https://developer.android.com/training/permissions/requesting.html

Solution 2:

This structure I am using to check if my app has permission and than request if it does not have permission. So in my main code from where i want to check write following :

int MyVersion = Build.VERSION.SDK_INT;
if (MyVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
                if (!checkIfAlreadyhavePermission()) {
                    requestForSpecificPermission();
                }
}

Module checkIfAlreadyhavePermission() is implemented as :

private boolean checkIfAlreadyhavePermission() {
    int result = ContextCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNTS);
    if (result == PackageManager.PERMISSION_GRANTED) {
        returntrue;
    } else {
        returnfalse;
    }
}

Module requestForSpecificPermission() is implemented as :

privatevoidrequestForSpecificPermission() {
        ActivityCompat.requestPermissions(this, newString[]{Manifest.permission.GET_ACCOUNTS, Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 101);
}

and Override in Activity :

@OverridepublicvoidonRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case101:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //granted
            } else {
                //not granted
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

Refer this link for more details : http://revisitingandroid.blogspot.in/2017/01/how-to-check-and-request-for-run-time.html

Solution 3:

Starting in Android Marshmallow, we need to request the user for specific permissions. We can also check through code if the permission is already given. Here is a list of commonly needed permissions:

  • android.permission_group.CALENDAR

    • android.permission.READ_CALENDAR
    • android.permission.WRITE_CALENDAR
  • android.permission_group.CAMERA

    • android.permission.CAMERA
  • android.permission_group.CONTACTS

    • android.permission.READ_CONTACTS
    • android.permission.WRITE_CONTACTS
    • android.permission.GET_ACCOUNTS
  • android.permission_group.LOCATION

    • android.permission.ACCESS_FINE_LOCATION
    • android.permission.ACCESS_COARSE_LOCATION
  • android.permission_group.MICROPHONE

    • android.permission.RECORD_AUDIO
  • android.permission_group.PHONE

    • android.permission.READ_PHONE_STATE
    • android.permission.CALL_PHONE
    • android.permission.READ_CALL_LOG
    • android.permission.WRITE_CALL_LOG
    • android.permission.ADD_VOICEMAIL
    • android.permission.USE_SIP
    • android.permission.PROCESS_OUTGOING_CALLS
  • android.permission_group.SENSORS

    • android.permission.BODY_SENSORS
  • android.permission_group.SMS

    • android.permission.SEND_SMS
    • android.permission.RECEIVE_SMS
    • android.permission.READ_SMS
    • android.permission.RECEIVE_WAP_PUSH
    • android.permission.RECEIVE_MMS
    • android.permission.READ_CELL_BROADCASTS
  • android.permission_group.STORAGE

    • android.permission.READ_EXTERNAL_STORAGE
    • android.permission.WRITE_EXTERNAL_STORAGE

Here is sample code to check for permissions:

if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
    if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.WRITE_CALENDAR)) {
        AlertDialog.BuilderalertBuilder=newAlertDialog.Builder(context);
        alertBuilder.setCancelable(true);
        alertBuilder.setMessage("Write calendar permission is necessary to write event!!!");
        alertBuilder.setPositiveButton(android.R.string.yes, newDialogInterface.OnClickListener() {
            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)publicvoidonClick(DialogInterface dialog, int which) {
                ActivityCompat.requestPermissions((Activity)context, newString[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
            }
        });
    } else {
        ActivityCompat.requestPermissions((Activity)context, newString[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
    }
}

Solution 4:

I have used this wrapper (Recommended) written by google developers. Its super easy to use.

https://github.com/googlesamples/easypermissions

Function dealing with checking and ask for permission if required

publicvoidlocationAndContactsTask() {
    String[] perms = { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS };
    if (EasyPermissions.hasPermissions(this, perms)) {
        // Have permissions, do the thing!
        Toast.makeText(this, "TODO: Location and Contacts things", Toast.LENGTH_LONG).show();
    } else {
        // Ask for both permissions
        EasyPermissions.requestPermissions(this, getString(R.string.rationale_location_contacts),
                RC_LOCATION_CONTACTS_PERM, perms);
    }
}

Happy coding :)

Solution 5:

My class for request runtime permissions in Activity or Fragment

It also help you show rationale or open Setting to enable permission after user denied a permission (with/without Never ask again) option easier

classRequestPermissionHandler(privateval activity: Activity? = null,
                               privateval fragment: Fragment? = null,
                               privateval permissions: Set<String> = hashSetOf(),
                               privateval listener: Listener? = null
) {
    privatevar hadShowRationale: Boolean = falsefunrequestPermission() {
        hadShowRationale = showRationaleIfNeed()
        if (!hadShowRationale) {
            doRequestPermission(permissions)
        }
    }

    funretryRequestDeniedPermission() {
        doRequestPermission(permissions)
    }

    privatefunshowRationaleIfNeed(): Boolean {
        val unGrantedPermissions = getPermission(permissions, Status.UN_GRANTED)
        val permanentDeniedPermissions = getPermission(unGrantedPermissions, Status.PERMANENT_DENIED)
        if (permanentDeniedPermissions.isNotEmpty()) {
            val consume = listener?.onShowSettingRationale(unGrantedPermissions)
            if (consume != null && consume) {
                returntrue
            }
        }

        val temporaryDeniedPermissions = getPermission(unGrantedPermissions, Status.TEMPORARY_DENIED)
        if (temporaryDeniedPermissions.isNotEmpty()) {
            val consume = listener?.onShowPermissionRationale(temporaryDeniedPermissions)
            if (consume != null && consume) {
                returntrue
            }
        }
        returnfalse
    }

    funrequestPermissionInSetting() {
        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
        val packageName = activity?.packageName ?: run {
            fragment?.requireActivity()?.packageName
        }
        val uri = Uri.fromParts("package", packageName, null)
        intent.data = uri
        activity?.apply {
            startActivityForResult(intent, REQUEST_CODE)
        } ?: run {
            fragment?.startActivityForResult(intent, REQUEST_CODE)
        }
    }

    funonRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
                                   grantResults: IntArray) {
        if (requestCode == REQUEST_CODE) {
            for (i in grantResults.indices) {
                if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                    markNeverAskAgainPermission(permissions[i], false)
                } elseif (!shouldShowRequestPermissionRationale(permissions[i])) {
                    markNeverAskAgainPermission(permissions[i], true)
                }
            }
            var hasShowRationale = falseif (!hadShowRationale) {
                hasShowRationale = showRationaleIfNeed()
            }
            if (hadShowRationale || !hasShowRationale) {
                notifyComplete()
            }
        }
    }

    funonActivityResult(requestCode: Int) {
        if (requestCode == REQUEST_CODE) {
            getPermission(permissions, Status.GRANTED).forEach {
                markNeverAskAgainPermission(it, false)
            }
            notifyComplete()
        }
    }

    funcancel() {
        notifyComplete()
    }

    privatefundoRequestPermission(permissions: Set<String>) {
        activity?.let {
            ActivityCompat.requestPermissions(it, permissions.toTypedArray(), REQUEST_CODE)
        } ?: run {
            fragment?.requestPermissions(permissions.toTypedArray(), REQUEST_CODE)
        }
    }

    privatefungetPermission(permissions: Set<String>, status: Status): Set<String> {
        val targetPermissions = HashSet<String>()
        for (p in permissions) {
            when (status) {
                Status.GRANTED -> {
                    if (isPermissionGranted(p)) {
                        targetPermissions.add(p)
                    }
                }
                Status.TEMPORARY_DENIED -> {
                    if (shouldShowRequestPermissionRationale(p)) {
                        targetPermissions.add(p)
                    }
                }
                Status.PERMANENT_DENIED -> {
                    if (isNeverAskAgainPermission(p)) {
                        targetPermissions.add(p)
                    }
                }
                Status.UN_GRANTED -> {
                    if (!isPermissionGranted(p)) {
                        targetPermissions.add(p)
                    }
                }
            }
        }
        return targetPermissions
    }

    privatefunisPermissionGranted(permission: String): Boolean {
        return activity?.let {
            ActivityCompat.checkSelfPermission(it, permission) == PackageManager.PERMISSION_GRANTED
        } ?: run {
            ActivityCompat.checkSelfPermission(fragment!!.requireActivity(), permission) == PackageManager.PERMISSION_GRANTED
        }
    }

    privatefunshouldShowRequestPermissionRationale(permission: String): Boolean {
        return activity?.let {
            ActivityCompat.shouldShowRequestPermissionRationale(it, permission)
        } ?: run {
            ActivityCompat.shouldShowRequestPermissionRationale(fragment!!.requireActivity(), permission)
        }
    }

    privatefunnotifyComplete() {
        listener?.onComplete(getPermission(permissions, Status.GRANTED), getPermission(permissions, Status.UN_GRANTED))
    }

    privatefungetPrefs(context: Context): SharedPreferences {
        return context.getSharedPreferences("SHARED_PREFS_RUNTIME_PERMISSION", Context.MODE_PRIVATE)
    }

    privatefunisNeverAskAgainPermission(permission: String): Boolean {
        return getPrefs(requireContext()).getBoolean(permission, false)
    }

    privatefunmarkNeverAskAgainPermission(permission: String, value: Boolean) {
        getPrefs(requireContext()).edit().putBoolean(permission, value).apply()
    }

    privatefunrequireContext(): Context {
        return fragment?.requireContext() ?: run {
            activity!!
        }
    }

    enumclassStatus{
        GRANTED, UN_GRANTED, TEMPORARY_DENIED, PERMANENT_DENIED
    }

    interfaceListener{
        funonComplete(grantedPermissions: Set<String>, deniedPermissions: Set<String>)funonShowPermissionRationale(permissions: Set<String>): BooleanfunonShowSettingRationale(permissions: Set<String>): Boolean
    }

    companionobject {
        constval REQUEST_CODE = 200
    }
}

Using in Activity like

classMainActivity : AppCompatActivity() {
    privatelateinitvar smsAndStoragePermissionHandler: RequestPermissionHandler

    overridefunonCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        smsAndStoragePermissionHandler = RequestPermissionHandler(this@MainActivity,
                permissions = setOf(Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_EXTERNAL_STORAGE),
                listener = object : RequestPermissionHandler.Listener {
                    overridefunonComplete(grantedPermissions: Set<String>, deniedPermissions: Set<String>) {
                        Toast.makeText(this@MainActivity, "complete", Toast.LENGTH_SHORT).show()
                        text_granted.text = "Granted: " + grantedPermissions.toString()
                        text_denied.text = "Denied: " + deniedPermissions.toString()
                    }

                    overridefunonShowPermissionRationale(permissions: Set<String>): Boolean {
                        AlertDialog.Builder(this@MainActivity).setMessage("To able to Send Photo, we need SMS and" + " Storage permission")
                                .setPositiveButton("OK") { _, _ ->
                                    smsAndStoragePermissionHandler.retryRequestDeniedPermission()
                                }
                                .setNegativeButton("Cancel") { dialog, _ ->
                                    smsAndStoragePermissionHandler.cancel()
                                    dialog.dismiss()
                                }
                                .show()
                        returntrue// don't want to show any rationale, just return false here
                    }

                    overridefunonShowSettingRationale(permissions: Set<String>): Boolean {
                        AlertDialog.Builder(this@MainActivity).setMessage("Go Settings -> Permission. " + "Make SMS on and Storage on")
                                .setPositiveButton("Settings") { _, _ ->
                                    smsAndStoragePermissionHandler.requestPermissionInSetting()
                                }
                                .setNegativeButton("Cancel") { dialog, _ ->
                                    smsAndStoragePermissionHandler.cancel()
                                    dialog.cancel()
                                }
                                .show()
                        returntrue
                    }
                })

        button_request.setOnClickListener { handleRequestPermission() }
    }

    privatefunhandleRequestPermission() {
        smsAndStoragePermissionHandler.requestPermission()
    }

    overridefunonRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
                                            grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        smsAndStoragePermissionHandler.onRequestPermissionsResult(requestCode, permissions,
                grantResults)
    }

    overridefunonActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        smsAndStoragePermissionHandler.onActivityResult(requestCode)
    }
}

Code on Github

Demo

Post a Comment for "Android Marshmallow Request Permission?"