A declarative API to handle Android runtime permissions.

Overview

PermissionsDispatcher CI for pull request PermissionsDispatcher

PermissionsDispatcher provides a simple annotation-based API to handle runtime permissions.

This library lifts the burden that comes with writing a bunch of check statements whether a permission has been granted or not from you, in order to keep your code clean and safe.

Usage

  • Kotlin: You can pick either of ktx or kapt.
  • Java: apt

Here's a minimum example, in which you register a MainActivity which requires Manifest.permission.CAMERA.

0. Prepare AndroidManifest

Add the following line to AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />

1. Attach annotations

PermissionsDispatcher introduces only a few annotations, keeping its general API concise:

NOTE: Annotated methods must not be private.

Annotation Required Description
@RuntimePermissions Register an Activity or Fragment to handle permissions
@NeedsPermission Annotate a method which performs the action that requires one or more permissions
@OnShowRationale Annotate a method which explains why the permissions are needed. It passes in a PermissionRequest object which can be used to continue or abort the current permission request upon user input. If you don't specify any argument for the method compiler will generate process${NeedsPermissionMethodName}ProcessRequest and cancel${NeedsPermissionMethodName}ProcessRequest. You can use those methods in place of PermissionRequest(ex: with DialogFragment)
@OnPermissionDenied Annotate a method which is invoked if the user doesn't grant the permissions
@OnNeverAskAgain Annotate a method which is invoked if the user chose to have the device "never ask again" about a permission
@RuntimePermissions
class MainActivity : AppCompatActivity(), View.OnClickListener {

    @NeedsPermission(Manifest.permission.CAMERA)
    fun showCamera() {
        supportFragmentManager.beginTransaction()
                .replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance())
                .addToBackStack("camera")
                .commitAllowingStateLoss()
    }

    @OnShowRationale(Manifest.permission.CAMERA)
    fun showRationaleForCamera(request: PermissionRequest) {
        showRationaleDialog(R.string.permission_camera_rationale, request)
    }

    @OnPermissionDenied(Manifest.permission.CAMERA)
    fun onCameraDenied() {
        Toast.makeText(this, R.string.permission_camera_denied, Toast.LENGTH_SHORT).show()
    }

    @OnNeverAskAgain(Manifest.permission.CAMERA)
    fun onCameraNeverAskAgain() {
        Toast.makeText(this, R.string.permission_camera_never_askagain, Toast.LENGTH_SHORT).show()
    }
}

2. Delegate to generated functions

Now generated functions become much more concise and intuitive than Java version!

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        findViewById(R.id.button_camera).setOnClickListener {
            // NOTE: delegate the permission handling to generated function
            showCameraWithPermissionCheck()
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        // NOTE: delegate the permission handling to generated function
        onRequestPermissionsResult(requestCode, grantResults)
    }

Check out the sample for more details.

Other features/plugins

Installation

NOTE:

  • If you're using jCenter we've moved on to MavenCentral, see migration guide.
  • 4.x only supports Jetpack. If you still use appcompat 3.x is the way to go.

To add PermissionsDispatcher to your project, include the following in your app module build.gradle file:

${latest.version} is Download

dependencies {
  implementation "com.github.permissions-dispatcher:permissionsdispatcher:${latest.version}"
  annotationProcessor "com.github.permissions-dispatcher:permissionsdispatcher-processor:${latest.version}"
}

With Kotlin:

apply plugin: 'kotlin-kapt'

dependencies {
  implementation "com.github.permissions-dispatcher:permissionsdispatcher:${latest.version}"
  kapt "com.github.permissions-dispatcher:permissionsdispatcher-processor:${latest.version}"
}

License

