EasyPermissions-ktx

repository·master·Indexed 19 days ago

https://github.com/vmadalin/easypermissions-ktx

A Kotlin wrapper for the Google EasyPermissions library designed to simplify Android permission handling for Android M and higher. It provides utilities for checking and requesting permissions, handling rationales and denials, and directing users to system settings via SettingsDialog. Key features include the @AfterPermissionGranted annotation for automatic execution, PermissionRequest.Builder for fine-grained control over rationale dialogs, and PermissionCallbacks for explicit result handling.

Tokens
3.3K
Snippets
11
Records
14
Agent score
62%

What's inside easypermissions-ktx

  1. Use @AfterPermissionGranted for automatic execution

    master

    The @AfterPermissionGranted annotation allows you to specify a method that should automatically execute once all permissions associated with a specific requestCode are granted.

    Requirements:

    • The annotated method must be void (or return Unit in Kotlin).
    • The annotated method must have no input parameters.
    • The requestCode used in the annotation must match the requestCode used in the requestPermissions call.
    @AfterPermissionGranted(REQUEST_CODE_LOCATION_AND_CONTACTS_PERMISSION)
    private fun methodRequiresTwoPermission() {
        // This runs automatically after permissions are granted
    }
  2. Handle Permanently Denied Permissions

    master

    If a user selects 'Never Ask Again', you can use EasyPermissions.somePermissionPermanentlyDenied(...) to detect this state. This method should be called within the onPermissionsDenied callback. If it returns true, you can then direct the user to the system settings using a SettingsDialog.

    override fun onPermissionsDenied(requestCode: Int, perms: List<String>) {
        // Check if the user denied permissions and checked "NEVER ASK AGAIN."
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            // Display a dialog directing them to enable the permission in app settings
            SettingsDialog.Builder(this).build().show()
        }
    }
  3. Initialize EasyPermissions in Activity or Fragment

    master

    To allow the library to handle permission results, you must override onRequestPermissionsResult in your Activity or Fragment and delegate the call to EasyPermissions.onRequestPermissionsResult.

    class MainActivity : AppCompatActivity() {
    
        override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    
            // EasyPermissions handles the request result.
            EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
        }
    }
  4. Check and Request Permissions

    master

    Use EasyPermissions.hasPermissions(...) to check if permissions are already granted. If not, use EasyPermissions.requestPermissions(...) to trigger the system request and show a rationale if necessary.

    // Check if permissions are already granted
    if (EasyPermissions.hasPermissions(this, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS)) {
        // Already have permission, do the thing
    } else {
        // Request them now
        EasyPermissions.requestPermissions(
            host = this,
            rationale = getString(R.string.permission_location_and_contacts_rationale_message),
            requestCode = REQUEST_CODE_LOCATION_AND_CONTACTS_PERMISSION,
            perms = Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS
        )
    }
  5. Interact with the Rationale Dialog using RationaleCallbacks

    master

    Implement EasyPermissions.RationaleCallbacks to respond specifically to whether a user accepted or denied the rationale dialog itself. Note that these callbacks indicate the user's response to the explanation, not necessarily the final permission state.

    // Implement RationaleCallbacks to handle user interaction with the rationale dialog
    override fun onRationaleAccepted(requestCode: Int) {
        // Rationale accepted to request some permissions
    }
    
    override fun onRationaleDenied(requestCode: Int) {
        // Rationale denied to request some permissions
    }
  6. Handle Permission Results with PermissionCallbacks

    master

    Implement the EasyPermissions.PermissionCallbacks interface in your Activity or Fragment to receive explicit callbacks when permissions are granted or denied.

    class MainActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks {
    
        override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
            EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
        }
    
        override fun onPermissionsGranted(requestCode: Int, perms: List<String>) {
            // Some permissions have been granted
        }
    
        override fun onPermissionsDenied(requestCode: Int, perms: List<String>) {
            // Some permissions have been denied
        }
    }
  7. Customize Permission Requests with PermissionRequest.Builder

    master

    For fine-grained control over the rationale dialog (such as custom themes or button text), use the PermissionRequest.Builder instead of passing simple parameters to requestPermissions.

    val request = PermissionRequest.Builder(this)
        .code(REQUEST_CODE)
        .perms(Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION)
        .theme(R.style.my_fancy_style)
        .rationale(R.string.camera_and_location_rationale)
        .positiveButtonText(R.string.rationale_ask_ok)
        .negativeButtonText(R.string.rationale_ask_cancel)
        .build()
    
    EasyPermissions.requestPermissions(this, request)
  8. Use showCompatDialog() vs showDialog() in RationaleDialog

    master

    The RationaleDialog provides two methods to display the dialog, depending on your project's dependency requirements:

    1. showCompatDialog(): Uses androidx.appcompat.app.AlertDialog. This is the recommended method for modern Android development to ensure backward compatibility and consistent styling.
    2. showDialog(): Uses the standard android.app.AlertDialog. Use this if you are not using AndroidX components.
  9. Show a permission rationale dialog with RationaleDialog

    master

    The RationaleDialog is used to prompt users to enable permissions in the app's settings screen when a permission request has been denied.

    When the user clicks the positive button (e.g., 'OK'), the dialog triggers onRationaleAccepted and automatically attempts to request the permissions again via directRequestPermissions.

    When the user clicks the negative button (e.g., 'Cancel'), it triggers onRationaleDenied and onPermissionsDenied.

    val rationaleDialog = RationaleDialog(context, permissionRequestModel)
    rationaleDialog.showCompatDialog()
  10. Show a SettingsDialog to direct users to app settings

    master

    Use SettingsDialog to prompt users to enable permissions by directing them to the system's application settings screen. When the user clicks the positive button, they are sent to the settings screen via an Intent. The result is returned to the calling Activity or Fragment via onActivityResult using the provided requestCode.

    To create and display the dialog, use the SettingsDialog.Builder pattern.

    SettingsDialog.Builder(context)
        .title("Permission Required")
        .rationale("Please enable this permission in settings to continue.")
        .requestCode(123)
        .build()
        .show()
  11. Configure SettingsDialog using Builder

    master

    The SettingsDialog.Builder allows you to customize the appearance and behavior of the settings prompt.

    Available Configuration Methods:

    • theme(@StyleRes theme: Int): Sets the dialog theme.
    • requestCode(requestCode: Int): Sets the request code used when calling startActivityForResult. Defaults to DEFAULT_SETTINGS_REQ_CODE (16061).
    • openOnNewTask(openOnNewTask: Boolean): If true, adds Intent.FLAG_ACTIVITY_NEW_TASK to the intent used to open settings.
    • title(title: String) or title(@StringRes resId: Int): Sets the dialog title.
    • rationale(rationale: String) or rationale(@StringRes resId: Int): Sets the message body (rationale).
    • positiveButtonText(text: String) or positiveButtonText(@StringRes resId: Int): Sets the text for the positive button.
    • negativeButtonText(text: String) or negativeButtonText(@StringRes resId: Int): Sets the text for the negative button.
    • build(): Returns the configured SettingsDialog instance.