Runtime
Permissions
Handling with
EasyPermissions
Android Sandbox
Android permissions model
System Resources
(Contacts, GPS, Bluetooth, SMS, Network.. etc.)
Permissions
Access Rules
Permissions protection levels
Normal permissions
Dangerous permissions
Signature permissions
Special permissions
Permissions protection levels
Normal permissions
Dangerous permissions
Signature permissions
Special permissions
WAKE_LOCK, BLUETOOTH,
ACCESS_NETWORK_STATE,
SET_TIME_ZONE, VIBRATE,
INTERNET, SET_WALLPAPER,
NFC.
Permissions protection levels
Normal permissions
Dangerous permissions
Signature permissions
Special permissions
CAMERA,
CONTACTS,
LOCATION, PHONE,
CALENDAR, SMS,
STORAGE, SENSOR
Permissions protection levels
Normal permissions
Dangerous permissions
Signature permissions
Special permissions
READ_VOICEMAIL,
WRITE_VOICEMAIL,
BIND_PRINT_SERVICE
Permissions protection levels
Normal permissions
Dangerous permissions
Signature permissions
Special permissions
WRITE_SETTINGS,
SYSTEM_ALERT_WINDOW
Requesting permissions
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.fancy.package.name">
<!-- Normal permssions -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Dangerous permissions -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<application ...>
...
</application>
</manifest>
Requesting permissions
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.fancy.package.name">
<!-- Normal permssions -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Dangerous permissions -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<application ...>
...
</application>
</manifest>
Requesting permissions
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.fancy.package.name">
<!-- Normal permssions -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Dangerous permissions -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<application ...>
...
</application>
</manifest>
Requesting permissions
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.fancy.package.name">
<!-- Normal permssions -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Dangerous permissions -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<application ...>
...
</application>
</manifest>
Install-time requests
(Android 5.1.1 or below)
Requesting permissions
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.fancy.package.name">
<!-- Normal permssions -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Dangerous permissions -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<application ...>
...
</application>
</manifest>
Runtime requests (Android 6.0 or higher)
class PermissionActivity : AppCompatActivity(){
private fun readContacts() {
// Check whether the permission has already been granted
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.READ_CONTACTS)) {
// Show the explanation dialog
} else {
// No explanation needed, request the permission
ActivityCompat.requestPermissions(context, arrayOf(Manifest.permission.READ_CONTACTS), RC_READ_CONTACTS)
}
} else {
// Permission has already been granted, Do the contacts-related task you need to do.
}
}
}
Requesting permissions
Ref: https://developer.android.com/training/permissions/requesting.html
class PermissionActivity : AppCompatActivity(){
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
RC_READ_CONTACTS -> {
// If request is cancelled, the result arrays are empty.
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// Permission was granted, yay! Do the contacts-related task you need to do.
} else {
// Permission denied, boo! Disable the functionality that depends on this permission.
}
return
}
...
else -> {
// Ignore all other requests.
}
}
}
}
Handling permissions request results
Ref: https://developer.android.com/training/permissions/requesting.html
EasyPermissions
EasyPermissions
❏ Open Source library by Google developers
❏ Simplify basic runtime permissions logic
❏ Works with Activities and Fragments
❏ Offers @AfterPermissionGranted annotation
❏ Offers control over rationale dialog
❏ Works with kotlin
❏ Great support community
EasyPermissions
class PermissionActivity : AppCompatActivity(){
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
RC_READ_CONTACTS -> {
// If request is cancelled, the result arrays are empty.
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// Permission was granted, yay! Do the contacts-related task you need to do.
} else {
// Permission denied, boo! Disable the functionality that depends on this permission.
}
return
}
...
else -> {
// Ignore all other requests.
}
}
}
}
EasyPermissions
class PermissionActivity : AppCompatActivity(){
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
// Forward results to EasyPermissions
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
}
}
EasyPermissions
class PermissionActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks {
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
// Forward results to EasyPermissions
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
}
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
// Some permissions have been granted
}
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
// Some permissions have been denied
}
}
EasyPermissions
class PermissionActivity : AppCompatActivity(){
private fun readContacts() {
// Check whether the permission has already been granted
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.READ_CONTACTS)) {
// Show the explanation dialog
} else {
// No explanation needed, request the permission
ActivityCompat.requestPermissions(context, arrayOf(Manifest.permission.READ_CONTACTS), RC_READ_CONTACTS)
}
} else {
// Permission has already been granted, Do the contacts-related task you need to do.
}
}
}
EasyPermissions
class PermissionActivity : AppCompatActivity(){
private fun readContact() {
// Check whether the permission has already been granted
if (EasyPermissions.hasPermissions(context!!, Manifest.permission.READ_CONTACTS)){
// Permission has already been granted, Do the contacts-related task you need to do.
} else{
// Permission not granted, request it now
EasyPermissions.requestPermissions(this, R.string.read_contact_rationale, RC_CONTACTS_PERM,
Manifest.permission.READ_CONTACTS)
}
}
}
EasyPermissions
class PermissionActivity : AppCompatActivity(){
@AfterPermissionGranted(RC_CAMERA_AND_LOCATION)
private fun requestMultiplePermissionss() {
val perms = arrayOf(Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION)
// Check whether the permission has already been granted
if (EasyPermissions.hasPermissions(this, *perms)){
// Permission has already been granted, Do the camera with location related task you need to do.
} else{
// Permissions not granted, request them now
EasyPermissions.requestPermissions(
PermissionRequest.Builder(this, RC_CAMERA_AND_LOCATION, *perms)
.setRationale(R.string.camera_and_location_rationale)
.setPositiveButtonText(R.string.rationale_ask_ok)
.setNegativeButtonText(R.string.rationale_ask_cancel)
.setTheme(R.style.my_fancy_style)
.build())
}
}
}
EasyPermissions
class PermissionActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks {
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
// Forward results to EasyPermissions
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
}
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
// Some permissions have been granted
}
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
// Some permissions have been denied
}
}
EasyPermissions
class PermissionActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks {
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
// Some permissions have been denied
…
// Check whether the user denied any permissions and checked "NEVER ASK AGAIN."
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
// This will display a dialog directing them to enable the permission in app settings.
AppSettingsDialog.Builder(this).build().show()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {
// Do something after user returned from app settings screen, like showing a Toast.
}
}
}
EasyPermissions
class PermissionActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks {
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
// Some permissions have been denied
…
// Check whether the user denied any permissions and checked "NEVER ASK AGAIN."
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
// This will display a dialog directing them to enable the permission in app settings.
AppSettingsDialog.Builder(this).build().show()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {
// Do something after user returned from app settings screen, like showing a Toast.
}
}
}
EasyPermissions
class PermissionActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks {
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
// Some permissions have been denied
…
// Check whether the user denied any permissions and checked "NEVER ASK AGAIN."
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
// This will display a dialog directing them to enable the permission in app settings.
AppSettingsDialog.Builder(this).build().show()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {
// Do something after user returned from app settings screen, like showing a Toast.
}
}
}
EasyPermissions
class PermissionActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks, EasyPermissions.RationaleCallbacks {
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
// Some permissions have been granted
}
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
// Some permissions have been denied
}
override fun onRationaleDenied(requestCode: Int) {
// Some permissions rationale denied
// ...
}
override fun onRationaleAccepted(requestCode: Int) {
// Some permissions rationale accepted
// ...
}
}
EasyPermissions
class PermissionActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks, EasyPermissions.RationaleCallbacks {
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
// Some permissions have been granted
}
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
// Some permissions have been denied
}
override fun onRationaleDenied(requestCode: Int) {
// Some permissions rationale denied
// ...
}
override fun onRationaleAccepted(requestCode: Int) {
// Some permissions rationale accepted
// ...
}
}
EasyPermissions
DEMO
References
Android app permissions:
https://developer.android.com/guide/topics/permissions/index.html
EasyPermissions
https://github.com/googlesamples/easypermissions
Demo
https://github.com/GDG-Trondheim/runtimepermissions
Thank You
Q&A
twitter.com/ernestkamara | ernest@kamara.io | www.kamara.io

