Giter VIP home page Giter VIP logo

eazypermissions's Introduction

Eazy Runtime Permission

License Pull request API ktlint Android Arsenal

A lightweight Android library which wraps boilerplate code of runtime permission and allows you to request permissions

  1. from coroutines. (No callbacks yay ๐ŸŽ‰)
  2. request and observe permissions through LiveData.
  3. through clean and concise Kotlin DSL.

From release 2.0.0 onwards library is migrated to AndroidX. If you are still using support library and haven't migrated to AndroidX then check out non-androidX version of the library.

Including in your project

Eazy permissions is available in the Jcenter and divided into three modules so that based on your need you can include either coroutines or livedata or Kotlin DSL support in your project

//For coroutines
implementation 'com.sagar:coroutinespermission:[latest_version]'

//For LiveData
implementation 'com.sagar:livedatapermission:[latest_version]'

//For Kotlin DSL
implementation 'com.sagar:dslpermission:[latest_version]'
  • latest_version for coroutines - Download
  • latest_version for livedata - Download
  • latest_version for Kotlin DSL - Download

Coroutines support

This is how you would request permission within coroutines.

.
.
.
launch {
    //CoroutineScope

    val permissionResult = PermissionManager.requestPermissions(           //Suspends the coroutine
                            this@Fragment,                                  
                            REQUEST_ID,
                            Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.READ_CONTACTS,
                            Manifest.permission.CAMERA
                        )
                        
    //Resume coroutine once result is ready
    when(permissionResult) {
        is PermissionResult.PermissionGranted -> {
            //Add your logic here after user grants permission(s)
        }
        is PermissionResult.PermissionDenied -> {
            //Add your logic to handle permission denial
        }
        is PermissionResult.PermissionDeniedPermanently -> {
            //Add your logic here if user denied permission(s) permanently.
            //Ideally you should ask user to manually go to settings and enable permission(s)
        }
        is PermissionResult.ShowRational -> {
            //If user denied permission frequently then she/he is not clear about why you are asking this permission.
            //This is your chance to explain them why you need permission.
        }
    }

}

Read more about coroutines support here

Kotlin DSL support

This is how you would request permission through clean and concise Kotlin DSL.

requestPermissions(
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.READ_CONTACTS,
    Manifest.permission.CAMERA
) {
    requestCode = 4
    resultCallback = {
        when(this) {
            is PermissionResult.PermissionGranted -> {
                //Add your logic here after user grants permission(s)
            }
            is PermissionResult.PermissionDenied -> {
                //Add your logic to handle permission denial
            }
            is PermissionResult.PermissionDeniedPermanently -> {
                //Add your logic here if user denied permission(s) permanently.
                //Ideally you should ask user to manually go to settings and enable permission(s)
            }
            is PermissionResult.ShowRational -> {
                //If user denied permission frequently then she/he is not clear about why you are asking this permission.
                //This is your chance to explain them why you need permission.
            }
        }
    }
}

Read more about Kotlin DSL support here

LiveData support

This is how you would request permission within Acivity/Fragment.

PermissionManager.requestPermissions(
                this,
                REQUEST_ID,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.READ_CONTACTS
            )

Observing permission result requires your Actvity/Fragment to implement PermissionObserver

/**
 * Interface definition for a callback to get [LiveData] of [PermissionResult]
 *
 * Implement this interface to get [LiveData] for observing permission request result.
 */
interface PermissionObserver {
    fun setupObserver(permissionResultLiveData: LiveData<PermissionResult>)
}

Just as you would observe other LiveData you can observe LiveData<PermissionResult> as follow.

override fun setupObserver(permissionResultLiveData: LiveData<PermissionResult>) {
    permissionResultLiveData.observe(this, Observer<PermissionResult> {
        when (it) {
            is PermissionResult.PermissionGranted -> {
                if (it.requestId == REQUEST_ID) {
                    //Add your logic here after user grants permission(s)
                }
            }
            is PermissionResult.PermissionDenied -> {
                if (it.requestId == REQUEST_ID) {
                    //Add your logic to handle permission denial
                }
            }
            is PermissionResult.PermissionDeniedPermanently -> {
                if (it.requestId == REQUEST_ID) {
                    //Add your logic here if user denied permission(s) permanently.
                    //Ideally you should ask user to manually go to settings and enable permission(s)
                }
            }
            is PermissionResult.ShowRational -> {
                if (it.requestId == REQUEST_ID) {
                    //If user denied permission frequently then she/he is not clear about why you are asking this permission.
                    //This is your chance to explain them why you need permission.
                }
            }
        }
    })
}

Read more about LiveData support here

Contributing

Have suggestions for improvements and want to contribute? or Found any issues?
Head over to Contribution guidelines to know more about contributing to this library.

Screenshots of sample

sc1 sc2
sc1 sc2

License

Copyright 2019 Sagar Viradiya

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.

eazypermissions's People

Contributors

neetigyachahar avatar sagar-viradiya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

eazypermissions's Issues

Memory leak in Fragment

This is how I use this library to requestPermissions in a Fragment:

    private fun showQrCodeCamera() {
        CoroutineScope(Job() + Dispatchers.Default).launch {
            withContext(Dispatchers.Main) {
                val permissionResult = PermissionManager.requestPermissions(
                    this@presentationFragment,
                    4,
                    Manifest.permission.CAMERA
                )
                when (permissionResult) {
                    is PermissionResult.PermissionGranted -> {
                        codeScanner.apply {
                            startPreview()
                        }
                    }
                    else -> {
                        showSnackBar(getString(R.string.camera_permission_denied))
                    }
                }
            }
        }
    }

