OK so we've got some code that should run.
So let's run the app a few times and see what happens when we deny and accept the permissions.
Now I'm going to be running this on our API 27 emulator that we've set up previously.
Now we know that it worked on the API 21, or actually API 22 and below, although we will test it again on that version
once everything's finished. It is a good idea to retest when you make changes to cater for particular
Android versions, just in case the changes break something in the earlier versions. But we'll leave that
final testing on API 21 until we've made all the changes we need to make.
So the first thing I've done is start up my API 27 emulator.
I'm going to make sure that the app's not installed, and what I'm going to do here is come over here to that Content
Provider Example. I'm just going to uninstall that so we're starting with a fresh installation. So we could have done the same thing
by going into Settings and Apps & notifications, App info - we could've looked for our app in there - but obviously I've deleted
that now
so that's alright. So we've seen previously that we can get a lot of irrelevant entries in the logcat.
So I'm going to go back to Android Studio and open logcat, but I'm going to filter then on MainActivity
and then I'm going to run the app.
I'm going to change this to floating plane mode as well, just to make sure that if you're using subtitles
you can still see what we're doing there, so I'll go ahead and do that.
So just to verify now the app is running.
You can see that it's running here, but back in the logcat we can see we've got checkSelfPermission
returned a negative one requesting permission, then onCreate ended. So again, note there that the request
Permission method has returned and onCreate has finished.
So our activity now is in a running state, and can be destroyed by the Android system if something like
an incoming phone call comes in.
And that's great because the app's not blocking while it waits for the user to deal with the dialog.
So speaking of the dialog we'll go back and just check that out.
We can see the dialog there - it's popping up and it says Allow Content Provider Example to access your
contacts? Deny or Allow.
So we're going to start here by allowing the permission and we'll see what happens in the logcat. You can
see here now that we've got permission granted - basically onRequestPermissionsResult starts, permission
granted, then onRequestPermissionsResult ends.
So that's working fine.
And just to confirm that we'll go back to our emulator, run, or click rather, the fab - the floating action
button. You can see we've got our two entries now showing.
Alright.
Next let's see what happens when the app runs
now that permission has been granted. So let's stop the app and we'll start it again.
And you can see what's happened here now - check
SelfPermission returned zero this time;
Permission granted, then onCreate ends.
So this time checkSelfPermission, as you can see, returned 0 which is permission granted.
So the app is ready to use,
in other words, with the READ_CONTACTS permission it needs, and if I just confirm that
by tapping the floating action button we can see we get the results returned. So that's great -
once the permission's been granted by the user, the app keeps that permission
each
time it's launched. Alright, so for the next test
we need to uninstall the app again, and this time we're going to try denying the request.
Alright, so I'm going to stop the app.
I'm just going to go into Settings,
Apps & notifications, and recently opened apps. Here's quite useful so I'm going to
click on that and uninstall, and uninstall our app so we're starting with a clean slate again.
And now if we run it again we should be back to where we were before. I'm just checking the log there;
that starts, checkSelfPermission's returned -1 requesting permission and our emulator is now asking for
access to the contacts - the DENY ALLOW dialog.
And again that's as expected because we uninstalled the app.
This time I'm going to deny the request and see what happens. I'll click on Deny; permission refused and ends in
our logcat.
Now we haven't checked the value of our boolean field in the onClickListener for the floating action button,
so consequently when I tap that we're going to get a crash there because we haven't got permission
to access the contacts.
I'm going to leave you to deal with it a bit later in the next video, because that sounds like a
good challenge. For now though, before we get to that let's run a few more tests.
So what we're going to do is come back and start it again.
You can see it's requesting permission again and we go back to logcat. We've got the same, a similar dialog than last
time, but this time notice over here we've got this Don't ask again, with a check-box to the left hand side.
So I'm not going to change that just yet but I will deny the request again.
So let's do that, just as
the case was last time, permission refused, and that's nothing
we didn't expect. And I'm not going to tap on the floating action button again because we know that it
will just crash the app.
Instead what we'll do is we'll just run the app again,
and back to Android Studio, run it again -
same deal there - requesting permission. And we're asked again this time whether we want to allow permission,
and we'll still got the same Don't ask again box. Alright so we're going to Allow this time, and we can see over there
we've got permission granted in our logcat, and if I click on the floating action button, unsurprisingly things
are working.
Alright, so there's one more test we need to do now.
So what I'm going to do is close down the app, but this time we're going to go into settings and revoke the permission.
Remember that we've allowed the permission, so I'm going to go into Settings, Apps & notifications,
we go into our Content Provider Example, and I'm going to come down here to permissions.
You can see we've got Contacts permission with a slider here and it's currently enabled. Now this screen, by
the way, is new in Android Marshmallow and above,
so if you're running this test on an API 21 emulator, we wouldn't have this option.
And one thing to note is that this option appears because we're running on a device that's using API
23 or higher. Now if we set the target SDK to 21, then our app would be treated by Android
as a legacy app,
and although this option would still be available, we'd actually get a warning if we tried to change it.
Now that makes sense because apps written before Google changed the security model have no way of dealing
with their permission being revoked.
So the Android framework checks, and if they were written for Android versions prior to API 23, then
this warning appears to let users know that things might break. Alright,
so what I'm going to do here is revoke the permission and see what happens when I run the app again.
So I'm going to click over here to revoke it and we'll run the app again.
And go back to the emulator and you can see it's now asking us whether we want to allow access
again, and again that's not surprising because we denied the permission.
So the important lesson from this last test is, just because your app had a permission today, you can't
rely on it still having that permission tomorrow.
When we're dealing with permissions, we have to make sure our code can cope with the situation where permission
isn't granted. Alright, so for the final test, for now at least, we're going to tick on this,
we're going to tick, or check the Don't ask again box and then I'm going to deny the permission.
And going back to our logcat, permission refused, which we would expect, and we get a crash if we try and
access by the floating action button.
So now by clicking on that check-box, the user's asked not to be bothered again. So it won't matter
how many times when I run the app and requestPermissions get called,
we'll never be granted permission.
So let's just confirm that; on requestPermissions
Result starts,
permission refused.
And looking at our emulator, we've got no dialog box, clicking on the floating action button and the
app crashes again.
So basically the users are never going to be asked again. Now if the permission was only needed for some
minor function of the app, such as sharing photos when the main purposes is taking them, then you could just
disable that particular function.
But this app's pretty useless without permission to access the contacts though,
because that's all it does.
So the core functionality is now disabled. Before we look at dealing with that,
one thing we should do is prevent the app from crashing when it doesn't have permission.
So an app that does nothing is pretty bad, but we don't want to get a reputation for running apps that crash.
So what I'm going to do is disable the floating action button if we don't have permission to access
the contacts.
Basically I'm going to write the kind of code that you'd use if the permission was for some
peripheral function that wasn't essential for your app to be useful.
So let's work on that in the next video.