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.

