Android Request Permission With AlertDialog in BottomSheetDialogFragment

December 17, 2019

If you plan to show an AlertDialog rationale to explain why you need such permission, you will notice the AlertDialog is dimmed. If you focus/click on the AlertDialog, the BottomSheetDialogFragment will get dimissed.

The following solution is from Bryan which allow AlertDialog to be shown on top of BottomSheetDialogFragment.

  • We need to show AlertDialog when the BottomSheetDialog is shown, instead of when Fragment is visible.
  • For simplicity, I dismiss the DialogFrament when permission is denied
class NearbyPlacesDialog : BottomSheetDialogFragment() {
    companion object {
        private const val REQUEST_LOCATION_PERMISSION = 1
    }

    // private val locationPermissions = arrayOf(ACCESS_FINE_LOCATION)
    private val locationPermission = ACCESS_FINE_LOCATION

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = super.onCreateDialog(savedInstanceState)
        dialog.setOnShowListener {
            if (!checkLocationPermission()) {
                requestLocationPermission()
            }
        }
        return dialog
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        if (checkLocationPermission()) {
            init()
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_LOCATION_PERMISSION) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                findCurrentPlace()
            } else {
                Timber.d("Location permission denied")

                val isNeverAskAgain = !ActivityCompat.shouldShowRequestPermissionRationale(
                        activity!!,
                        locationPermission)

                if (isNeverAskAgain) {
                    Snackbar.make(list, "Location Permission required", Snackbar.LENGTH_LONG)
                        .setAction("Settings") {
                            Intent(ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:${activity!!.packageName}")).apply {
                                addCategory(Intent.CATEGORY_DEFAULT)
                                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                                startActivity(this)
                            }
                        }
                        .addCallback(object: Snackbar.Callback() {
                            override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
                                super.onDismissed(transientBottomBar, event)
                                dismiss()
                            }
                        })
                        .show()
                }
                else {
                    Timber.d("Location permission denied")
                    dismiss()
                }

            }
        }
    }



    private fun init() {
        // TODO: initialize the UI
    }

    private fun checkLocationPermission(): Boolean {
        /*
        locationPermissions.forEach {
            if (ContextCompat.checkSelfPermission(context!!, it) != PackageManager.PERMISSION_GRANTED) {
                return false
            }
        }
        return true
         */
        return (ContextCompat.checkSelfPermission(context!!, locationPermission) == PackageManager.PERMISSION_GRANTED)
    }

    private fun requestLocationPermission() {
        // optional implementation of shouldShowRequestPermissionRationale
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity!!, locationPermission)) {
            AlertDialog.Builder(context!!)
                .setMessage("Need location permission to get current place")
                .setPositiveButton(android.R.string.ok) { _, _ ->
                    // ActivityCompat.requestPermissions(activity!!, locationPermissions, REQUEST_LOCATION_PERMISSION)
                    requestPermissions(arrayOf(locationPermission), REQUEST_LOCATION_PERMISSION)
                }
                .setNegativeButton(android.R.string.cancel) { _, _ ->
                    dismiss()
                }
                .show()
        }
        else {
            // ActivityCompat.requestPermissions(activity!!, locationPermissions, REQUEST_LOCATION_PERMISSION)
            requestPermissions(arrayOf(locationPermission), REQUEST_LOCATION_PERMISSION)
        }
    }


}
This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.