Peko

Additional

Language
Kotlin
Version
N/A
Created
Feb 23, 2018
Updated
Apr 22, 2018
Owner
Marko Devcic (deva666)
Contributors
Marko Devcic (deva666)
lucasvalenteds
2
Activity
Badge
Generate
Download
Source code
APK file

Show card

PEKO

PErmissions in KOtlin

Android Permissions with Kotlin Coroutines

No more callbacks, builders, listeners or verbose code for requesting Android permissions. Get Permission Request Result asynchronously with one function call. Thanks to Kotlin Coroutines, permissions requests are async and lightweight (no new threads are used/created).


Installation

Add jcenter repository

compile 'com.markodevcic.peko:peko:0.3'

Example in Android Activity:

launch (UI) {
    val permissionResultDeferred = Peko.requestPermissionsAsync(this, Manifest.permission.BLUETOOTH, Manifest.permission.WRITE_EXTERNAL_STORAGE) 
    val (grantedPermissions) = permissionResultDeferred.await()
    
    if (Manifest.permission.BLUETOOTH in grantedPermissions) {
        //we have Bluetooth permission
    } else {
        //no Bluetooth permission
    }
}

Screen rotations

Library has support for screen rotations. When activity get's recreated, coroutines that have not completed yet, have to be cancelled to avoid memory leaks. When you detect a orientation change, cancel the coroutine with an instance of ActivityRotatingException. Internally, this will retain the current request that is in progress. The Deferred can then be awaited again by calling Peko.resultDeferred.

Example:

First:

//job that will be cancelled in onDestroy
private val job = Job()

private fun requestPermission(vararg permissions: String) {
    launch(job + UI) { // combine job with UI context
        val result = Peko.requestPermissionsAsync(this@MainActivity, *permissions).await()
        setResults(result)
    }
}

Then in onDestroy of Activity:

if (isChangingConfigurations) {
    job.cancel(ActivityRotatingException()) //screen rotation, retain the results
} else { 
    job.cancel() //no rotation, just cancel the coroutine
}

And when activity get's recreated in onCreate function:

//check if we have a request already (or some other way you detect screen orientation)
if (Peko.isRequestInProgress()) {
    launch (UI) {
        //get the existing request and await the result
        val result = Peko.resultDeferred!!.await()
        setResults(result)
    }
}

Permission Rationales

If you want to show a permission rationale to the user, you can use the built in AlertDialogPermissionRationale. This will show an Alert Dialog with your message and title, explaining to user why this rationale is needed. It will be shown only once and only if user denies the permission for the first time.

val rationale = AlertDialogPermissionRationale(this@MainActivity) {
    this.setTitle("Need permissions")
    this.setMessage("Please give permissions to use this feature") 
}

launch (UI) {
    val permissionResult = Peko.requestPermissionsAsync(this, Manifest.permission.BLUETOOTH, rationale = rationale).await()
}

There is also a SnackBarRationale class that shows a SnackBar when permission rationale is required.

val snackBar = Snackbar.make(rootView, "Permissions needed to continue", Snackbar.LENGTH_LONG)
val snackBarRationale = SnackBarRationale(snackBar, actionTitle = "Request again")

launch(UI) {
    val permissionResult = Peko.requestPermissionsAsync(this@MainActivity, *permissions, rationale = snackBarRationale).await()
}

You can also show your own implementation of Permission Rationale to the user. Just implement the interface PermissionRationale. If true is returned from suspend function shouldRequestAfterRationaleShownAsync, permissions will be asked for again, otherwise the request completes and returns the current permission result.

License

Copyright 2018 Marko Devcic

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.