1 00:00:05,170 --> 00:00:09,890 Alright so we've established that the app's pretty useless without permission to access the Contacts. 2 00:00:10,070 --> 00:00:11,040 That's all it does, 3 00:00:11,210 --> 00:00:13,580 so the core functionality is now disabled. 4 00:00:13,820 --> 00:00:18,950 We can stop the app from crashing though. An app that does nothing is pretty bad, but we don't want to get 5 00:00:18,950 --> 00:00:21,870 a reputation for writing apps that crash. 6 00:00:21,920 --> 00:00:24,680 So what I'm going to do is disable the floating action button 7 00:00:24,830 --> 00:00:29,900 if we don't have permission to access the contacts. Basically I'm going to write the kind of code that 8 00:00:29,900 --> 00:00:35,890 you'd use if the permission was for some peripheral function that wasn't essential for your app 9 00:00:35,900 --> 00:00:37,400 to be useful. 10 00:00:37,400 --> 00:00:42,710 Now one thing that may not have been obvious when you use a synthetic import, is that the widget reference 11 00:00:42,710 --> 00:00:46,200 is valid throughout the activity's methods. 12 00:00:46,280 --> 00:00:51,990 And that means we can refer to fab in the onRequestPermissionsResult method, and disable it 13 00:00:52,050 --> 00:00:54,410 if the permission isn't granted. 14 00:00:55,130 --> 00:01:01,280 So basically we can access it within the onRequestPermissionsResult function here on the screen now. 15 00:01:01,790 --> 00:01:07,250 Now note that I was careful to say the reference is valid throughout the activity's methods. 16 00:01:07,250 --> 00:01:11,120 It's not necessarily available everywhere in the activity. 17 00:01:11,120 --> 00:01:16,940 And you'll see later that we can't always use these synthetic imports in an inner class which includes 18 00:01:17,030 --> 00:01:23,860 listeners that we implement as an inner class. When onRequestPermissionsResult's called, we can enable 19 00:01:23,860 --> 00:01:27,930 or disable the floating action button depending on the result. 20 00:01:27,980 --> 00:01:34,760 That's quite interesting. We can just come down here outside of the test there for setting the read 21 00:01:34,760 --> 00:01:37,260 Granted variable to True or False. 22 00:01:37,340 --> 00:01:48,210 Now on this next line we can put fab.isEnabled equals readGranted. And basically rather than just 23 00:01:48,210 --> 00:01:53,970 disabling the fab in the else clause, I've used the Boolean field readGranted and put the code at the end 24 00:01:53,970 --> 00:02:00,270 of the case, so that the fab's enabled as well as disabled depending on whether we've got the required 25 00:02:00,270 --> 00:02:01,190 permission or not. 26 00:02:01,410 --> 00:02:03,180 Now that can be a useful technique 27 00:02:03,390 --> 00:02:08,280 when we just want to disable some functionality. Let's just confirm that. We're going to run the app again. 28 00:02:15,160 --> 00:02:20,380 Coming over here now, I'm clicking on the floating action button - the fab button - and nothing's happening. 29 00:02:20,380 --> 00:02:25,200 So the floating action button's now disabled as a result of us not having the required permission. 30 00:02:25,450 --> 00:02:31,400 Now we might do something like that to disable a button or a menu item in a more complex app, but here 31 00:02:31,420 --> 00:02:33,180 it's not very user friendly. 32 00:02:33,190 --> 00:02:37,260 We've got an app that doesn't do anything and there's nothing to let the user know why. 33 00:02:37,540 --> 00:02:39,810 So what I'm going to do instead is comment that line out, 34 00:02:43,640 --> 00:02:50,170 and now it's time for a challenge. Alright, so your challenge is to modify the onClickListener of the floating 35 00:02:50,170 --> 00:02:56,500 action button, so that its onClick method displays a Snackbar if permission to view the Contacts 36 00:02:56,620 --> 00:03:03,490 isn't granted. Now if permission is granted the contact details should be displayed, just as they were when I ran 37 00:03:03,490 --> 00:03:06,340 the app and accepted the permission request. 38 00:03:06,430 --> 00:03:11,500 We haven't covered Snackbars yet and I'm going to go into more detail about them shortly, 39 00:03:11,740 --> 00:03:17,380 but if you create a new project using the basic activity template, you'll find the code you need in the 40 00:03:17,380 --> 00:03:19,950 onClick method that's generated for you. 41 00:03:20,080 --> 00:03:25,510 So you can copy that and paste that code into this project, and note that you can create a new project 42 00:03:25,510 --> 00:03:26,710 without closing this one. 43 00:03:26,800 --> 00:03:30,470 Once you've copied the code and closed a new project you'll be back in this one. 44 00:03:30,790 --> 00:03:31,620 So that's your challenge. 45 00:03:31,620 --> 00:03:36,340 Pause the video now and see how you go with that challenge and I'll see you when you get back. 46 00:03:36,340 --> 00:03:40,020 Pause the video now. 47 00:03:40,020 --> 00:03:41,040 Alright so welcome back. 48 00:03:41,160 --> 00:03:43,070 Hopefully you managed to get through that. 49 00:03:43,110 --> 00:03:45,140 Let's start by creating the new project, 50 00:03:45,160 --> 00:03:51,880 so I'm going to come over here and do File, New project. Now I'm just going to accept all the defaults, 51 00:03:51,910 --> 00:03:59,160 then Next, Next. I'm going to make sure I choose basic activity so we get the Snackbar code in the floating 52 00:03:59,160 --> 00:04:00,300 action button that we need, 53 00:04:00,480 --> 00:04:01,460 Next, 54 00:04:01,740 --> 00:04:02,120 Finish. 55 00:04:09,590 --> 00:04:13,190 OK, once that's loaded I want to go to MainActivity.kt, 56 00:04:13,470 --> 00:04:20,649 and we're going to grab this code, this Snackbar code that's in the onClickListener, the setOnClickListener function 57 00:04:20,760 --> 00:04:22,390 and copy that. 58 00:04:22,600 --> 00:04:24,340 And that's literally all we need from here, 59 00:04:24,340 --> 00:04:25,870 so I'm going to close the project. 60 00:04:26,020 --> 00:04:30,260 Now the full path is up here at the top in the title bar, 61 00:04:30,520 --> 00:04:35,050 so you could make a note of that and delete the directory later if you want, because we're not going 62 00:04:35,050 --> 00:04:36,970 to be re-using that app for anything else. 63 00:04:37,070 --> 00:04:38,310 So I'm going to close this one down, 64 00:04:38,310 --> 00:04:40,410 File, Close Project, 65 00:04:40,980 --> 00:04:45,110 and that brings us back into our other project which was left open. 66 00:04:45,370 --> 00:04:52,250 So what we need to do now is wrap the existing onClickListener method in an if statement. So I'm going to come up here, 67 00:04:53,590 --> 00:04:56,430 and by the way, occasionally I've found in Android Studio you will get these errors 68 00:04:56,430 --> 00:05:02,790 when you open and close files, for some reason. So we click on build and rebuild - that will nearly always fix 69 00:05:02,790 --> 00:05:03,510 the problem. 70 00:05:07,060 --> 00:05:09,630 Alright you can see that the rebuild fixed that problem. 71 00:05:09,640 --> 00:05:16,770 Alright so we need to wrap the code as I mentioned, or wrap an if condition in our setOnClickListener function. 72 00:05:16,780 --> 00:05:24,290 So what we're going to do is, just after the fab onClick starts, a log call. We're going to put an if, parentheses 73 00:05:24,320 --> 00:05:33,940 readGranted, and we're going to open up a code block. Then we're going to add an else, and we're going to open a code block for 74 00:05:33,940 --> 00:05:34,880 the else. 75 00:05:35,010 --> 00:05:39,700 Now what I'm going to do firstly for the else, is I'm going to paste in the code that I've just copied 76 00:05:40,330 --> 00:05:41,740 from the other project - the Snackbar 77 00:05:41,770 --> 00:05:45,010 code - I'm going to paste that in, 78 00:05:45,030 --> 00:05:49,880 noting that it's asking for an import. I'm going to click OK to that, and we're going to change the text 79 00:05:49,880 --> 00:06:00,010 message there, which will be Please grant access to your Contacts. 80 00:06:00,340 --> 00:06:04,700 Alright so that's the else code, and then we need to grab a copy of the code starting from this 81 00:06:04,710 --> 00:06:10,940 val projection line, down to and including the contact names dot adapter equals adapter line. 82 00:06:10,940 --> 00:06:15,240 So I'm going to cut that, just clear up those lines, that line there. 83 00:06:15,320 --> 00:06:20,720 I'm going to paste that in the first code block, if the if condition was true, 84 00:06:21,190 --> 00:06:24,650 and just click on OK there to accept those imports. 85 00:06:24,680 --> 00:06:29,960 So basically that's it. We've now got a test there that's checking to see whether we've got permission and only 86 00:06:29,960 --> 00:06:33,710 trying to execute the code in the fab button, 87 00:06:33,830 --> 00:06:38,450 in other words, to retrieve the contacts and display them if we have got root access, and if we haven't we've 88 00:06:38,540 --> 00:06:43,820 got an else clause down here starting on line 61 that shows a message on the screen. 89 00:06:44,120 --> 00:06:49,760 So what I'm going to do is go back to our emulator, and just to make sure that we're starting with a 90 00:06:49,760 --> 00:06:52,520 clear slate, I'm going to uninstall. 91 00:06:52,550 --> 00:06:56,690 So I'm going to close that down, and I'm going to uninstall as I would normally uninstall - 92 00:07:00,660 --> 00:07:06,780 uninstall Content Provider Example, which is our app of course - and I'm going to run the app again and put 93 00:07:10,720 --> 00:07:11,950 our logcat on screen. 94 00:07:15,070 --> 00:07:19,770 OK and we can tab over to the emulator. You can see we're getting the standard dialog to Deny 95 00:07:19,770 --> 00:07:21,080 or Allow access. 96 00:07:21,120 --> 00:07:27,460 And now when I click on Deny, we got permission refused in logcat, but if I click on the fab button now, 97 00:07:28,570 --> 00:07:32,890 you can see we get this groovy little Snackbar appearing on the bottom of the screen with a message for the 98 00:07:32,890 --> 00:07:33,440 user. 99 00:07:33,610 --> 00:07:35,010 So that's a lot friendlier. 100 00:07:35,320 --> 00:07:40,330 Basically it's telling the user now that they need to grant access to their contacts in order to get 101 00:07:40,330 --> 00:07:42,240 our app to display them. 102 00:07:42,730 --> 00:07:45,700 So your solution to the challenge may have been slightly different to mine. 103 00:07:45,850 --> 00:07:47,940 But if it works, then congratulations. 104 00:07:48,190 --> 00:07:50,460 So with that said, we can do even better than that. 105 00:07:50,490 --> 00:07:55,870 So Snackbars, by the way, were introduced with material design as a replacement for toast messages, 106 00:07:56,230 --> 00:07:59,670 and they're a lot more interactive than the old toast messages were. 107 00:07:59,950 --> 00:08:05,000 So I'm going to stop the video here, and in the next one we'll have a look at Snackbars in more detail, 108 00:08:05,590 --> 00:08:09,240 and once we've done that we can then improve our app even further. 109 00:08:09,430 --> 00:08:10,710 So I'll see you in the next video.