Runtime permissions handling with easy permissions

  • 1.
  • 2.
    Android Sandbox Android permissionsmodel System Resources (Contacts, GPS, Bluetooth, SMS, Network.. etc.) Permissions Access Rules
  • 3.
    Permissions protection levels Normalpermissions Dangerous permissions Signature permissions Special permissions
  • 4.
    Permissions protection levels Normalpermissions Dangerous permissions Signature permissions Special permissions WAKE_LOCK, BLUETOOTH, ACCESS_NETWORK_STATE, SET_TIME_ZONE, VIBRATE, INTERNET, SET_WALLPAPER, NFC.
  • 5.
    Permissions protection levels Normalpermissions Dangerous permissions Signature permissions Special permissions CAMERA, CONTACTS, LOCATION, PHONE, CALENDAR, SMS, STORAGE, SENSOR
  • 6.
    Permissions protection levels Normalpermissions Dangerous permissions Signature permissions Special permissions READ_VOICEMAIL, WRITE_VOICEMAIL, BIND_PRINT_SERVICE
  • 7.
    Permissions protection levels Normalpermissions Dangerous permissions Signature permissions Special permissions WRITE_SETTINGS, SYSTEM_ALERT_WINDOW
  • 8.
    Requesting permissions <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.fancy.package.name"> <!--Normal permssions --> <uses-permission android:name="android.permission.INTERNET"/> <!-- Dangerous permissions --> <uses-permission android:name="android.permission.READ_CONTACTS"/> <application ...> ... </application> </manifest>
  • 9.
    Requesting permissions <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.fancy.package.name"> <!--Normal permssions --> <uses-permission android:name="android.permission.INTERNET"/> <!-- Dangerous permissions --> <uses-permission android:name="android.permission.READ_CONTACTS"/> <application ...> ... </application> </manifest>
  • 10.
    Requesting permissions <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.fancy.package.name"> <!--Normal permssions --> <uses-permission android:name="android.permission.INTERNET"/> <!-- Dangerous permissions --> <uses-permission android:name="android.permission.READ_CONTACTS"/> <application ...> ... </application> </manifest>
  • 11.
    Requesting permissions <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.fancy.package.name"> <!--Normal permssions --> <uses-permission android:name="android.permission.INTERNET"/> <!-- Dangerous permissions --> <uses-permission android:name="android.permission.READ_CONTACTS"/> <application ...> ... </application> </manifest> Install-time requests (Android 5.1.1 or below)
  • 12.
    Requesting permissions <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="your.fancy.package.name"> <!--Normal permssions --> <uses-permission android:name="android.permission.INTERNET"/> <!-- Dangerous permissions --> <uses-permission android:name="android.permission.READ_CONTACTS"/> <application ...> ... </application> </manifest> Runtime requests (Android 6.0 or higher)
  • 13.
    class PermissionActivity :AppCompatActivity(){ private fun readContacts() { // Check whether the permission has already been granted if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.READ_CONTACTS)) { // Show the explanation dialog } else { // No explanation needed, request the permission ActivityCompat.requestPermissions(context, arrayOf(Manifest.permission.READ_CONTACTS), RC_READ_CONTACTS) } } else { // Permission has already been granted, Do the contacts-related task you need to do. } } } Requesting permissions Ref: https://developer.android.com/training/permissions/requesting.html
  • 14.
    class PermissionActivity :AppCompatActivity(){ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { when (requestCode) { RC_READ_CONTACTS -> { // If request is cancelled, the result arrays are empty. if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { // Permission was granted, yay! Do the contacts-related task you need to do. } else { // Permission denied, boo! Disable the functionality that depends on this permission. } return } ... else -> { // Ignore all other requests. } } } } Handling permissions request results Ref: https://developer.android.com/training/permissions/requesting.html
  • 15.
  • 16.
    EasyPermissions ❏ Open Sourcelibrary by Google developers ❏ Simplify basic runtime permissions logic ❏ Works with Activities and Fragments ❏ Offers @AfterPermissionGranted annotation ❏ Offers control over rationale dialog ❏ Works with kotlin ❏ Great support community
  • 17.
    EasyPermissions class PermissionActivity :AppCompatActivity(){ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { when (requestCode) { RC_READ_CONTACTS -> { // If request is cancelled, the result arrays are empty. if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { // Permission was granted, yay! Do the contacts-related task you need to do. } else { // Permission denied, boo! Disable the functionality that depends on this permission. } return } ... else -> { // Ignore all other requests. } } } }
  • 18.
    EasyPermissions class PermissionActivity :AppCompatActivity(){ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) // Forward results to EasyPermissions EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) } }
  • 19.
    EasyPermissions class PermissionActivity :AppCompatActivity(), EasyPermissions.PermissionCallbacks { override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) // Forward results to EasyPermissions EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) } override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) { // Some permissions have been granted } override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) { // Some permissions have been denied } }
  • 20.
    EasyPermissions class PermissionActivity :AppCompatActivity(){ private fun readContacts() { // Check whether the permission has already been granted if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.READ_CONTACTS)) { // Show the explanation dialog } else { // No explanation needed, request the permission ActivityCompat.requestPermissions(context, arrayOf(Manifest.permission.READ_CONTACTS), RC_READ_CONTACTS) } } else { // Permission has already been granted, Do the contacts-related task you need to do. } } }
  • 21.
    EasyPermissions class PermissionActivity :AppCompatActivity(){ private fun readContact() { // Check whether the permission has already been granted if (EasyPermissions.hasPermissions(context!!, Manifest.permission.READ_CONTACTS)){ // Permission has already been granted, Do the contacts-related task you need to do. } else{ // Permission not granted, request it now EasyPermissions.requestPermissions(this, R.string.read_contact_rationale, RC_CONTACTS_PERM, Manifest.permission.READ_CONTACTS) } } }
  • 22.
    EasyPermissions class PermissionActivity :AppCompatActivity(){ @AfterPermissionGranted(RC_CAMERA_AND_LOCATION) private fun requestMultiplePermissionss() { val perms = arrayOf(Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION) // Check whether the permission has already been granted if (EasyPermissions.hasPermissions(this, *perms)){ // Permission has already been granted, Do the camera with location related task you need to do. } else{ // Permissions not granted, request them now EasyPermissions.requestPermissions( PermissionRequest.Builder(this, RC_CAMERA_AND_LOCATION, *perms) .setRationale(R.string.camera_and_location_rationale) .setPositiveButtonText(R.string.rationale_ask_ok) .setNegativeButtonText(R.string.rationale_ask_cancel) .setTheme(R.style.my_fancy_style) .build()) } } }
  • 23.
    EasyPermissions class PermissionActivity :AppCompatActivity(), EasyPermissions.PermissionCallbacks { override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) // Forward results to EasyPermissions EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) } override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) { // Some permissions have been granted } override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) { // Some permissions have been denied } }
  • 24.
    EasyPermissions class PermissionActivity :AppCompatActivity(), EasyPermissions.PermissionCallbacks { override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) { // Some permissions have been denied … // Check whether the user denied any permissions and checked "NEVER ASK AGAIN." if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { // This will display a dialog directing them to enable the permission in app settings. AppSettingsDialog.Builder(this).build().show() } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) { // Do something after user returned from app settings screen, like showing a Toast. } } }
  • 25.
    EasyPermissions class PermissionActivity :AppCompatActivity(), EasyPermissions.PermissionCallbacks { override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) { // Some permissions have been denied … // Check whether the user denied any permissions and checked "NEVER ASK AGAIN." if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { // This will display a dialog directing them to enable the permission in app settings. AppSettingsDialog.Builder(this).build().show() } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) { // Do something after user returned from app settings screen, like showing a Toast. } } }
  • 26.
    EasyPermissions class PermissionActivity :AppCompatActivity(), EasyPermissions.PermissionCallbacks { override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) { // Some permissions have been denied … // Check whether the user denied any permissions and checked "NEVER ASK AGAIN." if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { // This will display a dialog directing them to enable the permission in app settings. AppSettingsDialog.Builder(this).build().show() } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) { // Do something after user returned from app settings screen, like showing a Toast. } } }
  • 27.
    EasyPermissions class PermissionActivity :AppCompatActivity(), EasyPermissions.PermissionCallbacks, EasyPermissions.RationaleCallbacks { override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) { // Some permissions have been granted } override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) { // Some permissions have been denied } override fun onRationaleDenied(requestCode: Int) { // Some permissions rationale denied // ... } override fun onRationaleAccepted(requestCode: Int) { // Some permissions rationale accepted // ... } }
  • 28.
    EasyPermissions class PermissionActivity :AppCompatActivity(), EasyPermissions.PermissionCallbacks, EasyPermissions.RationaleCallbacks { override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) { // Some permissions have been granted } override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) { // Some permissions have been denied } override fun onRationaleDenied(requestCode: Int) { // Some permissions rationale denied // ... } override fun onRationaleAccepted(requestCode: Int) { // Some permissions rationale accepted // ... } }
  • 29.
  • 30.
  • 31.
    Thank You Q&A twitter.com/ernestkamara |ernest@kamara.io | www.kamara.io