Copyright 2016 Shintaro Katafuchi, Marcel Schnelle, Yoshinori Isogai

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • android x support

    android x support

    See #488

    ~We need to wait bintray support gradle 4.6 or release this alpha version manually ✋~

    TODO

    • [x] Support androidx
    • [x] Drop support v4
    • [x] Handle the problem with bintray-release

    NOT TODO for this PR

    • Drop native fragment support
    opened by shiraji 33
  • Mechanism that delegate the check work to users

    Mechanism that delegate the check work to users

    ref: https://github.com/hotchemi/PermissionsDispatcher/issues/187

    This is definitely unexpected, but some devices like from Xiaomi need different check flow to get the state of permission. Currently we provide PermisisonUtils in library module, but I'm thinking to provide the following interface to allow users to put in their original logic.

    @RuntimePermission(checker = XiaomiChecker.class) // default value is PermisisonUtils.class
    class Some {
    }
    

    @aurae @shiraji What do you think?

    @a1018875550 Can you solve the problem with above interface?

    enhancement contributionwelcome proposal 
    opened by hotchemi 33
  • Error:Execution failed for task ':sample:clean'

    Error:Execution failed for task ':sample:clean'

    When I include PermissionsDispatcher code, my project fails to clean build with following error message:

    Error:Execution failed for task ':sample:clean'.

    Unable to delete file: C:\PermissionsDispatcher-master\PermissionsDispatcher-master\sample\build\intermediates\exploded-aar\PermissionsDispatcher-master\library\unspecified\jars\lint.jar

    If I remove this PermissionDispatcher code including from build.gradle file then everything working fine.

    opened by sanjaykumarm 31
  • OnNeverAskAgain and OnShowRationale are never called

    OnNeverAskAgain and OnShowRationale are never called

    The phone is htc m8sw,os version is android 6.0.1.I use your library,but both OnNeverAskAgain and OnShowRationale are never called. Library version is 2.1.0.Help me.

    inquiry 
    opened by whenan 30
  • Check permissions on xiaomi device with a version below api 23

    Check permissions on xiaomi device with a version below api 23

    As you know, Xiaomi devices have their own system of permissions. I'm testing my application on the device xiaomi redmi 3, api 22, android 5.1.1. I want to check if there is permission to access the camera and audio. boolean b = hasSelfPermissionForXiaomi(getActivity(),"android.permission.CAMERA");} `

    private boolean hasSelfPermissionForXiaomi(Context context,String permission){
    String permissionTop = AppOpsManagerCompat.permissionToOp(permission);
    if(permissionTop == null){
        // not dangerous
        return true;
    }
    int noteOp = AppOpsManagerCompat.noteOp(context,permissionTop, Process.myUid(),context.getPackageName());
    return noteOp == AppOpsManagerCompat.MODE_ALLOWED && checkSelfPermission(context,permission) == PackageManager.PERMISSION_GRANTED;}`
    

    b = true, although this is not true.

    inquiry 
    opened by sdroider 27
  • SupportV13MissingException when jack is enabled

    SupportV13MissingException when jack is enabled

    After enabling the Jack, Im getting permissions.dispatcher.processor.exception.SupportV13MissingException: PermissionsDispatcher for annotated class 'MyFragment' can't be generated, because the support-v13 dependency is missing on your project

    The v13 dependency is in place, it works fine if I switch back to apt plugin.

    bug contributionwelcome 
    opened by livotov 24
  • Add embedded lint checks to prevent direct access to permission-protected methods

    Add embedded lint checks to prevent direct access to permission-protected methods

    This enhancement is derived from #56, in which the OP asked for a more convenient way to use PermissionDispatcher's delegate pattern. In my opinion, it would make sense to embed custom lint checks that prevent users from directly invoking methods annotated with @NeedsPermission. Furthermore, another check would raise a warning (preferably an error) if the call to the delegate object's onRequestPermissionsResult() method is omitted in the respective Activity / Fragment method.

    @NeedsPermission(Manifest.permission.CAMERA)
    void useCamera() {
    }
    
    // Somewhere else...
    void onCameraButtonClicked() {
        this.useCamera();    // This line would raise a lint error ("Trying to access permission-protected method directly", for instance)
    }
    

    Futher reading (tools.android.com)

    enhancement contributionwelcome 
    opened by mannodermaus 23
  • add lint

    add lint

    see #59

    TODO

    • [x] Add a lint that checks calling @NeedsPermission method, directly
    • [x] Add a gradle task that injects lint.jar to PermissionsDispatcher

    NOT GOING TO DO

    Because they make this pull request huge and there are no test cases, I won't do followings for this pull request.

    • Add test cases
    • Add a lint that checks implementing onRequestPermissionsResult() except WRITE_SETTINGS or SYSTEM_ALERT_WINDOW
    • Add test cases for implementing onRequestPermissionsResult() except WRITE_SETTINGS or SYSTEM_ALERT_WINDOW
    • Add a lint that checks implementing onRequestPermissionsResult() except WRITE_SETTINGS or SYSTEM_ALERT_WINDOW in Activity (not Fragment since user may skip it in case it handles in another Fragment.)
    • Add test cases for implementing onActivityResult() if it's asking WRITE_SETTINGS or SYSTEM_ALERT_WINDOW in Activity
    opened by shiraji 22
  • [KTX] System dialog doesn't show up, after manually disable permission from setting

    [KTX] System dialog doesn't show up, after manually disable permission from setting

    Overview

    I've two permissions in my fragment (camera and storage) this is my code for them:

    private fun checkCameraPermission() {
            constructPermissionsRequest(
                    Manifest.permission.CAMERA,
                    onShowRationale = { request ->
                        showPermissionRationaleDialog(
                                Manifest.permission.CAMERA,
                                onAccept = { request.proceed() },
                                onDeny = { navigateHome() }
                        )
                    },
                    onPermissionDenied = {
                        navigateHome()
                    },
                    onNeverAskAgain = {
                        showPermissionNeverAskAgainDialog(
                                Manifest.permission.CAMERA,
                                onDeny = { navigateHome() }
                        )
                    }
            ) {
                showCamera()
            }.launch()
        }
    
        private fun checkStoragePermission() {
            constructPermissionsRequest(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    onShowRationale = { request ->
                        showPermissionRationaleDialog(
                            Manifest.permission.WRITE_EXTERNAL_STORAGE,
                            onAccept = { request.proceed() }
                        )
                    },
                    onNeverAskAgain = {
                        showPermissionNeverAskAgainDialog(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    }
            ) {
                saveFile()
            }.launch()
        }
    

    I'm calling checkCameraPermission() on my fragment's onStart() function. but there is a save button for calling checkStoragePermission(). Everything works great. until when I go to setting and manually disable storage permission from there. After returning to the fragment when I press the save button, Rationale shows up but when I accept button the system permission dialog doesn't show up. (I set a breakpoint and I saw that request.proceed() called. but It doesn't jump to the requiresPermission method.) The Strange part is that If I disable checkCameraPermission() from onStart() It will work.

    Expected

    System dialog shows up event after manually disabling permission from setting

    Actual

    System dialog doesn't show up, after manually disable permission from setting (when there is two permission checks on the fragment)

    Environment

    • Which library version are you using? ktx 1.0.1
    • On which devices do you observe the issue? all devices
    inquiry 
    opened by TurKurT656 21
  • Not working if build tool version is >=25

    Not working if build tool version is >=25

    Overview

    • I'm working on a android project with Build Tool Version 25.0.2 and added dependency for Permission Dispatcher. When i am building the project, library is not generating any Permission Dispatcher classes at all corresponding to any Activity or Fragments which has annotation @RuntimePermissions. It is working fine if Build tool version downgrades to <25.
    inquiry 
    opened by 3niman 20
  • NeedOnRequestPermissionsResult lint check is firing erroneously

    NeedOnRequestPermissionsResult lint check is firing erroneously

    After https://github.com/hotchemi/PermissionsDispatcher/pull/227 was merged and I bumped the version in app, it looks like there is a misfiring lint check.

    This is the check — NeedOnRequestPermissionsResult: Call the "onRequestPermissionsResult" method of the generated PermissionsDispatcher class in the respective method of your Activity or Fragment

    And here is code that it is triggering on:

        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions,
                int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            FooBarFragmentPermissionsDispatcher
                    .onRequestPermissionsResult(this, requestCode, grantResults);
        }
    

    So the call to the PermissionsDispatcher is actually happening but the lint check does not think it is.

    cc @eyedol @hotchemi @felipecsl

    bug contributionwelcome 
    opened by seanabraham 19
  • @OnNeverAskAgain called along with @NeedsPermission if we ask permission in onViewCreated() of Fragment

    @OnNeverAskAgain called along with @NeedsPermission if we ask permission in onViewCreated() of Fragment

    Overview

    When we are asking for permission on Fragment launch inside onViewCreated() method. Both @OnNeverAskAgain and @NeedsPermissionare getting called immediately. and if we are asking permission on some button click then it is working fine.

    Expected

    • It should not call @OnNeverAskAgain without any action along with @NeedsPermission

    Actual

    • On fragment launch, both @OnNeverAskAgain and @NeedsPermissionare getting called immediately.

    Environment

    • Which library version are you using? Current Version implementation 'com.github.permissions-dispatcher:permissionsdispatcher:4.9.2' kapt 'com.github.permissions-dispatcher:permissionsdispatcher-processor:4.9.2'

    • On which devices do you observe the issue? One Plus 7 Android 11 , Samsung M30 and other

    https://user-images.githubusercontent.com/25843884/190325927-54570126-6f24-4305-9c94-c59f034ca1e9.mov

    opened by satwinder07 0
  • Kotlin 1.7 Support

    Kotlin 1.7 Support

    We are trying to upgrade project code to Kotlin 1.7 however PermissionsDispatcher blocks us as it only supports Kotlin 1.5. Is there any plan to support Kotlin 1.7? Below is the error:

    Caused by: java.lang.IllegalArgumentException: Modifiers [PRIVATE] are not allowed on Kotlin parameters. Allowed modifiers: [VARARG, NOINLINE, CROSSINLINE]
    	at com.squareup.kotlinpoet.ParameterSpec.<init>(ParameterSpec.kt:41)
    	at com.squareup.kotlinpoet.ParameterSpec.<init>(ParameterSpec.kt:29)
    	at com.squareup.kotlinpoet.ParameterSpec$Builder.build(ParameterSpec.kt:157)
    	at com.squareup.kotlinpoet.FunSpec$Builder.addParameter(FunSpec.kt:500)
    	at permissions.dispatcher.processor.impl.kotlin.KotlinBaseProcessorUnit.createPermissionRequestClass(KotlinBaseProcessorUnit.kt:452)
    	at permissions.dispatcher.processor.impl.kotlin.KotlinBaseProcessorUnit.createPermissionRequestClasses(KotlinBaseProcessorUnit.kt:415)
    	at permissions.dispatcher.processor.impl.kotlin.KotlinBaseProcessorUnit.createFile(KotlinBaseProcessorUnit.kt:43)
    	at permissions.dispatcher.processor.impl.kotlin.KotlinBaseProcessorUnit.createFile(KotlinBaseProcessorUnit.kt:17)
    	at permissions.dispatcher.processor.PermissionsProcessor.processKotlin(PermissionsProcessor.kt:68)
    	at permissions.dispatcher.processor.PermissionsProcessor.process(PermissionsProcessor.kt:58)
    	at org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor.process(incrementalProcessors.kt:90)
    	at org.jetbrains.kotlin.kapt3.base.ProcessorWrapper.process(annotationProcessing.kt:197)
    	at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:980)
    
    
    opened by chenxiangcxc 11
  • Fix for issue 767 in forked repo

    Fix for issue 767 in forked repo

    Keep a strong reference to onNeverAskAgain to avoid the WeakRefence to it stored on PermissionRequestViewModel to become null when user denies permission multiple times. This should resolve #767 .

    opened by francescopedronomnys 0
  • [ktx] onNeverAskAgain not called

    [ktx] onNeverAskAgain not called

    Overview

    onNeverAskAgain callback is not called when "Don't ask again" is selected.

    Expected

    onNeverAskAgain callback is called, so I can show the appropriate UI.

    Actual

    onNeverAskAgain callback is not called.

    Environment

    • Running ktx-sample on API 29 and API 30, using ktx v1.1.3

    Investigation

    After debugging it, I can see that onNeverAskAgain: WeakReference<Fun>? is null in PermissionRequestViewModel.invoke(). After reading through the closed issues, I came across https://github.com/permissions-dispatcher/PermissionsDispatcher/issues/735. Wondering if the weakreference could be the issue? If I downgrade the ktx library to 1.0.4, onNeverAskAgain is successfully called.

    Reproducible steps

    https://user-images.githubusercontent.com/35034828/158357946-129980bf-6547-4228-82a4-a03399f88269.mp4

    opened by SammyOdenhoven 4
  • Change to use Fragment as a LifecycleOwner when PermissionRequester is constructed by Fragment

    Change to use Fragment as a LifecycleOwner when PermissionRequester is constructed by Fragment

    Resolves https://github.com/permissions-dispatcher/PermissionsDispatcher/issues/765

    Overview

    • Changed to use Fragment as a LifecycleOwner when PermissionRequester is constructed by Fragment
    • For Activity, it changes nothing (uses Activity as a LifecycleOwner just like before)

    GIFs

    Behaviors of sample app before | after -- | -- |

    opened by omtians9425 1
Releases(4.8.0)
Android library for permissions request (updated 27.11.2017)

NoPermission Simple Android library for permissions request. Consists of only one class. Why NoPermission: Not a framework. It's just one class Dialog

Alexey Bykov 105 Nov 15, 2022
Simplifying Android Permissions

Gota Libary With Android 6.0 Marshmallow, Google introduced a new permission model that allows users to better understand why an application may be re

Abdullah Alhazmy 73 Jul 24, 2022
Simplify Android M system permissions

EasyPermissions EasyPermissions is a wrapper library to simplify basic system permissions logic when targeting Android M or higher. Note: If your app

Google Samples 9.6k Nov 16, 2022
Ask Permission - Simple RunTime permission manager

Ask Permission https://kishanjvaghela.github.io/Ask-Permission/ Simple RunTime permission manager How to use Add url to your gradle file compile 'com.

Kishan Vaghela 77 Nov 18, 2022
Annotation based simple API flavored with AOP to handle new Android runtime permission model

Let Annotation based simple API flavoured with AOP to handle new Android runtime permission model. If you check Google's Samples about the new permiss

Can Elmas 530 Nov 25, 2022
Android runtime permissions powered by RxJava2

RxPermissions This library allows the usage of RxJava with the new Android M permission model. Setup To use this library your minSdkVersion must be >=

Thomas Bruyelle 10.4k Nov 25, 2022
Android Library to help you with your runtime Permissions.

PermissionHelper Android Library to help you with your runtime Permissions. Demo Android M Watch it in action. Pre M Watch it in action. Nexus 6 (M) N

Kosh Sergani 1.2k Nov 10, 2022
Easy way to handle all permissions

BestPermissionUtil You can read the story from here https://hamurcuabi.medium.com/permissions-with-the-easiest-way-9c466ab1b2c1 Prerequisites Add this

Emre Hamurcu 8 May 12, 2022
Runtime Mobile Security (RMS) 📱🔥 - is a powerful web interface that helps you to manipulate Android and iOS Apps at Runtime

Runtime Mobile Security (RMS) ?? ?? by @mobilesecurity_ Runtime Mobile Security (RMS), powered by FRIDA, is a powerful web interface that helps you to

Mobile Security 2k Nov 29, 2022
A declarative, Kotlin-idiomatic API for writing dynamic command line applications.

A declarative, Kotlin-idiomatic API for writing dynamic command line applications.

Varabyte 341 Nov 21, 2022
Kotter - aims to be a relatively thin, declarative, Kotlin-idiomatic API that provides useful functionality for writing delightful console applications.

Kotter (a KOTlin TERminal library) aims to be a relatively thin, declarative, Kotlin-idiomatic API that provides useful functionality for writing delightful console applications.

Varabyte 345 Nov 27, 2022
Android library which makes it easy to handle the different obstacles while calling an API (Web Service) in Android App.

API Calling Flow API Calling Flow is a Android library which can help you to simplify handling different conditions while calling an API (Web Service)

Rohit Surwase 19 Nov 9, 2021
Handle various HTTP status code by safe api call with Result sealed class

retrofit2-safe-api-call Handle various HTTP status code by safe api call with Result sealed class Library Retrofit2 OkHttp3 Gson Coroutine DI : Koin V

Jaesung Lee 2 May 16, 2022
GmailCompose is an Android application 📱 for showcasing Jetpack Compose for building declarative UI in Android.

GmailCompose GmailCompose Demo GmailCompose is an Android application ?? for showcasing Jetpack Compose for building declarative UI in Android. About

Baljeet Singh 36 Jul 27, 2022
{ } Declarative Kotlin DSL for choreographing Android transitions

Transition X Kotlin DSL for choreographing Android Transitions TransitionManager makes it easy to animate simple changes to layout without needing to

Arunkumar 519 Nov 10, 2022
A declarative framework for building efficient UIs on Android.

Litho Litho is a declarative framework for building efficient UIs on Android. Declarative: Litho uses a declarative API to define UI components. You s

Facebook 7.5k Nov 23, 2022
android project based on declarative UI (jetpack compose)

jetpack_compose_mvvm jetpack compose Coroutines and flows Dependency Injection with Koin Library. Model View Intent Architecture - MVI. Clean Architec

null 1 Apr 8, 2022
weiV(pronounced the same as wave), a new declarative UI development framework based on the Android View system.

weiV(pronounced the same as wave) 简体中文 if ("weiV" == "View".reversed()) { Log.d( "weiV", "It means Inversion of Control, you shoul

fangbing chen 68 Nov 14, 2022
Ivy FRP is a Functional Reactive Programming framework for declarative-style programming for Android

FRP (Functional Reactive Programming) framework for declarative-style programming for Andorid. :rocket: (compatible with Jetpack Compose)

null 7 Sep 7, 2022