easypermissions icon indicating copy to clipboard operation
easypermissions copied to clipboard

Rationale callback when not using Fragment or Activity

Open Dkhusainov opened this issue 6 years ago • 10 comments

Basic Information

Device type: ________ OS version: 25 EasyPermissions version: 1.0.1

Describe the problem

What happened?
I don't use Fragment or Activity as my PermissionCallback. If the user denies rationale, I don't get the callback in onRequestPermissionsResult

What did you expect to happen? Get the callback

Dkhusainov avatar May 24 '18 09:05 Dkhusainov

@Dkhusainov can you show the code that you're using to request permissions and some of the class where you expect to get the callback?

samtstern avatar May 30 '18 17:05 samtstern

My "PermissionService" implements PermissionCallbacks, then I just delegate onRequestPermissionsResult callback manually from Activity

Dkhusainov avatar May 31 '18 08:05 Dkhusainov

@Dkhusainov please show the code where you request permissions and how you "delegate" the callback.

samtstern avatar May 31 '18 14:05 samtstern

image

image

act variable is an Activity from which I delegate the callback

Dkhusainov avatar Jun 04 '18 15:06 Dkhusainov

@Dkhusainov I don't think this is a good idea, Service classes should not hold references to Activities. Also permissions should only be requested when the user is inside of your app, which means you should have an Activity or Fragment context at that time.

So I don't think EasyPermissions should support this request.

samtstern avatar Jun 11 '18 15:06 samtstern

  1. It's not an android Service. Just a class that I suffixed with Service
  2. Obviously I have activitity context, otherwiouse how would I request permissions?

I simply ask you to maybe overload EasyPermissions and add another param(explicit PermissionCallbacks), instead of casting things left and right the usual Google/Android way.

image

Dkhusainov avatar Jun 14 '18 11:06 Dkhusainov

Any updates on this issue?

Dkhusainov avatar Nov 01 '18 15:11 Dkhusainov

Any updates on this issue?

aantoniv avatar Apr 01 '19 09:04 aantoniv

I ended up just using this hack. Hope this helps anyone

  private val main = Handler(Looper.getMainLooper())

  inline fun <reified T> Any.castOrNull(): T? = if (this is T) this else null
  fun Any.getFieldValue(name: String): Any? {
    val cls = this::class.java
    val obj = this
    return cls.getDeclaredField(name).run {
      isAccessible = true
      get(obj)
    }
  }

  fun hackRationaleCallback(act: Activity, cb: EasyPermissions.RationaleCallbacks) {
    main.post {
      try {
        act
          .castOrNull<AppCompatActivity>()
          ?.supportFragmentManager
          ?.findFragmentByTag(RationaleDialogFragmentCompat.TAG)
          ?.castOrNull<RationaleDialogFragmentCompat>()
          ?.dialog
          ?.getFieldValue("mAlert")
          ?.getFieldValue("mButtonNegativeMessage")
          ?.getFieldValue("obj")
          ?.let { obj ->
            obj::class.java.getDeclaredField("mRationaleCallbacks").apply {
              isAccessible = true
              set(obj, cb)
            }
          }
        act
          .fragmentManager
          ?.findFragmentByTag(RationaleDialogFragment.TAG)
          ?.castOrNull<RationaleDialogFragment>()
          ?.dialog
          ?.getFieldValue("mAlert")
          ?.getFieldValue("mButtonNegativeMessage")
          ?.getFieldValue("obj")
          ?.let { obj ->
            obj::class.java.getDeclaredField("mRationaleCallbacks").apply {
              isAccessible = true
              set(obj, cb)
            }
          }
      } catch (e: Throwable) {
        Timber.e(e, "Failed to hack EasyPermission rationale callback")
      }
    }
  }

Dkhusainov avatar Apr 01 '19 15:04 Dkhusainov

For make permission request from service or worker - use Notification.

java1developer avatar Aug 24 '19 10:08 java1developer