Giter Site home page Giter Site logo

Comments (6)

kovrizhin avatar kovrizhin commented on July 4, 2024 1

@Canato Yeah, thanks a lot for. Yep, I do the first approach right now and trying to find good solution, how to correct handle it. The second of course is better, but it is required a lot of staff just for small things, and if you have quite simple application it is a big pain :)

But thanks a lot. :)

from permissions-samples.

kovrizhin avatar kovrizhin commented on July 4, 2024

Hello, also will be quite interesting to see, how to pass parameters from launch to callback. Because in early version it was easy to do with closures, but now it is not possible to do, because you have to register your callback when you create activity or fragments.

Should we build Custom Contract, and where store values?

Thanks.

from permissions-samples.

Canato avatar Canato commented on July 4, 2024

@kovrizhin could you take a look in the PR?
#8

Would this solve your question?

If not, can you provide some code sample from the way you said in early version so I can help to find the latest way of doing it?

from permissions-samples.

kovrizhin avatar kovrizhin commented on July 4, 2024

@Canato Thanks a lot for quick response. I checked #8 and looks like I don't find answer for now. I understood a bit that it is wrong how I want to use and how I use it, this is why it was deprecated and not allowed, but it was quite useful. I will try to write code:

Previously it was possible to write code like this, for example we have a RecycleView and in onBindViewHolder we create a closure, and provide item like this:

        override fun onBindViewHolder(holder: EmptyViewHolder, position: Int) {
            val item = dataset[position]
            holder.downloadButton.setOnClickListener {
                registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
                    if (isGranted) GlobalScope.launch(Dispatchers.IO) {
                        clientService.download(item, position) // passing item and position as parameter, this is what I mean by context
                    } else {
                        notificationServie.notifyUser(item)
                    }
                }.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
            }
        }

but now I need to check permission firstly and if I have it I can continue if not I need to ask it, when I request it loose context I don't have ability to continue action with parameters after user grant me permission, the user have click again action.

    val registerForActivityResult = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
        if (isGranted) {
               clientService.download(???, ???) // how should I retrieve here parameters 
        } else {
              notificationServie.notifyUser(???, ???) // how should I retrieve here parameters
        }
    }

        override fun onBindViewHolder(holder: EmptyViewHolder, position: Int) {
            val item = dataset[position]
            holder.downloadButton.setOnClickListener {
                if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                    clientService.download(item, position) // passing item and position as parameter, this is what I mean by context
                } else {
                    registerForActivityResult.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                }
            }
        }

And I can't find how to do it in correct way, because creating custom contract will also not solve it, where is no place to store custom date inside to contract.

Of course there are two possible hacks :) But I don't like it. You can store item into instance of your class or in the custom contract when do createIntent, but this I don't like..

from permissions-samples.

Canato avatar Canato commented on July 4, 2024

I see your point.

Indeed you could create a wrapper with custom contract, but for your case I agree is not the best solution, my personal suggestion (be clear I'm not part of the google team)

Easy fix(little hack and little unsafe): make a latestPosition parameter in this class so you save the state and get the item later.

 private val latestPosition: Int = 0
    val registerForActivityResult = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
        if (isGranted) {
            clientService.download(dataset[latestPosition], latestPosition) // how should I retrieve here parameters
        } else {
            notificationServie.notifyUser(???, ???) // how should I retrieve here parameters
        }
    }

    override fun onBindViewHolder(holder: EmptyViewHolder, position: Int) {
        val item = dataset[position]
        holder.downloadButton.setOnClickListener {
            if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                clientService.download(item, position) // passing item and position as parameter, this is what I mean by context
            } else {
                latestPosition = position
                registerForActivityResult.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
            }
        }
    }

Fix I would do: On clickListener would active a listener fun onDowloadClicked(item, position) this will pass the logic check to your presenter/viewModel/Controller depending on your architecture, that would check if you have the permission and start the download when provide.
This will be the right place to hold a instance/cache the value and later access the service/repository.
And if you are worry about the safety of the value, ideally immutable, the solution would be to create a Stream/cue, like a Coroutines Channel to keep the value safe.

This second solution bring more work cause you would need to bring everything in another place following your architecture. But this will make your code safer and reliable on the long term.

from permissions-samples.

IamMuhammadHasib avatar IamMuhammadHasib commented on July 4, 2024

@SuppressLint("MissingSuperCall")
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array,
grantResults: IntArray
) {
if (requestCode == myResquestCode) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLastLocation()
} else {
requestPermission()
}
}
}

from permissions-samples.

Related Issues (20)

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.