1 00:00:05,222 --> 00:00:06,560 At the end of the previous video, 2 00:00:06,560 --> 00:00:09,380 we ran the app and we got a security exception 3 00:00:09,380 --> 00:00:11,080 because the app didn't have permissions 4 00:00:11,080 --> 00:00:12,820 to access the Internet. 5 00:00:12,820 --> 00:00:14,290 Now, we had a look at the stack trace 6 00:00:14,290 --> 00:00:16,000 and how it's a useful way to work out 7 00:00:16,000 --> 00:00:18,220 what went wrong, and we're just gonna 8 00:00:18,220 --> 00:00:21,030 run the app again, just to get the same error 9 00:00:21,030 --> 00:00:22,930 and we can see the links in our own code 10 00:00:22,930 --> 00:00:24,190 appear in blue when I do that, 11 00:00:24,190 --> 00:00:25,590 so let's just start that up. 12 00:00:29,990 --> 00:00:32,009 Okay, so you see we've got a crash there 13 00:00:32,009 --> 00:00:34,340 and if we have a look at Logcat, 14 00:00:34,340 --> 00:00:35,760 we can come over here and scroll over 15 00:00:35,760 --> 00:00:37,453 and we can see our links in blue. 16 00:00:38,390 --> 00:00:39,540 I can click on that first link 17 00:00:39,540 --> 00:00:40,990 and that takes us to line 51. 18 00:00:41,941 --> 00:00:44,080 You can see that the error happened 19 00:00:44,080 --> 00:00:46,510 when we tried to do anything with the connection, 20 00:00:46,510 --> 00:00:49,740 in this case, even just reading the response code. 21 00:00:49,740 --> 00:00:51,500 The problem was with the Internet connection 22 00:00:51,500 --> 00:00:54,150 and the fact that it's a security exception 23 00:00:54,150 --> 00:00:57,630 really provides all the remaining information we need. 24 00:00:57,630 --> 00:01:00,200 Just to confirm that it is a security exception again, 25 00:01:00,200 --> 00:01:02,200 let's scroll up and have a look. 26 00:01:02,200 --> 00:01:05,740 Java.lang.SecurityException permission denied 27 00:01:05,740 --> 00:01:06,970 and I got a suggestion there for 28 00:01:06,970 --> 00:01:08,870 missing Internet permissions, perhaps. 29 00:01:09,780 --> 00:01:11,200 Before we look at fixing the problem 30 00:01:11,200 --> 00:01:13,300 which is obviously something we need to do, 31 00:01:13,300 --> 00:01:15,040 let's catch that exception and make 32 00:01:15,040 --> 00:01:17,370 all those error messages a bit tidier 33 00:01:17,370 --> 00:01:19,640 instead of showing the full stack trace. 34 00:01:19,640 --> 00:01:23,054 I'm going to close down the Logcat for now. 35 00:01:23,054 --> 00:01:25,745 We're going to add another catch here 36 00:01:25,745 --> 00:01:28,760 and we're going to put the original exception 37 00:01:28,760 --> 00:01:31,470 back again now, but above that, 38 00:01:31,470 --> 00:01:34,250 what I'm going to do is add another catch 39 00:01:36,020 --> 00:01:38,000 for our security exception. 40 00:01:38,000 --> 00:01:41,473 The catch, e: SecurityException. 41 00:01:45,410 --> 00:01:46,470 Then a code block, and we're gonna do 42 00:01:46,470 --> 00:01:50,770 a Log.e, parentheses tag, comma. 43 00:01:50,770 --> 00:01:54,530 That's gonna be downloadXML: security exception, 44 00:02:01,540 --> 00:02:04,630 needs permission, then we'll put 45 00:02:04,630 --> 00:02:08,002 a dollar sign, left and right curly braces, e.message. 46 00:02:09,250 --> 00:02:11,530 Let's try running that again now. 47 00:02:11,530 --> 00:02:13,330 It should prevent us from getting that 48 00:02:13,330 --> 00:02:15,970 big exception, big stack trace, rather 49 00:02:17,830 --> 00:02:20,513 but we should still see our error logged. 50 00:02:20,513 --> 00:02:22,020 Now it's no longer crashing, but if 51 00:02:22,020 --> 00:02:23,790 we have a look at our Logcat, 52 00:02:23,790 --> 00:02:25,220 you can see I've got a security exception, 53 00:02:25,220 --> 00:02:26,900 needs permission, and then we've got 54 00:02:26,900 --> 00:02:28,410 the message that's coming back from 55 00:02:28,410 --> 00:02:30,550 the actual exception itself, 56 00:02:30,550 --> 00:02:33,030 permission denied, missing Internet permission. 57 00:02:33,030 --> 00:02:36,290 Then of course we've got error downloading as a result. 58 00:02:36,290 --> 00:02:38,370 While we've got some good errors in the Logcat, 59 00:02:38,370 --> 00:02:40,190 I'm gonna digress briefly and show you 60 00:02:40,190 --> 00:02:42,700 a bit more about the Logcat and how you can 61 00:02:42,700 --> 00:02:45,360 make it easier to find information in it. 62 00:02:45,360 --> 00:02:47,690 I'm gonna start by clearing the filter 63 00:02:47,690 --> 00:02:49,093 by clicking on X over here, 64 00:02:50,450 --> 00:02:52,370 and now you can just see how busy the Logcat gets. 65 00:02:52,370 --> 00:02:53,610 There's lots of other information 66 00:02:53,610 --> 00:02:55,620 that we've been filtering out 67 00:02:55,620 --> 00:02:57,390 but we can filter that using the box 68 00:02:57,390 --> 00:03:00,550 near the top right of the AndroidMonitor pane. 69 00:03:00,550 --> 00:03:01,850 Again, you've seen this before, 70 00:03:01,850 --> 00:03:03,350 but if I type in downloaddata, 71 00:03:06,860 --> 00:03:08,260 then we'll only see messages logged 72 00:03:08,260 --> 00:03:11,100 by our downloaddata class, but curiously, 73 00:03:11,100 --> 00:03:13,150 this is sort of case sensitive. 74 00:03:13,150 --> 00:03:16,730 If I delete this and I start the word download 75 00:03:16,730 --> 00:03:18,503 with a capital D, download, 76 00:03:20,960 --> 00:03:22,910 to match the tag that appears in the log, 77 00:03:22,910 --> 00:03:24,270 and you have to continue matching 78 00:03:24,270 --> 00:03:26,710 the case exactly, so downloaddata 79 00:03:26,710 --> 00:03:29,250 will display the entries logged by the class, 80 00:03:29,250 --> 00:03:32,750 but Downloadd, so you can see here. 81 00:03:32,750 --> 00:03:34,050 I don't need to type anymore because 82 00:03:34,050 --> 00:03:37,000 you can see straight away it's not matching anything. 83 00:03:37,000 --> 00:03:38,130 The best thing to do here is to 84 00:03:38,130 --> 00:03:40,370 type all your filters in lowercase, 85 00:03:40,370 --> 00:03:44,423 so downloaddata, which then works again. 86 00:03:45,745 --> 00:03:46,850 Now that I've done that and typed in 87 00:03:46,850 --> 00:03:48,740 downloaddata into the filter box, 88 00:03:48,740 --> 00:03:51,003 we can see the doInBackground starting. 89 00:03:51,940 --> 00:03:54,080 Starts with, and then the link 90 00:03:54,080 --> 00:03:55,630 and the URL that received, obviously, 91 00:03:55,630 --> 00:03:58,300 and it also logs an error after the error 92 00:03:58,300 --> 00:04:02,210 from downloadXML catching the security exception. 93 00:04:02,210 --> 00:04:05,040 Finally, onPostExecute is logging 94 00:04:05,040 --> 00:04:06,430 its parameter as an empty string 95 00:04:06,430 --> 00:04:11,430 which is what we'd expect if doInBackground gave an error. 96 00:04:11,430 --> 00:04:14,120 Again, when I delete the contents or clear it 97 00:04:14,120 --> 00:04:17,567 by clicking on the X, we get heaps of messages again. 98 00:04:17,567 --> 00:04:19,630 Now, this would contain far more 99 00:04:19,630 --> 00:04:22,650 on a physical device, but even an emulator 100 00:04:22,650 --> 00:04:25,490 is continuously logging all sorts of stuff. 101 00:04:25,490 --> 00:04:27,220 In fact, if I change this dropdown here 102 00:04:27,220 --> 00:04:31,130 to the right to no filters and scroll up, 103 00:04:32,850 --> 00:04:35,040 you can see now that there's an absolute load 104 00:04:35,040 --> 00:04:36,380 of things that have been logged here. 105 00:04:36,380 --> 00:04:38,270 Heaps of things, and you can see 106 00:04:38,270 --> 00:04:42,110 there's just pages and pages and pages of stuff there. 107 00:04:42,110 --> 00:04:43,550 I'm gonna change that back to show only 108 00:04:43,550 --> 00:04:47,472 selected applications again, application I should say. 109 00:04:47,472 --> 00:04:50,660 We're just getting stuff that's relevant for us. 110 00:04:50,660 --> 00:04:52,560 The selected application it's referring to 111 00:04:52,560 --> 00:04:54,980 by the way is the one in the second dropdown 112 00:04:54,980 --> 00:04:56,350 from the left, this one here, 113 00:04:56,350 --> 00:04:57,370 which is obviously our app, 114 00:04:57,370 --> 00:05:00,563 our academy.learnprogramming.top10downloader. 115 00:05:01,490 --> 00:05:03,560 Now Android devices have quite a few things 116 00:05:03,560 --> 00:05:05,330 going on at once, so you can actually 117 00:05:05,330 --> 00:05:08,070 look at logs for other applications if you want 118 00:05:08,070 --> 00:05:09,100 but unless you're getting involved 119 00:05:09,100 --> 00:05:10,820 in Android system programming, 120 00:05:10,820 --> 00:05:12,910 you generally just want to leave it to display 121 00:05:12,910 --> 00:05:14,710 just the entries for your app. 122 00:05:14,710 --> 00:05:16,960 If you do want a full stack trace to be printed 123 00:05:16,960 --> 00:05:19,450 when you've caught an exception, you can do that. 124 00:05:19,450 --> 00:05:22,120 I'll just go back here, back to our code, 125 00:05:22,120 --> 00:05:23,220 close down the Logcat. 126 00:05:24,546 --> 00:05:26,090 You can do that by calling 127 00:05:26,090 --> 00:05:28,690 the printStackTrace method of the exception, 128 00:05:28,690 --> 00:05:30,310 so I'm gonna add that to the catch block 129 00:05:30,310 --> 00:05:32,640 for the security exception just to show you. 130 00:05:32,640 --> 00:05:35,450 I'm gonna actually do that before the log. 131 00:05:35,450 --> 00:05:36,708 It doesn't really matter where we do it 132 00:05:36,708 --> 00:05:37,570 but we'll do it before. 133 00:05:37,570 --> 00:05:40,613 We'll do it e.printStackTrace. 134 00:05:41,892 --> 00:05:43,140 Let's go back to the Logcat and make sure that 135 00:05:43,140 --> 00:05:45,770 I have cleared the filter so it doesn't 136 00:05:45,770 --> 00:05:47,540 filter out most of the stack trace. 137 00:05:47,540 --> 00:05:50,080 Basically, I'm gonna get more data by doing that. 138 00:05:50,080 --> 00:05:51,130 Now that I've made that change 139 00:05:51,130 --> 00:05:53,260 let's try running it again. 140 00:05:53,260 --> 00:05:54,190 What I'll do first is I'll actually 141 00:05:54,190 --> 00:05:57,520 clear the filter as well there, clear the Logcat. 142 00:05:57,520 --> 00:05:58,570 We'll run that again. 143 00:06:04,470 --> 00:06:06,453 You can see now that we've done that, 144 00:06:08,290 --> 00:06:11,110 we've printed out quite a bit of stuff there. 145 00:06:11,110 --> 00:06:12,370 Basically, that's the stack trace 146 00:06:12,370 --> 00:06:14,470 that we had before I caught the exception. 147 00:06:15,330 --> 00:06:18,380 You can see scrolling up that it's actually done that. 148 00:06:18,380 --> 00:06:20,870 Android Studio doesn't colour the messages red 149 00:06:20,870 --> 00:06:22,200 and that's because they're created 150 00:06:22,200 --> 00:06:24,830 deliberately by our app now rather than 151 00:06:24,830 --> 00:06:26,960 by the Java Runtime, but the links 152 00:06:26,960 --> 00:06:29,240 in the the code, if we scroll down 153 00:06:29,240 --> 00:06:31,190 and have a look over here to the right, 154 00:06:32,830 --> 00:06:34,420 they're still a different colour. 155 00:06:34,420 --> 00:06:36,820 We can still click on mainactivity.kt 156 00:06:36,820 --> 00:06:40,500 and get to line 51 and see where the error actually is. 157 00:06:40,500 --> 00:06:41,550 Basically, it's the same line of code 158 00:06:41,550 --> 00:06:45,820 that our response equals, connection.responseCode. 159 00:06:45,820 --> 00:06:48,020 Something else we can do, as I mentioned earlier, 160 00:06:48,020 --> 00:06:50,060 is filter out more than one term 161 00:06:50,060 --> 00:06:51,480 and it'd be useful to get some idea 162 00:06:51,480 --> 00:06:53,220 of what's happening through MainActivity 163 00:06:53,220 --> 00:06:54,460 and we can do that by filtering 164 00:06:54,460 --> 00:06:56,620 from MainActivity or downloaddata. 165 00:06:56,620 --> 00:06:57,630 We have seen this before, 166 00:06:57,630 --> 00:07:00,160 but we'll just briefly show that again. 167 00:07:00,160 --> 00:07:01,310 So that's mainactivity. 168 00:07:04,630 --> 00:07:06,110 You've seen the use of this pipe 169 00:07:06,110 --> 00:07:08,217 or bar character before, vertical bar, 170 00:07:08,217 --> 00:07:10,320 which actually means or. 171 00:07:10,320 --> 00:07:11,777 You can type downloaddata, 172 00:07:12,817 --> 00:07:14,850 and now we're getting information 173 00:07:14,850 --> 00:07:17,146 about MainActivity or downloaddata, 174 00:07:17,146 --> 00:07:19,620 so the vertical bar means or, basically. 175 00:07:19,620 --> 00:07:20,840 Alright, so that cleans everything up 176 00:07:20,840 --> 00:07:22,490 and we can see onCreate being started 177 00:07:22,490 --> 00:07:25,437 in MainActivity over here, as well as 178 00:07:25,437 --> 00:07:28,340 the log entries from the DownloadData class. 179 00:07:28,340 --> 00:07:30,812 Okay, so I'm gonna close Logcat for now. 180 00:07:30,812 --> 00:07:33,730 Let's talk about permissions. 181 00:07:33,730 --> 00:07:37,210 By default, an app has no permissions to anything at all. 182 00:07:37,210 --> 00:07:39,010 An app has to get permission from the user 183 00:07:39,010 --> 00:07:41,600 to access resources it needs and this was 184 00:07:41,600 --> 00:07:43,500 usually done when the app's installed. 185 00:07:45,370 --> 00:07:46,872 Now I say was, as you can see on the screen there, 186 00:07:46,872 --> 00:07:50,400 because with Android 6.0, Marshmallow, 187 00:07:50,400 --> 00:07:52,140 Google changed the way that an app 188 00:07:52,140 --> 00:07:55,980 obtained permissions for the resources it needs. 189 00:07:55,980 --> 00:07:58,266 Prior to Android Marshmallow, the user granted 190 00:07:58,266 --> 00:08:01,400 the requested permissions when they installed the app. 191 00:08:01,400 --> 00:08:03,490 If they didn't grant all the permissions, 192 00:08:03,490 --> 00:08:05,710 then the app couldn't be installed. 193 00:08:05,710 --> 00:08:09,270 Once granted, the app had all the requested permissions 194 00:08:09,270 --> 00:08:12,310 for its entire lifetime on the device. 195 00:08:12,310 --> 00:08:13,830 The only way to revoke any of the permissions 196 00:08:13,830 --> 00:08:15,680 was effectively to uninstall the app. 197 00:08:16,720 --> 00:08:19,890 With Marshmallow and above, an app requests 198 00:08:19,890 --> 00:08:22,227 the permissions it needs when it runs 199 00:08:22,227 --> 00:08:25,300 and it has to do so each time it is run. 200 00:08:25,300 --> 00:08:27,530 Now actually Google documentation states 201 00:08:27,530 --> 00:08:29,830 even if the app used the camera yesterday, 202 00:08:29,830 --> 00:08:33,169 it can't assume it still has that permission today. 203 00:08:33,169 --> 00:08:35,860 The documentation isn't as clear as it could be 204 00:08:35,860 --> 00:08:37,820 and if you read it in a certain way, 205 00:08:37,820 --> 00:08:39,390 it could be implying that your app 206 00:08:39,390 --> 00:08:41,600 has to request the permission from the user 207 00:08:41,600 --> 00:08:45,210 each time it runs, but that isn't the case fortunately. 208 00:08:45,210 --> 00:08:47,720 Once the user has granted a permission, 209 00:08:47,720 --> 00:08:50,220 then your app continues to have that permission 210 00:08:50,220 --> 00:08:52,910 unless the user specifically revokes it. 211 00:08:52,910 --> 00:08:54,750 The app still has to request the permission 212 00:08:54,750 --> 00:08:56,800 each time but the Android system 213 00:08:56,800 --> 00:08:59,003 doesn't ask the user every time. 214 00:09:01,270 --> 00:09:02,190 Alright, so let's have a look at 215 00:09:02,190 --> 00:09:03,740 the documentation because apart from 216 00:09:03,740 --> 00:09:06,750 that one source of confusion, it's pretty good. 217 00:09:06,750 --> 00:09:08,550 Google separates their documentation 218 00:09:08,550 --> 00:09:11,200 into reference, guides, and tutorials 219 00:09:11,200 --> 00:09:14,590 and the tutorial pages for permissions explains it all. 220 00:09:14,590 --> 00:09:16,490 I'm gonna just open that in a browser. 221 00:09:19,450 --> 00:09:21,440 Paste the link there. 222 00:09:21,440 --> 00:09:23,060 Now this first page explains that 223 00:09:23,060 --> 00:09:26,440 each app runs in its own sandbox. 224 00:09:26,440 --> 00:09:28,240 Elsewhere in the documentation explains 225 00:09:28,240 --> 00:09:30,180 how this is achieved, which is by 226 00:09:30,180 --> 00:09:32,910 creating a new Linux user ID for each app, 227 00:09:32,910 --> 00:09:34,340 but we don't need to understand that 228 00:09:34,340 --> 00:09:36,930 level of data to work with permissions. 229 00:09:36,930 --> 00:09:39,890 The getting started link down here at the bottom 230 00:09:39,890 --> 00:09:42,240 goes into a bit more detail, so click that, 231 00:09:42,240 --> 00:09:43,700 and it starts by saying the app 232 00:09:43,700 --> 00:09:45,320 has to declare the permissions 233 00:09:45,320 --> 00:09:47,520 it needs in the App Manifest. 234 00:09:47,520 --> 00:09:48,590 We're gonna be doing that for 235 00:09:48,590 --> 00:09:50,660 the Internet permission in a minute. 236 00:09:50,660 --> 00:09:53,700 In this second paragraph is a description 237 00:09:53,700 --> 00:09:57,950 of the different behaviour for Android versions up to 5.1 238 00:09:57,950 --> 00:10:00,640 and for version 6.0 and higher. 239 00:10:00,640 --> 00:10:03,770 Up to 5.1, the user grants permission 240 00:10:03,770 --> 00:10:05,230 when they instal the app. 241 00:10:05,230 --> 00:10:06,870 If they don't grant the permissions, 242 00:10:06,870 --> 00:10:08,900 then the app doesn't instal, 243 00:10:08,900 --> 00:10:11,500 but from Android 6.0 and above, 244 00:10:11,500 --> 00:10:14,320 the user grants permission when they run the app. 245 00:10:14,320 --> 00:10:16,390 It's worth going through this Google tutorial 246 00:10:16,390 --> 00:10:18,410 when you come to create your own apps, 247 00:10:18,410 --> 00:10:19,750 as there are recommendations on 248 00:10:19,750 --> 00:10:22,210 when and how you should request permissions 249 00:10:22,210 --> 00:10:23,940 when your app is running. 250 00:10:23,940 --> 00:10:26,390 Google suggests that you don't request 251 00:10:26,390 --> 00:10:28,470 all the permissions at once, but instead 252 00:10:28,470 --> 00:10:29,840 you wait until the user does something 253 00:10:29,840 --> 00:10:33,630 that needs a permission before asking them for it. 254 00:10:33,630 --> 00:10:35,060 It makes more sense to the user 255 00:10:35,060 --> 00:10:38,030 if your app asks them for permission 256 00:10:38,030 --> 00:10:40,210 to access their contacts when they've just 257 00:10:40,210 --> 00:10:41,990 tried to use your app to share a file 258 00:10:41,990 --> 00:10:43,680 with someone, for example. 259 00:10:43,680 --> 00:10:45,390 But if you request that permission 260 00:10:45,390 --> 00:10:47,550 as soon as they first run your app, 261 00:10:47,550 --> 00:10:48,810 then they may be left wondering why 262 00:10:48,810 --> 00:10:51,323 the app needs to access their contacts at all. 263 00:10:52,190 --> 00:10:53,870 There's a very useful link at the end of 264 00:10:53,870 --> 00:10:56,740 the third paragraph, down here, 265 00:10:56,740 --> 00:10:58,920 which will take you to the definition 266 00:10:58,920 --> 00:11:01,003 of normal and dangerous permissions. 267 00:11:03,030 --> 00:11:04,510 Permission to access the Internet 268 00:11:04,510 --> 00:11:07,380 counts as a normal permission and the system will 269 00:11:07,380 --> 00:11:09,470 automatically grant that permission 270 00:11:09,470 --> 00:11:12,520 as long as we declare it in the manifest. 271 00:11:12,520 --> 00:11:14,780 But scrolling down slightly, 272 00:11:14,780 --> 00:11:16,160 you can see that we've got a list here 273 00:11:16,160 --> 00:11:18,510 of dangerous permissions and permission groups 274 00:11:19,580 --> 00:11:21,450 and we can talk here about permission groups 275 00:11:21,450 --> 00:11:23,810 and I guess it goes into a bit more detail 276 00:11:23,810 --> 00:11:25,450 about the various types of permissions 277 00:11:25,450 --> 00:11:27,690 and this is dangerous permissions as well. 278 00:11:27,690 --> 00:11:29,970 A bit of an overview of what it is. 279 00:11:29,970 --> 00:11:32,350 Looking at the table, it's actually listing 280 00:11:32,350 --> 00:11:36,020 what Android or Google suggests 281 00:11:36,020 --> 00:11:38,130 are dangerous permissions. 282 00:11:38,130 --> 00:11:39,500 We're gonna be looking at how to deal with 283 00:11:39,500 --> 00:11:41,110 requesting permissions when our app is 284 00:11:41,110 --> 00:11:43,250 running later in the course, when we need 285 00:11:43,250 --> 00:11:45,890 access to the contacts and the microphone. 286 00:11:45,890 --> 00:11:48,870 I'm gonna scroll up a bit, basically up to 287 00:11:48,870 --> 00:11:50,490 the normal permissions group here, 288 00:11:50,490 --> 00:11:52,670 normal and dangerous permissions. 289 00:11:52,670 --> 00:11:54,380 There's a link there for normal permissions, 290 00:11:54,380 --> 00:11:55,730 so I'm gonna click on that. 291 00:11:57,780 --> 00:11:59,310 If we have a look you can see if we scroll down, 292 00:11:59,310 --> 00:12:03,060 Internet is defined as a normal permission 293 00:12:03,060 --> 00:12:05,020 so the good news for this app is 294 00:12:05,020 --> 00:12:06,510 we only have to declare that we need 295 00:12:06,510 --> 00:12:08,780 Internet permission in the manifest 296 00:12:08,780 --> 00:12:11,160 and the app will work on all Android versions 297 00:12:11,160 --> 00:12:12,663 that we're actually targeting. 298 00:12:13,880 --> 00:12:15,863 If we go back now to Android Studio, 299 00:12:17,450 --> 00:12:20,480 I'm going to open the Android manifest. 300 00:12:20,480 --> 00:12:22,020 If you're working in Android view, 301 00:12:22,020 --> 00:12:24,170 I suggest you really want to do that, 302 00:12:24,170 --> 00:12:27,060 you'll find the manifest in the manifests folder under app. 303 00:12:27,060 --> 00:12:29,135 If we open it up, you can see that 304 00:12:29,135 --> 00:12:31,560 I'm in Android view here, we've got manifests. 305 00:12:31,560 --> 00:12:34,960 I'm gonna click on that and there's our AndroidManifest.XML. 306 00:12:34,960 --> 00:12:36,860 I can double click on that to open it. 307 00:12:37,800 --> 00:12:39,890 Now, don't worry too much about all this stuff in here. 308 00:12:39,890 --> 00:12:41,570 We're gonna be looking at the application tag 309 00:12:41,570 --> 00:12:44,210 later on and explaining what it means. 310 00:12:44,210 --> 00:12:45,840 For now though, we need to add an entry 311 00:12:45,840 --> 00:12:49,080 to declare that the app uses the Internet. 312 00:12:49,080 --> 00:12:51,630 I'm gonna make some space at the top here, 313 00:12:51,630 --> 00:12:54,540 just after the package, before the start 314 00:12:54,540 --> 00:12:55,863 of the application tag. 315 00:12:56,790 --> 00:12:59,550 I'm gonna start typing the uses tag, 316 00:12:59,550 --> 00:13:02,183 so less than sign and then uses. 317 00:13:04,530 --> 00:13:05,710 I definitely recommend using 318 00:13:05,710 --> 00:13:07,690 the code completion feature here 319 00:13:07,690 --> 00:13:10,520 to make sure you don't make any errors when typing. 320 00:13:10,520 --> 00:13:12,200 If you get the case wrong, you won't see 321 00:13:12,200 --> 00:13:14,450 an error in here but the app won't work 322 00:13:14,450 --> 00:13:16,870 because the permission won't be granted. 323 00:13:16,870 --> 00:13:19,760 I want users-permission, I'll go to tab 324 00:13:19,760 --> 00:13:22,230 to use my arrow keys to go down to that. 325 00:13:22,230 --> 00:13:23,460 Then I'm gonna press enter or I could have 326 00:13:23,460 --> 00:13:25,320 clicked on it to select it. 327 00:13:25,320 --> 00:13:26,470 Notice that when I've done that, 328 00:13:26,470 --> 00:13:28,620 we automatically got this pop-up 329 00:13:28,620 --> 00:13:31,090 and I prefer to use the arrow keys 330 00:13:31,090 --> 00:13:33,010 to select the one I want and that's because 331 00:13:33,010 --> 00:13:34,530 I don't like switching from the keyboard or mouse 332 00:13:34,530 --> 00:13:36,854 but it's your choice as to which one you want. 333 00:13:36,854 --> 00:13:39,210 All the available permissions are shown. 334 00:13:39,210 --> 00:13:41,780 As you can see here, I can select the one I want. 335 00:13:41,780 --> 00:13:44,250 Again, these permissions are case sensitive 336 00:13:44,250 --> 00:13:46,470 so once again, I recommend that you select them 337 00:13:46,470 --> 00:13:49,610 from the list rather than typing them in. 338 00:13:49,610 --> 00:13:50,910 You can filter the list as well, 339 00:13:50,910 --> 00:13:53,221 so if I type in cam for example 340 00:13:53,221 --> 00:13:56,240 you can see that android.permission.camera 341 00:13:56,240 --> 00:13:58,120 is showing on the list, but I don't want that one 342 00:13:58,120 --> 00:14:00,850 so I'm gonna delete cam, type int instead 343 00:14:02,450 --> 00:14:03,890 and you can see we've got some of 344 00:14:03,890 --> 00:14:07,590 the other ones that have got the letters int in them. 345 00:14:07,590 --> 00:14:09,660 You can see that there's the Internet permission there, 346 00:14:09,660 --> 00:14:10,590 the second one, so I'm gonna use 347 00:14:10,590 --> 00:14:12,690 the down arrow key, I'm gonna press enter. 348 00:14:14,340 --> 00:14:15,670 You can see that's added it for us 349 00:14:15,670 --> 00:14:17,870 and I just need to close the tag 350 00:14:17,870 --> 00:14:19,260 with the forward slash, so I'm gonna 351 00:14:19,260 --> 00:14:20,810 click on the forward slash and that closes it 352 00:14:20,810 --> 00:14:22,970 and adds the last bit of the tag 353 00:14:22,970 --> 00:14:24,400 and that's the Internet permission 354 00:14:24,400 --> 00:14:27,090 declared now in the manifest. 355 00:14:27,090 --> 00:14:29,130 This time, the app should run without any errors, 356 00:14:29,130 --> 00:14:32,180 so let's run it and then have a look at the Logcat. 357 00:14:32,180 --> 00:14:33,013 Actually what we'll do is we'll open up 358 00:14:33,013 --> 00:14:36,040 the Logcat first, and we'll run it. 359 00:14:36,040 --> 00:14:37,780 Just clear the log, Logcat, 360 00:14:37,780 --> 00:14:39,130 which I've mentioned before, is a good habit 361 00:14:39,130 --> 00:14:41,100 to get into, even though Android Studio 362 00:14:41,100 --> 00:14:43,000 tends to do that for us at the moment. 363 00:14:44,450 --> 00:14:46,430 Alright, so you can see this time 364 00:14:46,430 --> 00:14:48,930 we haven't got an error anymore. 365 00:14:48,930 --> 00:14:51,080 If we scroll back up to the top, 366 00:14:51,080 --> 00:14:52,280 you can see now right at the top here 367 00:14:52,280 --> 00:14:56,540 we've got downloadXML, the response code was 200. 368 00:14:56,540 --> 00:14:58,420 That's looking good, and that means, 369 00:14:58,420 --> 00:15:02,200 the response code of 200 means OK. 370 00:15:02,200 --> 00:15:03,580 If your Internet connection goes through 371 00:15:03,580 --> 00:15:06,220 a proxy, then you might get a 203 response code 372 00:15:06,220 --> 00:15:07,723 instead but that's also fine. 373 00:15:08,760 --> 00:15:09,843 We can see the XML, you probably saw that 374 00:15:09,843 --> 00:15:12,480 just by scrolling up, and that's the XML 375 00:15:12,480 --> 00:15:14,420 printed by the onPostExecute method 376 00:15:14,420 --> 00:15:17,060 so our download's definitely working fine. 377 00:15:17,060 --> 00:15:18,690 One thing to be aware of is that 378 00:15:18,690 --> 00:15:21,400 there's a limit to how much a log entry can be, 379 00:15:21,400 --> 00:15:24,990 so you won't necessarily see all the XML in the Logcat. 380 00:15:24,990 --> 00:15:27,790 If it hadn't all downloaded there'd be an error 381 00:15:27,790 --> 00:15:30,788 so it looks like everything's fine. 382 00:15:30,788 --> 00:15:32,030 If we scroll down and have a look, 383 00:15:32,030 --> 00:15:34,210 you can see it seems to just chop it off 384 00:15:34,210 --> 00:15:37,240 but again, that's due to the limit of Logcat 385 00:15:37,240 --> 00:15:38,750 and if we saw an error, there was 386 00:15:38,750 --> 00:15:40,370 an error downloading, it would have got 387 00:15:40,370 --> 00:15:43,470 some form of error and we haven't, in this case. 388 00:15:43,470 --> 00:15:46,102 We also logged the number of bytes received. 389 00:15:46,102 --> 00:15:49,570 You can see we received 61601 bytes, 390 00:15:49,570 --> 00:15:52,910 which is about 6k, close to 7k, 391 00:15:52,910 --> 00:15:54,790 showing in the log so that's good. 392 00:15:54,790 --> 00:15:56,740 Obviously it's not all been logged 393 00:15:56,740 --> 00:15:58,920 but it has been downloaded. 394 00:15:58,920 --> 00:16:00,390 By the way, we can see what happens 395 00:16:00,390 --> 00:16:02,100 when things don't work properly. 396 00:16:02,100 --> 00:16:03,210 It's very simple to do, we can just 397 00:16:03,210 --> 00:16:05,880 change the URL to something invalid. 398 00:16:05,880 --> 00:16:08,000 If we close the manifest file now 399 00:16:08,000 --> 00:16:10,390 and just go back up to the top of our file 400 00:16:10,390 --> 00:16:12,950 and we'll just perhaps add another letter. 401 00:16:12,950 --> 00:16:17,820 This axe, let's add ere there to make that invalid. 402 00:16:17,820 --> 00:16:19,173 If we run that again now, 403 00:16:24,300 --> 00:16:26,120 you can see we get a completely different error here. 404 00:16:26,120 --> 00:16:30,010 Unable to resolve host aerex.itunes.apple.com. 405 00:16:30,010 --> 00:16:32,500 We get a traditional error, so basically 406 00:16:32,500 --> 00:16:35,370 it's an IO exception that's being logged there. 407 00:16:35,370 --> 00:16:37,450 We know that because it's IO exception 408 00:16:37,450 --> 00:16:39,210 reading data, which was the message 409 00:16:39,210 --> 00:16:41,820 that we typed in when we specified 410 00:16:41,820 --> 00:16:44,820 the catch block for the IO exception. 411 00:16:44,820 --> 00:16:47,720 You can see here, IO exception reading data. 412 00:16:47,720 --> 00:16:49,460 Now, the extra bit of the error message there, 413 00:16:49,460 --> 00:16:51,220 if we scroll over and have a look. 414 00:16:51,220 --> 00:16:53,420 Unable to resolve host, obviously that's not 415 00:16:53,420 --> 00:16:54,800 something that's come from us, 416 00:16:54,800 --> 00:16:57,750 that's come from this e.message property 417 00:16:57,750 --> 00:16:59,010 over here to the right hand side, 418 00:16:59,010 --> 00:17:00,900 and it's been printed out and basically 419 00:17:00,900 --> 00:17:02,810 we're impending that to the log entry. 420 00:17:02,810 --> 00:17:05,770 Exceptions include various bits of information 421 00:17:05,770 --> 00:17:08,050 and the message is a useful thing to log 422 00:17:08,050 --> 00:17:09,490 because it provides more information 423 00:17:09,490 --> 00:17:11,589 on what may have caused the error. 424 00:17:11,589 --> 00:17:12,810 Alright, so I've now tested that 425 00:17:12,810 --> 00:17:14,869 all three exceptions are caught 426 00:17:14,869 --> 00:17:17,020 but there's one thing more to do. 427 00:17:17,020 --> 00:17:19,200 Firstly, I'm gonna fix line 23. 428 00:17:21,346 --> 00:17:23,030 We're gonna undo that so we're 429 00:17:23,030 --> 00:17:25,317 left with now a valid URL again. 430 00:17:27,067 --> 00:17:28,339 Then what I'm gonna do is turn off 431 00:17:28,339 --> 00:17:30,653 the Internet connection in the emulator. 432 00:17:31,870 --> 00:17:33,993 I'm going to just bring the emulator on the screen. 433 00:17:35,020 --> 00:17:36,400 What I'm gonna do now is turn off 434 00:17:36,400 --> 00:17:38,972 the Internet connection in the emulator. 435 00:17:38,972 --> 00:17:40,700 Unlike a real device where you could just 436 00:17:40,700 --> 00:17:43,040 stop the wifi and mobile data, 437 00:17:43,040 --> 00:17:45,285 you can't actually do that on some emulators. 438 00:17:45,285 --> 00:17:48,300 What we can do though is turn on aeroplane mode, 439 00:17:48,300 --> 00:17:51,370 which prevents the emulator from accessing the network. 440 00:17:51,370 --> 00:17:52,650 Just like a physical device, 441 00:17:52,650 --> 00:17:55,030 you can drag the top of the screen down. 442 00:17:55,030 --> 00:17:58,050 We can do that here to see the common options 443 00:17:58,050 --> 00:17:59,750 but we can also go into settings if we want 444 00:17:59,750 --> 00:18:02,670 and turn on aeroplane mode from there. 445 00:18:02,670 --> 00:18:04,340 Click on that if we wanted to and 446 00:18:04,340 --> 00:18:09,340 we can do a search for aeroplane, select that. 447 00:18:11,141 --> 00:18:13,468 I'm going to turn aeroplane mode on 448 00:18:13,468 --> 00:18:16,420 and so you get the icon at the top of the screen here. 449 00:18:16,420 --> 00:18:18,900 While I'm in there, notice that wifi is off 450 00:18:18,900 --> 00:18:19,870 and that's because the emulator 451 00:18:19,870 --> 00:18:22,370 is using the computer's network connection. 452 00:18:22,370 --> 00:18:23,720 Instead what it does, it sees it 453 00:18:23,720 --> 00:18:25,980 as a mobile data connection. 454 00:18:25,980 --> 00:18:28,940 Mobile data has got an icon on the far left 455 00:18:28,940 --> 00:18:30,490 if we go back to where we were. 456 00:18:32,920 --> 00:18:36,180 I'll just close that down and bring this out again. 457 00:18:36,180 --> 00:18:39,280 We can see over here this is the option 458 00:18:39,280 --> 00:18:41,370 for mobile data connection. 459 00:18:41,370 --> 00:18:43,174 If you click on that it'll click it off 460 00:18:43,174 --> 00:18:44,294 but we're in aeroplane mode. 461 00:18:44,294 --> 00:18:45,440 I'm gonna click it off in any event. 462 00:18:45,440 --> 00:18:48,160 We're gonna leave aeroplane mode on for now 463 00:18:48,160 --> 00:18:49,537 and we come back here and run again. 464 00:18:49,537 --> 00:18:51,100 I'm gonna clear the Logcat just to 465 00:18:51,100 --> 00:18:53,370 get into the habit of doing that. 466 00:18:53,370 --> 00:18:56,500 Let's see what happens with aeroplane mode on 467 00:18:56,500 --> 00:18:58,243 and mobile data turned off. 468 00:19:02,270 --> 00:19:03,620 You can see here we got the error, 469 00:19:03,620 --> 00:19:07,410 IO exception reading data unable to resolve a host. 470 00:19:07,410 --> 00:19:08,530 Without access to the network, 471 00:19:08,530 --> 00:19:12,830 the host then can't be resolved even with a valid URL. 472 00:19:12,830 --> 00:19:15,660 Now, strangely, occasionally you will find 473 00:19:15,660 --> 00:19:17,230 this emulator will work even though 474 00:19:17,230 --> 00:19:18,980 you've set to aeroplane mode. 475 00:19:18,980 --> 00:19:20,640 If that happens, just stop the app and re-run it. 476 00:19:20,640 --> 00:19:21,870 I presume it's some sort of bug, 477 00:19:21,870 --> 00:19:24,308 perhaps with the emulator, but in our case 478 00:19:24,308 --> 00:19:26,220 you can see that it worked here OK. 479 00:19:26,220 --> 00:19:28,740 That's our app downloading the XML for the RSS feed. 480 00:19:28,740 --> 00:19:31,520 What I will do is before we change anything 481 00:19:31,520 --> 00:19:34,090 is just turn aeroplane mode off 482 00:19:34,090 --> 00:19:36,259 and click on to make sure that 483 00:19:36,259 --> 00:19:38,550 my mobile data connection is activated. 484 00:19:38,550 --> 00:19:40,323 We'll just go back and run the app one more time 485 00:19:40,323 --> 00:19:42,853 just to make sure that it is now working again. 486 00:19:47,140 --> 00:19:48,510 You can see we're now getting data 487 00:19:48,510 --> 00:19:51,770 in the Logcat down at the bottom so we're good to go. 488 00:19:51,770 --> 00:19:53,530 Alright, so that's the app downloading 489 00:19:53,530 --> 00:19:55,500 the XML for the RSS feed. 490 00:19:55,500 --> 00:19:57,020 In the next video, we're gonna change 491 00:19:57,020 --> 00:19:58,240 all this code and write it 492 00:19:58,240 --> 00:20:00,610 in a much more Kotlin-like manner, 493 00:20:00,610 --> 00:20:02,310 so I'll see you in the next video.