How to Do PROPER Permission Handling in Jetpack Compose - Android Studio Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys welcome back to new video in this video i will show you how you can properly handle runtime permissions in jetpack compose because handling these permissions on android is usually not a very simple thing and there's a lot of stuff to consider which some people actually just don't do but that's just not the proper way to do it and it will backfire in your app at some point so you will learn how you can request multiple permissions and also what i actually mean by um handling them properly so let me quickly show you the app that we will build not a really functional one but it fulfills the purpose to show you how permissions work so first of all we get this permission dialog we will just request camera and record audio permission here let's say we accept the camera permission and we decline the record audio permission then we will just have a state that is updated to reflect that so we see camera permissions granted and this text for the record audio permission here is the so-called permission rationale the permission rationale is basically usually a text that explains to the user why a permission is needed and it's displayed when a user declined the permission for the first time so here the user might have thought that okay now i don't want this app to use my microphone and then your app should basically say hey microphone is needed so others can actually hear you in a call or something like that whatever the microphone is needed for in your app and then the user will have the chance to actually accept that permission again so the first time he declines that we showed this if we then relaunched the app and see then permission is just requested again just for record audio this time because we already have the camera permission of course if we now deny again we see you permanently denied record audio permission go to the app settings to enable it so that is what usually should happen once you declined a permission for the second time because then the user really does not want to grant this permission and we should rather tell them to actually go to the app settings to change it if they really decide so i'll show you how you can just detect these things if a permission was crowned if you should show the rationale and what to do in that case and if a permission was actually permanently denied and yeah that you can basically have that as a state and compose and build your ui based on that first of all it's actually important to note that i'm using a dependency here that comes from the google components library and that makes permission handling quite easy for compose you can also do it without this library it's just a little bit more work a little bit more management and stuff like that i like to use this because you will see you will just get a cool permission state that makes your life very easy with that it's still quite a little bit of work but a lot less work than if you would do it manually so you will be able to find the dependency down here in my github repository or you can just uh pause here and write it off if you have that you can actually jump into main activity and all i want to do here is we first want to get that permission state i talked about and that comes from the confidence library so let's create our permissions state which is equal to remember permission actually remember multiple permission state if you just want to request a single one that will be okay and you just specify the permission you want to request i want to show you how you can do that with multiple permissions because that's often the case that you need those and here we need to specify these permissions in form of the list so we say okay we have a list and we want to request record audio and camera permission so we say manifest from the android one here that permission record audio and for the camera let's also not forget to add this to our manifest so we click on manifest and we add two users permissions here on the one hand camera and on the other hand record audio so far so good we also need to add an annotation here this experimental permissions api we can press alt plus enter here and attach that to our main activity class so that warning will go away now let's next see how it works to to use the state and actually detect if we already accepted these permissions if we want to show the rationale for a specific permission or if we basically permanently denied one of these or both of these for that i will have a column here i will attach a little modifier here modifier film x size and let's simply center our text so actually horizontal alignment center and vertical arrangement is center as well and in that we want to have our two texts that basically say okay camera permission accepted maybe and we have the same for record audio permission accepted of course we don't just want to show these texts like that in here because that would always show them we only want to show them when we actually also granted the corresponding permission so let's see how that now works with our permission state we will first of all use that permission state and you can see we we get quite some information here that's interesting for us on the one hand that permissions list which is just a list of permission states so that is a permissions state so multiple ones and that is a single permission state which just contains information about a specific permission which will be needed here actually but we can also easily check if all permissions were grounded if we actually requested some permissions if we revoked some that's also a list of permission states and if we should show any type of rationale here but what we will use is we'll use this permissions list because we want to explicitly explicitly check if we actually accept it camera permission and if we accept it record audio permission so we will use this we will loop over this and get the get the current permission here in this in each iteration and here in this for loop we can then check when the permission that permission so that will give us the string of that permission but you can also see we we also get house permission which is just a boolean if we have that permission if we requested that if we should show the rationale basically the same as we have for the multiple permission state here but this time it only refers to a single specific permission we want to use permission so we can easily now check in that one expression if that permission is camera we want to do this and if it is record audio we want to do this so that does not yet mean that we actually have that permission because we just checked okay this is currently the camera permission but it doesn't give us any information about if we accept it or decline that so we have another one expression here and i hope it gets a little bit complex but that's how you have to do it sadly when actually without any parentheses here instead in here we can now use that permission because now we know that's a that's the camera permission now we can use that to actually check if we have that permission if we should show the rational if we permanently declined it and stuff like that so if permission has permission we do this if the permission should show rational so if we should show the rationale the info text about the camera permission specifically here we execute this piece of code here and how do we actually detect if we permanently declined that well we don't really have a boolean for that but we can kind of use these booleans that we have here to to detect that so on the one hand for that we want to make sure that we don't have permission because otherwise we would have that and we wouldn't have permanently declined that but we also want to make sure that we sh that we don't want to see the rationale and perm should show rational because that means if we if the rationale should not be shown and we also don't have the permission then the user declined that permission at least for the second time and let's actually take this boolean expression and make it an extension function of our permission state because i think that makes it a bit more readable so let's go to our root package create a new carton class now we'll call that permissions state extension will just be a plain kotlin file and here we will write that function so permissions state just permission state actually that is permanently um denied maybe we'll return a boolean and here we also need to press alt plus enter to add this annotation to this function so we get rid of the warning and here we just return um should show rational so if we don't want to show the rational and we also don't have the permission then we know it's permanently declined so we can go back to main activity and say perm that is permanently denied and then we also know that information now the next step would be to actually take our attacks and display the corresponding text in the corresponding permission block here of course the rational does not need to be a plain text that's just for simplicity here usually that's some kind of dialogue or so you want to show then you would simply show that dialog here and we also want to have the text here and let's now adjust these texts a little bit so here we can then describe what the camera permission is needed for permission is needed to access the camera i don't know it doesn't really matter here usually just give your users a little better explanation here but i think you get what i mean here um if it's permanently declined we can say something like camera permission was permanently denied you can enable it in the app settings something like that then we can copy this one expression because we also need that for record audio you need that for every single runtime permission you actually want to request also for location also for writing to external storage and stuff like that here for record audio we can just swap these out with record audio paste it here and here and this text here can be removed so far so good so right now we're definitely ready to display our ui that that properly reflects the current permission state but right now we don't really request these permissions that's also something that i that i see people do wrong quite often especially if you if you just want to make the permission request so yeah basically request the permissions from the user as soon as they visit a specific screen because most people then just just put that that code and that logic to request a permission just in oncreate or on view created in fragments i mean that's composed here that's something different but the issue with putting it in oncreate or in on view created is that it could happen that the user actually accepts your permission then minimizes the app goes to the app settings and denies it there then goes back to the app but oncreate isn't triggered anymore because the app is still active so yeah you won't have permission because the user actually manually denied that in the app settings and your app won't know about that so when you deal with these permission scenarios in which you request a permission once a screen opens then you should actually make that request in on resume because that way you can also detect if the user minimizes the app denies the permission in the app settings and then goes back because then on resume is is called again if you however request the permissions on a button click or so so a user initiated action then that's not a problem because uh yeah you can just check on on button click if the permission is given or not and if not then yeah you just request it again or you display corresponding message to the user but i want to show you that way to automatically request that permission when visiting a specific screen because you need to consider a little bit of stuff regarding regards to that in jetpack compose and that is actually dealing with the life cycle events because in compose we we don't have i mean we have an activity and that has on resume and stuff like that but yeah this this code might be somewhere deep down in a composable hierarchy and not in our activity like we have it in this simple scenario here so we somehow need access to onresume deep down in our composable hierarchy and we can easily do that with the lifecycle owner and we can add a call back to that so we can say val lifecycle owner and we can get the current lifecycle owner using local lifecycleowner.current and then we want to add a callback here so we could say lifecycleowner at actually lifecycle ad observer but that would be a big mistake here if we would do it like this because we can't control how often this piece of code is called here because it's it's just directly put in a composable function and whenever that recomposes we would add another observer for things like these we have the so-called disposable effect effect handler which is this one here in which we can basically register a callback that is cleaned up after use so for the key we want to use that lifecycle owner so whenever the lifecycle owner actually changes here the disposable effect will basically fire off again and here in the effect we we then put the logic for adding and removing that observer we can say val observer is equal to a so-called live cycle event observer we can open a block of code here the first parameter is needed but the second one is and that is the event so with that event we can now check if the life cycle is in a specific stage so if the event is actually just life cycle dot event dot on resume because that is the event we are interested in if the life cycle is in that on resume state what do we want to do well we want to request our permissions so we use our permission state and we say launch multiple permissions requests and that is how we will actually show that permission dialog to accept or decline these permissions now we still get a big error here because the we didn't finish the setup of this disposable effect scope here we of course also want to add this observer right now we only declare it so we say livecycle owner a lifecycle add observer and we pass our observer and then we need to finish off every every of these disposable effect handlers with and on this post function so when these observers should actually be cleaned up this this post function will be called and in here we can then do that so we can say life cycle owner lifecycle.remove observer and we pass our observer again and that is now everything we need to do to properly handle our permissions here or runtime permissions of course that's not needed for all permissions only for the dangerous ones android calls it i think um so let's let's have a little recap so we first of all declare this permission state by using remember multiple permission state we declare our permissions we want to request then we simply loop over all of these permissions here in that state and we simply check okay what is the current permission if it's if we're dealing with a camera permission we simply check okay do we have camera permission if yes we display this text if we should show the rationale the info text we display this text as i said usually you you don't just display a plain text here instead of dialog or so and if we permanently deny that permission we also properly show that to the user and yeah just the same stuff for the record audio permission and to actually initiate that permission request we um basically intercept this on resume callback here from our lifecycle um we use this disposable effect handler to make sure that the the observer here is properly cleaned up when this composable here leaves the composition or when this key changes and yeah here you can see we just removed the observer let's actually now launch this and see if this works but it should so there we go i uninstalled the app and let's see now we deny both of these again and you can now see um it's mr space here but doesn't matter you can see both of these rationales show up because we declined the permissions for the first time if we now relaunch the app then it will basically request permission again um allow to take pictures and record a view let's say we we don't allow let's say we actually allow both of these then you can see both are accepted if we now minimize that and go in the app settings and now decline the permissions here so we say deny and deny and then go back to our app then you can see it will request the permissions again because we used onstart here if we used oncreate here that wouldn't have happened and we can now accept or decline this again so you i think you get how this works so my general suggestion is you should request permissions when the user is actually about to to use that permission so if the permission is actually needed to initially load some data on the screen then directly requested like we did here if the permission is for example needed when the user clicks on the camera button and then enables the camera then i would rather ask for permissions after clicking on this button and then you don't need this this observer stuff here so that is it for this video i hope you enjoyed it if so then you will definitely also love my free email newsletter so you can simply subscribe down below there for free of course um you will just find a link to my website there and yeah just enter your email and you will get regular kotlin android architectural advice right into your inbox on a weekly basis so you'll definitely enjoy that i wish you an excellent rest of the day and see you back in the next video bye bye
Info
Channel: Philipp Lackner
Views: 4,442
Rating: undefined out of 5
Keywords: android, tutorial, philip, philipp, filipp, filip, fillip, fillipp, phillipp, phillip, lackener, leckener, leckner, lackner, kotlin, mobile
Id: ltHN50BdDc4
Channel Id: undefined
Length: 20min 27sec (1227 seconds)
Published: Tue Nov 09 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.