QuickPermissions / QuickPermissions-Kotlin

The most easiest way to handle Android Runtime Permissions in Kotlin
Apache License 2.0
313 stars 35 forks source link

Using quick permission in fragment #9

Open abangkis opened 5 years ago

abangkis commented 5 years ago

I'm trying to use this library in a fragment to get the current location using fused location provider. Here's the code. I just assume that it will work either in activity or fragment. But i get

" java.lang.IllegalStateException: FragmentManager is already executing transactions"

Maybe some more samples usecase code could help new users to use this library.

@SuppressLint("MissingPermission")
override fun onAttach(context: Context?) {
    super.onAttach(context)
    if (context != null) {
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)

        runWithPermissions(Manifest.permission.ACCESS_COARSE_LOCATION) {
            val locationClient = fusedLocationClient
            locationClient?.lastLocation?.addOnSuccessListener {
                // Got last known location. In some rare situations this can be null.
                Timber.d("last location $it")
                vm.currentLocation = it
            }
        }
    }
}
kirtan403 commented 5 years ago

Hi @abangkis Thanks for reaching out. There are couple of things you can try out here.

  1. You can try committing your transaction by commitNow() on your fragment transaction or call executePendingTransactions() on your transaction. That should work in my opinion.
  2. Move this code out of onAttach() and use in onCreateView() or any other method.

Out of this 2 methods, you should not be getting the error you are experiencing now. Let me know if it works for you.

abangkis commented 5 years ago

Hi @kirtan403, thanks for the reply. I don't do any fragment transaction, i use google maps in that activity though.

I refactor my code to this and the problem still persist:

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        (childFragmentManager.findFragmentById(R.id.gMap) as SupportMapFragment?)?.getMapAsync(this)

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(activity as Context)
        getLastLocation()
        childFragmentManager.executePendingTransactions()
    }

    @SuppressLint("MissingPermission")
    fun getLastLocation() = runWithPermissions(Manifest.permission.ACCESS_COARSE_LOCATION) {
        val locationClient = fusedLocationClient
        locationClient?.lastLocation?.addOnSuccessListener {
            // Got last known location. In some rare situations this can be null.
            Timber.d("last location $it")
            vm.currentLocation = it
        }
    }
kirtan403 commented 5 years ago

Your code looks good to me. I have used like this at many places and never had the problem. Can I request you something? It would be nice if you can provide me a sample repo with the reproduced bug so that I can look into and resolve the issue?

abangkis commented 5 years ago

Hi, I've created a sample repo for this. It's not reproducible yet. 2 things that i haven't implement from the original project.

  1. I'm using koin dependency injection
  2. I'm migrating from a java project. So there's a mix between java & kotlin.

https://github.com/abangkis/PermissionBug

abangkis commented 5 years ago

Hi, I just pushed a reproducible code to the repo. To reproduce just uncomment the getLastLocation function in OurMapFragment or BwMapFragment3 class

kirtan403 commented 5 years ago

@abangkis Awesome, I'll have a look today. Thanks for the update.

jahonn commented 5 years ago

I have same problem while using in Fragment.

And it seems caused by this line. "context" is always a AppCompatActivity, the "context" here should be "target".

AdoniasAlcantara commented 4 years ago

Same to me using Google Maps: "java.lang.IllegalStateException: FragmentManager is already executing transactions"

Any solution?

Edit: I forgot to mention that I'm using Navigation component from Android Jetpack

lbaron123 commented 3 years ago

I am having same issue:

runWithPermissions(android.Manifest.permission.READ_CALENDAR){
            u.l(requireActivity().applicationContext,"We have permission to read calendar")
            val time = measureTimeMillis {
                val calendarProvider = CalendarProvider(requireActivity().applicationContext)
                val events = mutableListOf<CalendarEvent>()
                for (i in 1150..1200){
                    val desc: String = calendarProvider.getEvent(i.toLong())?.description?.toString() ?: "t"
                    if (desc.length > 2){
                        if(desc.contains("PFO")){
                            val event = CalendarEvent(i.toLong() ,desc)
                            u.l(requireActivity().applicationContext, event.desc)
                            events.add(event)
                        }
                    }
                }
            }

            u.l(requireActivity().applicationContext,"Time taken = ${time/1000}")
        }

Fails on the first line pasteed with:

2021-04-29 21:24:25.540 17517-17517/com.lbaron.flyingweather E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.lbaron.flyingweather, PID: 17517
    java.lang.IllegalStateException: FragmentManager is already executing transactions

Has anyone managed to fix this? I am also using navigation component.

Thanks a lot