And LeakCanary detects this as a leak:


โ”ฌโ”€โ”€โ”€
โ”‚ GC Root: Java local variable
โ”‚
โ”œโ”€ kotlinx.coroutines.scheduling.CoroutineScheduler$Worker thread
โ”‚    Leaking: UNKNOWN
โ”‚    Thread name: 'DefaultDispatcher-worker-3'
โ”‚    โ†“ CoroutineScheduler$Worker.<Java Local>
โ”‚                                ~~~~~~~~~~~~
โ”œโ”€ kotlinx.coroutines.DispatchedContinuation instance
โ”‚    Leaking: UNKNOWN
โ”‚    โ†“ DispatchedContinuation.callerFrame
โ”‚                             ~~~~~~~~~~~
โ”œโ”€ com.examplee.presentationFragment$showQrCodeCamera$1 instance
โ”‚    Leaking: UNKNOWN
โ”‚    Anonymous subclass of kotlin.coroutines.jvm.internal.SuspendLambda
โ”‚    โ†“ presentationFragment$showQrCodeCamera$1.this$0
โ”‚                                         ~~~~~~
โ•ฐโ†’ com.examplee.presentationFragment instance
โ€‹     Leaking: YES (ObjectWatcher was watching this because com.examplee.presentationFragment received Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
โ€‹     key = 9f1a985f-899f-45ae-a526-3da8a630f1a2
โ€‹     watchDurationMillis = 41787
โ€‹     retainedDurationMillis = 36786

METADATA

Build.VERSION.SDK_INT: 29
Build.MANUFACTURER: Google
LeakCanary version: 2.4
App process name: com.example.dev
Analysis duration: 12284 ms

README enhancements

Move the introduction to Coroutines, LiveData and Kotlin DSL in the individual README file within the respective module.

Move to MavenCentral

Hi,

As JCenter will be closed, is it possible to reupload your library to MavenCentral?

Kotlin DSL support

Add support for Kotlin DSL for those who just want to consume lib without coroutines and LiveData.

lateinit property completableDeferred has not been initialized

While testing the library I ran into this issue (p.s. the library is awesome ๐Ÿ‘):

Caused by kotlin.UninitializedPropertyAccessException: lateinit property completableDeferred has not been initialized
       at com.eazypermissions.coroutinespermission.PermissionManager.onDestroy + 113(PermissionManager.kt:113)
       at androidx.fragment.app.Fragment.performDestroy + 2825(Fragment.java:2825)
       at androidx.fragment.app.FragmentManagerImpl.moveToState + 1028(FragmentManagerImpl.java:1028)
       at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState + 1238(FragmentManagerImpl.java:1238)
       at androidx.fragment.app.FragmentManagerImpl.moveToState + 1303(FragmentManagerImpl.java:1303)
       at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange + 2656(FragmentManagerImpl.java:2656)
       at androidx.fragment.app.FragmentManagerImpl.dispatchDestroy + 2641(FragmentManagerImpl.java:2641)
       at androidx.fragment.app.FragmentController.dispatchDestroy + 329(FragmentController.java:329)
       at androidx.fragment.app.FragmentActivity.onDestroy + 366(FragmentActivity.java:366)
       at androidx.appcompat.app.AppCompatActivity.onDestroy + 233(AppCompatActivity.java:233)
...

grantedPermissions on PermissionResult.PermissionGranted is required..

Hi Segar,
deniedPermissions is available on PermissionResult.PermissionDenied.
Why don't you support grantedPermissions on PermissionResult.PermissionGranted and something on PermissionResult.ShowRational?
I need to separately handle each permission.
It would be helpful if it is supported.

Crash in requestPermissions()

Used your code in a new Android application:

 requestPermissions(Manifest.permission.ACCESS_FINE_LOCATION) {
            requestCode = 1
            resultCallback = {
                handlePermissionsResult(this)
            }
        }


It crashes with:
java.lang.NoSuchMethodError: No virtual method getRequestCode()I in class Lcom/eazypermissions/common/model/PermissionResult; or its super classes (declaration of 'com.eazypermissions.common.model.PermissionResult' appears in base.apk)
at com.eazypermissions.dsl.PermissionManager.onPermissionResult(PermissionManager.kt:35)
at com.eazypermissions.common.BasePermissionManager.requestPermissions(BasePermissionManager.kt:82)
at com.eazypermissions.dsl.PermissionManager.access$requestPermissions(PermissionManager.kt:30)
at com.eazypermissions.dsl.PermissionManager$Companion._requestPermissions(PermissionManager.kt:129)

The "requestCode" is shown as unresolved in

override fun onPermissionResult(permissionResult: PermissionResult) {
        callbackMap[permissionResult.requestCode]?.let {
            permissionResult.it()
        }
        callbackMap.remove(permissionResult.requestCode)
    }

ERROR: Failed to resolve: com.sagar:common:2.0.2

Can't build project with version 2.0.2, because of:
ERROR: Failed to resolve: com.sagar:common:2.0.2

dependencies{ ... implementation 'com.sagar:coroutinespermission:2.0.2' ... }

Version 2.0.1 works correctly, but I need to update because of #18

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.