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)
Open Liberty is a highly composable, fast to start, dynamic application server runtime environment

Summary A lightweight open framework for building fast and efficient cloud-native Java microservices: Open Liberty is fast to start up with low memory

Open Liberty Project 1k Dec 21, 2022
null 5 Jan 11, 2022
Jakarta money is a helpful library for a better developer experience when combining Money-API with Jakarta and MicroProfile API.

jakarta-money Jakarta money is a helpful library for a better developer experience when combining Money-API with Jakarta and MicroProfile API. The dep

Money and Currency API | JavaMoney 19 Aug 12, 2022
Screaming fast JSON parsing and serialization library for Android.

#LoganSquare The fastest JSON parsing and serializing library available for Android. Based on Jackson's streaming API, LoganSquare is able to consiste

BlueLine Labs 3.2k Dec 18, 2022
Android processing and secured library for managing SharedPreferences as key-value elements efficiently and structurally.

Memo Android processing and secured library for managing SharedPreferences as key-value elements efficiently and structurally. 1. Depend on our librar

ZeoFlow 18 Jun 30, 2022
Bu repositorie Google'ın tamamıyla ücretsiz olarak sunduğu Android Kotlin Fundamentals içeriğindeki projelerin tamamıdır.

Bu repositorie Google'ın tamamıyla ücretsiz olarak sunduğu Android Kotlin Fundamentals içeriğindeki projelerin tamamıdır. Kotlin ile Android geliştiriciliğine başlayacaklara önerilir.

Serkan Alc 15 Dec 2, 2022
✔️ Simple, pretty and powerful logger for android

Logger Simple, pretty and powerful logger for android Setup Download implementation 'com.orhanobut:logger:2.2.0' Initialize Logger.addLogAdapter(new A

Orhan Obut 13.5k Jan 5, 2023
Core part of Jackson that defines Streaming API as well as basic shared abstractions

Overview This project contains core low-level incremental ("streaming") parser and generator abstractions used by Jackson Data Processor. It also incl

FasterXML, LLC 2.1k Jan 1, 2023
Lean JSON Library for Java, with a compact, elegant API.

mJson is an extremely lightweight Java JSON library with a very concise API. The source code is a single Java file. The license is Apache 2.0. Because

Borislav Iordanov 77 Dec 25, 2022
Google Search Results JAVA API via SerpApi

Google Search Results JAVA API This Java package enables to scrape and parse Google, Bing and Baidu search results using SerpApi. Feel free to fork th

SerpApi 21 Dec 18, 2022
dOOv (Domain Object Oriented Validation) a fluent API for type-safe bean validation and mapping

dOOv (Domain Object Oriented Validation) dOOv is a fluent API for typesafe domain model validation and mapping. It uses annotations, code generation a

dOOv 77 Nov 20, 2022
Elide is a Java library that lets you stand up a GraphQL/JSON-API web service with minimal effort.

Elide Opinionated APIs for web & mobile applications. Read this in other languages: 中文. Table of Contents Background Documentation Install Usage Secur

Yahoo 921 Jan 3, 2023
A simple Plugin to allow server admins and user with Permissions to change fast and easy thier own Gamemode

A simple Plugin to allow server admins and user with Permissions to change fast and easy thier own Gamemode

Qubik Studios 1 Jan 17, 2022
Minecraft mod running on the TTCp engine to load modules written in JS at runtime - with runtime deobfuscation!

PolyFire ClickGUI opens with NUMROW_0 How to use: Run -jsmodules to initialize Navigate to your .minecraft folder Go to config/pf/modules/ Copy Exampl

Daniel H. 8 Nov 18, 2022
InterfaceMaker is a modern plugin to handle and customize join items, hotbars and menus with a developer and administrator friendly API.

Interface Maker InterfaceMaker is a modern plugin to handle and customize join items, hotbars and menus with a developer friendly API. Features Simple

2LStudios - Minecraft 10 Nov 27, 2022
A declarative mapping library to simplify testable object mappings.

ReMap - A declarative object mapper Table of Contents Long story short About ReMap Great News Mapping operations Validation Features Limitations The m

REMONDIS IT Services GmbH & Co. KG 103 Dec 27, 2022
MapNeat is a JVM library written in Kotlin that provides an easy to use DSL (Domain Specific Language) for transforming JSON to JSON, XML to JSON, POJO to JSON in a declarative way.

MapNeat is a JVM library written in Kotlin that provides an easy to use DSL (Domain Specific Language) for transforming JSON to JSON, XML to JSON, POJ

Andrei Ciobanu 59 Sep 17, 2022
Excel utility for Java to read and write data in declarative way.

Data Excel Exporter A Java wrapper using Apache POI to read and write Excel file in declarative fashion. Installation ExcelUtil is using Apache POI ve

null 27 Oct 16, 2022
Simple, declarative mail utility for sending mails with default smtp server or with custom channels.

Introduction email-util is simple, declarative utility library. Key features are: declarative email building; text or html rendering; annotation suppo

Nijat Asgarzada 3 Oct 12, 2021