1 00:00:05,420 --> 00:00:07,900 OK so we've got some code that should run. 2 00:00:08,000 --> 00:00:13,810 So let's run the app a few times and see what happens when we deny and accept the permissions. 3 00:00:13,850 --> 00:00:18,480 Now I'm going to be running this on our API 27 emulator that we've set up previously. 4 00:00:18,500 --> 00:00:24,590 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 5 00:00:24,590 --> 00:00:29,720 once everything's finished. It is a good idea to retest when you make changes to cater for particular 6 00:00:29,750 --> 00:00:35,090 Android versions, just in case the changes break something in the earlier versions. But we'll leave that 7 00:00:35,090 --> 00:00:39,830 final testing on API 21 until we've made all the changes we need to make. 8 00:00:40,190 --> 00:00:43,780 So the first thing I've done is start up my API 27 emulator. 9 00:00:43,910 --> 00:00:49,800 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 10 00:00:49,800 --> 00:00:58,070 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 11 00:00:58,070 --> 00:01:07,130 by going into Settings and Apps & notifications, App info - we could've looked for our app in there - but obviously I've deleted 12 00:01:07,180 --> 00:01:07,530 that now 13 00:01:07,530 --> 00:01:13,910 so that's alright. So we've seen previously that we can get a lot of irrelevant entries in the logcat. 14 00:01:13,910 --> 00:01:20,050 So I'm going to go back to Android Studio and open logcat, but I'm going to filter then on MainActivity 15 00:01:23,420 --> 00:01:27,070 and then I'm going to run the app. 16 00:01:30,260 --> 00:01:35,120 I'm going to change this to floating plane mode as well, just to make sure that if you're using subtitles 17 00:01:35,120 --> 00:01:43,950 you can still see what we're doing there, so I'll go ahead and do that. 18 00:01:43,970 --> 00:01:45,810 So just to verify now the app is running. 19 00:01:46,110 --> 00:01:50,900 You can see that it's running here, but back in the logcat we can see we've got checkSelfPermission 20 00:01:50,900 --> 00:01:56,720 returned a negative one requesting permission, then onCreate ended. So again, note there that the request 21 00:01:56,720 --> 00:02:00,310 Permission method has returned and onCreate has finished. 22 00:02:00,650 --> 00:02:05,900 So our activity now is in a running state, and can be destroyed by the Android system if something like 23 00:02:05,900 --> 00:02:07,760 an incoming phone call comes in. 24 00:02:07,760 --> 00:02:11,740 And that's great because the app's not blocking while it waits for the user to deal with the dialog. 25 00:02:11,900 --> 00:02:13,990 So speaking of the dialog we'll go back and just check that out. 26 00:02:13,990 --> 00:02:18,500 We can see the dialog there - it's popping up and it says Allow Content Provider Example to access your 27 00:02:18,500 --> 00:02:20,670 contacts? Deny or Allow. 28 00:02:20,960 --> 00:02:27,530 So we're going to start here by allowing the permission and we'll see what happens in the logcat. You can 29 00:02:27,560 --> 00:02:33,360 see here now that we've got permission granted - basically onRequestPermissionsResult starts, permission 30 00:02:33,360 --> 00:02:37,340 granted, then onRequestPermissionsResult ends. 31 00:02:37,830 --> 00:02:38,960 So that's working fine. 32 00:02:38,970 --> 00:02:43,670 And just to confirm that we'll go back to our emulator, run, or click rather, the fab - the floating action 33 00:02:43,720 --> 00:02:47,090 button. You can see we've got our two entries now showing. 34 00:02:47,310 --> 00:02:47,530 Alright. 35 00:02:47,550 --> 00:02:49,470 Next let's see what happens when the app runs 36 00:02:49,470 --> 00:02:54,830 now that permission has been granted. So let's stop the app and we'll start it again. 37 00:03:01,550 --> 00:03:03,480 And you can see what's happened here now - check 38 00:03:03,490 --> 00:03:05,540 SelfPermission returned zero this time; 39 00:03:05,650 --> 00:03:08,520 Permission granted, then onCreate ends. 40 00:03:08,950 --> 00:03:13,690 So this time checkSelfPermission, as you can see, returned 0 which is permission granted. 41 00:03:13,780 --> 00:03:15,300 So the app is ready to use, 42 00:03:15,490 --> 00:03:19,390 in other words, with the READ_CONTACTS permission it needs, and if I just confirm that 43 00:03:19,390 --> 00:03:25,430 by tapping the floating action button we can see we get the results returned. So that's great - 44 00:03:25,570 --> 00:03:29,470 once the permission's been granted by the user, the app keeps that permission 45 00:03:29,530 --> 00:03:29,780 each 46 00:03:29,770 --> 00:03:33,280 time it's launched. Alright, so for the next test 47 00:03:33,310 --> 00:03:37,400 we need to uninstall the app again, and this time we're going to try denying the request. 48 00:03:37,570 --> 00:03:39,050 Alright, so I'm going to stop the app. 49 00:03:39,280 --> 00:03:40,490 I'm just going to go into Settings, 50 00:03:43,090 --> 00:03:47,430 Apps & notifications, and recently opened apps. Here's quite useful so I'm going to 51 00:03:47,430 --> 00:03:54,040 click on that and uninstall, and uninstall our app so we're starting with a clean slate again. 52 00:03:54,640 --> 00:04:00,800 And now if we run it again we should be back to where we were before. I'm just checking the log there; 53 00:04:01,090 --> 00:04:08,770 that starts, checkSelfPermission's returned -1 requesting permission and our emulator is now asking for 54 00:04:08,770 --> 00:04:13,290 access to the contacts - the DENY ALLOW dialog. 55 00:04:13,740 --> 00:04:16,420 And again that's as expected because we uninstalled the app. 56 00:04:16,660 --> 00:04:24,700 This time I'm going to deny the request and see what happens. I'll click on Deny; permission refused and ends in 57 00:04:24,820 --> 00:04:25,570 our logcat. 58 00:04:25,910 --> 00:04:30,870 Now we haven't checked the value of our boolean field in the onClickListener for the floating action button, 59 00:04:31,140 --> 00:04:37,220 so consequently when I tap that we're going to get a crash there because we haven't got permission 60 00:04:37,580 --> 00:04:39,280 to access the contacts. 61 00:04:39,340 --> 00:04:42,740 I'm going to leave you to deal with it a bit later in the next video, because that sounds like a 62 00:04:42,740 --> 00:04:46,790 good challenge. For now though, before we get to that let's run a few more tests. 63 00:04:46,790 --> 00:04:49,270 So what we're going to do is come back and start it again. 64 00:04:54,850 --> 00:05:00,370 You can see it's requesting permission again and we go back to logcat. We've got the same, a similar dialog than last 65 00:05:00,370 --> 00:05:06,050 time, but this time notice over here we've got this Don't ask again, with a check-box to the left hand side. 66 00:05:06,340 --> 00:05:09,800 So I'm not going to change that just yet but I will deny the request again. 67 00:05:09,820 --> 00:05:13,100 So let's do that, just as 68 00:05:13,120 --> 00:05:16,300 the case was last time, permission refused, and that's nothing 69 00:05:16,300 --> 00:05:20,740 we didn't expect. And I'm not going to tap on the floating action button again because we know that it 70 00:05:20,740 --> 00:05:22,710 will just crash the app. 71 00:05:22,990 --> 00:05:25,420 Instead what we'll do is we'll just run the app again, 72 00:05:25,600 --> 00:05:27,070 and back to Android Studio, run it again - 73 00:05:31,350 --> 00:05:37,220 same deal there - requesting permission. And we're asked again this time whether we want to allow permission, 74 00:05:37,430 --> 00:05:45,430 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 75 00:05:45,440 --> 00:05:51,230 we've got permission granted in our logcat, and if I click on the floating action button, unsurprisingly things 76 00:05:51,230 --> 00:05:52,310 are working. 77 00:05:52,360 --> 00:05:54,350 Alright, so there's one more test we need to do now. 78 00:05:54,590 --> 00:06:00,580 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. 79 00:06:00,670 --> 00:06:07,840 Remember that we've allowed the permission, so I'm going to go into Settings, Apps & notifications, 80 00:06:07,900 --> 00:06:13,550 we go into our Content Provider Example, and I'm going to come down here to permissions. 81 00:06:13,750 --> 00:06:19,040 You can see we've got Contacts permission with a slider here and it's currently enabled. Now this screen, by 82 00:06:19,040 --> 00:06:21,560 the way, is new in Android Marshmallow and above, 83 00:06:21,560 --> 00:06:26,930 so if you're running this test on an API 21 emulator, we wouldn't have this option. 84 00:06:27,070 --> 00:06:32,260 And one thing to note is that this option appears because we're running on a device that's using API 85 00:06:32,560 --> 00:06:38,740 23 or higher. Now if we set the target SDK to 21, then our app would be treated by Android 86 00:06:38,740 --> 00:06:40,100 as a legacy app, 87 00:06:40,150 --> 00:06:44,960 and although this option would still be available, we'd actually get a warning if we tried to change it. 88 00:06:45,370 --> 00:06:50,800 Now that makes sense because apps written before Google changed the security model have no way of dealing 89 00:06:50,800 --> 00:06:52,630 with their permission being revoked. 90 00:06:52,660 --> 00:06:58,860 So the Android framework checks, and if they were written for Android versions prior to API 23, then 91 00:06:58,870 --> 00:07:03,290 this warning appears to let users know that things might break. Alright, 92 00:07:03,340 --> 00:07:08,200 so what I'm going to do here is revoke the permission and see what happens when I run the app again. 93 00:07:08,240 --> 00:07:12,260 So I'm going to click over here to revoke it and we'll run the app again. 94 00:07:19,460 --> 00:07:25,550 And go back to the emulator and you can see it's now asking us whether we want to allow access 95 00:07:25,550 --> 00:07:28,910 again, and again that's not surprising because we denied the permission. 96 00:07:29,060 --> 00:07:34,970 So the important lesson from this last test is, just because your app had a permission today, you can't 97 00:07:34,970 --> 00:07:37,420 rely on it still having that permission tomorrow. 98 00:07:37,730 --> 00:07:43,460 When we're dealing with permissions, we have to make sure our code can cope with the situation where permission 99 00:07:43,550 --> 00:07:48,020 isn't granted. Alright, so for the final test, for now at least, we're going to tick on this, 100 00:07:48,020 --> 00:07:53,110 we're going to tick, or check the Don't ask again box and then I'm going to deny the permission. 101 00:07:55,660 --> 00:08:00,440 And going back to our logcat, permission refused, which we would expect, and we get a crash if we try and 102 00:08:00,460 --> 00:08:02,670 access by the floating action button. 103 00:08:03,010 --> 00:08:08,080 So now by clicking on that check-box, the user's asked not to be bothered again. So it won't matter 104 00:08:08,080 --> 00:08:11,250 how many times when I run the app and requestPermissions get called, 105 00:08:11,270 --> 00:08:13,390 we'll never be granted permission. 106 00:08:13,390 --> 00:08:18,430 So let's just confirm that; on requestPermissions 107 00:08:18,460 --> 00:08:19,270 Result starts, 108 00:08:19,270 --> 00:08:20,180 permission refused. 109 00:08:20,200 --> 00:08:25,450 And looking at our emulator, we've got no dialog box, clicking on the floating action button and the 110 00:08:25,450 --> 00:08:27,120 app crashes again. 111 00:08:27,280 --> 00:08:32,220 So basically the users are never going to be asked again. Now if the permission was only needed for some 112 00:08:32,220 --> 00:08:37,130 minor function of the app, such as sharing photos when the main purposes is taking them, then you could just 113 00:08:37,140 --> 00:08:39,020 disable that particular function. 114 00:08:39,100 --> 00:08:42,750 But this app's pretty useless without permission to access the contacts though, 115 00:08:43,030 --> 00:08:44,490 because that's all it does. 116 00:08:44,680 --> 00:08:48,700 So the core functionality is now disabled. Before we look at dealing with that, 117 00:08:48,700 --> 00:08:53,260 one thing we should do is prevent the app from crashing when it doesn't have permission. 118 00:08:53,260 --> 00:08:58,950 So an app that does nothing is pretty bad, but we don't want to get a reputation for running apps that crash. 119 00:08:59,170 --> 00:09:03,580 So what I'm going to do is disable the floating action button if we don't have permission to access 120 00:09:03,580 --> 00:09:04,470 the contacts. 121 00:09:04,720 --> 00:09:09,490 Basically I'm going to write the kind of code that you'd use if the permission was for some 122 00:09:09,520 --> 00:09:13,350 peripheral function that wasn't essential for your app to be useful. 123 00:09:13,360 --> 00:09:15,280 So let's work on that in the next video.