Alright, so we're now ready to run the
app again, to see how it behaves. We're
going to do that, then talk about what's
wrong with the code. So we need to see,
firstly, how the app behaves some scratch.
So I'm going to go back to our emulator,
and I'm going to delete this app so
we're starting from a clean slate. So I'm
going to install that, and I'll run it
again, and we'll open our logcat so that
we can see what's going on. So the first
test that we want to do here, is to see
how it behaves when we deny access. I'm just
gonna move this over a little bit more,
so we can see a bit more of the log.
Alright, so as I said, the first test is
going to be to see how it behaves when
we deny access. So I'm gonna click on
Deny, and now when I click on the FAB, it
should display our Snackbar and the link
there to Grant Access, which it is. And
that should continue to appear whenever
we click the FAB. So if I swipe that off
screen - the Snackbar. Click it again - it
comes back again, which is good and which is
the expected behavior. And in the logcat,
you can see as I'm doing that, the FAB's
onClick method starting and ending.
Alright, so let's see now what happens
when the Grant Access link is clicked. So
the logcat now, you can see, has the
onClick method starting again - this time
a call to requestPermissions, and then
the onClick method ending. And as a
result, we've now got the Android dialogue
asking for permission to access the
contacts. So when I come over here and
click on Deny again, we see permission
refused over here, in the log.
We're now onRequestPermissionsResult:
callback is called. So let's do that
again,
but this time, when I click on Grant
Access, I'm going to check the Don't ask
again checkbox and click on Deny. So now
effectively, what I've done, is told
Android not to ask again. So in terms
of our code, the call to shouldShowRequest
PermissionRationale should now return
false. So in other words, this bit of
code down here should now be
executed.
So let's actually check that. I'm going
to click on the FAB button again,
click on Grant Access, and you can see
what's happened in this case - that code
was executed, and the settings for the
application is now showing on the screen
again. so that bit's working well, and
looking at the logcat down here as well,
you can see the URI showing on the
screen there; package:academy.learn
programming.contentproviderexample. So
it's that URI, together with the ACTION
_APPLICATION_
DETAILS_SETTING - a value that
we used in setAction - that sets, or let's
rather, Android open the settings for
this app, rather than just going into the
main settings screen. And notice down here
also, in the log, that the Snackbar's
onClick method has finished. So you can
see the Snackbar onClick: ends entry
after the launching of the settings, and
we'll see why that's important in a
moment. Alright, so back over in our app,
I'm going to click on Permissions, and
then I'm going to grant access to our
Contacts, by turning that on. Once I've
done that, tapping back a few times
should take us back to our app, which it's
done here now. But notice that when I'm
doing that, nothing's appeared over here
in the logcat. The app now has the
permission it needs, but it doesn't know
that it has got that permission. So you
can see, basically at this point, where
I've tapped the FAB again, the Snackbar
still appearing instead of our contact
details. Now if I quit the app, close this
down, and run it again and
click on our button - our FAB - it is actually
working correctly. And you can see, in
fact, the permission's granted now
showing in our logcat. But really,
that's not the best user experience
requiring the user to shut down the app
and start it up again, in order to
proceed.
So let's actually have a look at the
code, to see what's gone wrong here. So
the actual problem is caused by the test
in the FAB's onClick method - and
this is the code here, basically line
46. So we've used readGranted here, to
store whether we have access or not,
but we haven't updated it after going
into the settings. So consequently, it
actually failed there and returned false,
and we weren't able to get access to our
contacts, until we closed down the app and
started it again. Now I'm not going to
say never store state in a variable, like
we've done here, but what I will say is
think long and hard before doing so.
Sometimes it can be necessary, but
generally, it's much tidier to check the
state when you need it, rather than
storing it in a field, as we've done here.
And the problem we've got here, is that
we check to see if we had access in the
onCreate method, and set readGranted to
true or false, to reflect the state of
our access. But down in the onRequest
PermissionResult callback method, we
also set it to true. Scroll down and
have a look at that - this one here, code
standing on line 91. So we also set that
to true if access is granted, after
calling requestPermissions. So that
means that the app would work, after
tapping Allow in the dialogue. But our
code that launches the app's Settings, has
no way of knowing whether the user
granted access or not. Now of course, we
know that they went into the settings
because we sent them there, but we've got
no control over what they did, when they
got into the settings. So it's very
tempting to store things like, whether
you have a particular permission, and
it's also very common. But once you start
doing that, you'll find yourself adding
more code to keep the variable
up-to-date as state changes. We saw
earlier that the Snackbar's onClick
method ends while the user is still in
the Settings, so we don't really have a
convenient way to check the permissions
again. So a good rule is, if you want to
know the state of your environment, then
check it each time you need to know,
rather than storing that state in a
field. So don't store the state, because
you'll end up struggling to keep your
stored value up-to-date. Alright, so how
do we go about fixing that? Well let's
work on that, in the next video.