1 00:00:04,810 --> 00:00:11,430 In the previous videos we wrote a very simple app that created a database and inserted some data into 2 00:00:11,430 --> 00:00:12,900 a Contacts table. 3 00:00:13,050 --> 00:00:17,130 In this video I'm going to show you a little bit about the Android File System. 4 00:00:17,130 --> 00:00:20,670 This can be useful so that we can check where our database file is, 5 00:00:20,790 --> 00:00:23,310 then we'll open it and have a look at the data in there. 6 00:00:23,370 --> 00:00:30,430 So Android is built on Linux. Android and Linux uses forward slashes rather than back slashes in paths. 7 00:00:30,720 --> 00:00:32,830 File and Directory names are case sensitive: 8 00:00:33,120 --> 00:00:39,150 so in other words /data is not the same as /Data with a capital D. Now Android 9 00:00:39,180 --> 00:00:46,200 creates a new user account for each app, to keep each app secure. App data is stored under the package 10 00:00:46,200 --> 00:00:52,490 name in /data/data, and Android emulators are rooted, 11 00:00:52,860 --> 00:00:57,710 and I'll talk more about rooted shortly. The Android operating system is based on Linux. 12 00:00:57,960 --> 00:00:58,530 That's right. 13 00:00:58,530 --> 00:01:02,580 Essentially an Android device is really a Linux system. 14 00:01:02,580 --> 00:01:07,140 So if you've already been using Linux, or used Linux, then you'll be already very familiar with 15 00:01:07,140 --> 00:01:14,580 the file system and the basic commands we're going to look at. 0S X on a Mac also shares a lot in common with 16 00:01:14,580 --> 00:01:18,080 Linux, as both operating systems evolved from Unix. 17 00:01:18,330 --> 00:01:23,580 Now if you're used to Windows on the other hand, remember that Linux uses the slash character in file 18 00:01:23,580 --> 00:01:28,370 paths, the forward slash, rather than the back slash used by Windows. 19 00:01:28,370 --> 00:01:33,450 And again as I mentioned, Android installs and runs each app under a separate user account, and it creates 20 00:01:33,450 --> 00:01:37,570 a new account for every app that's installed. By default, 21 00:01:37,590 --> 00:01:40,650 Linux doesn't allow users to access each other's data, 22 00:01:40,920 --> 00:01:43,240 so this results in a great deal of security. 23 00:01:43,280 --> 00:01:48,540 One app can't access the data belonging to another app, and that includes our database. 24 00:01:48,540 --> 00:01:53,530 Now there are ways to share data, and we will be looking at that later in this section. 25 00:01:53,580 --> 00:02:00,060 Now an app data is stored in a sub directory inside /data/data, and each app has 26 00:02:00,060 --> 00:02:02,130 its own directory in there. 27 00:02:02,250 --> 00:02:06,600 The app's directory name is just the package name, and we'll look at that shortly. 28 00:02:06,600 --> 00:02:11,310 Now finally some of the emulators are rooted, and what that means - it doesn't mean that they're not 29 00:02:11,310 --> 00:02:16,110 working - it means that you've got root access, or administrator access 30 00:02:16,110 --> 00:02:20,750 if you prefer the Windows term, so you can access everything on the device. But unless you've rooted your 31 00:02:20,770 --> 00:02:26,160 physical phone, much of what we're about to do here won't work on a physical Android device. 32 00:02:26,520 --> 00:02:31,530 And the other thing to note is that it won't work on the Google Play emulators. I mentioned way back 33 00:02:31,530 --> 00:02:36,260 in Section 3 that the Google Play emulators don't allow root access. 34 00:02:36,300 --> 00:02:41,550 You can either have the ability to install apps from the Play Store with your emulators, or you can have root 35 00:02:41,550 --> 00:02:42,730 access to the emulator. 36 00:02:42,780 --> 00:02:46,690 You can't have both - at least not at the time I'm recording this video anyway. 37 00:02:46,980 --> 00:02:52,110 So what that means is that it's important not to use a Google Play emulator if you want to examine your 38 00:02:52,110 --> 00:02:55,480 apps database on the emulator. Now the Google APIs 39 00:02:55,490 --> 00:02:56,850 emulators are fine. 40 00:02:56,850 --> 00:03:03,420 Make sure you choose an image that doesn't have an entry in the Play Store column in the AVD manager. 41 00:03:03,450 --> 00:03:11,030 And what I mean by that, so I'm just going to open the AVD manager up, and you can see over here we've got a Nexus 5X API 26, and 42 00:03:11,040 --> 00:03:13,460 we can update that in a few videos time. 43 00:03:13,630 --> 00:03:15,770 But notice we've got the little Play Store icon. 44 00:03:15,810 --> 00:03:18,370 So that's an example of a device that isn't rooted. 45 00:03:18,390 --> 00:03:21,130 So in other words we wouldn't be able to access the database. 46 00:03:21,180 --> 00:03:26,190 But this one down here, and I've actually made it clear that it has got root access, noting that it hasn't got 47 00:03:26,190 --> 00:03:28,100 the Google Play icon there. 48 00:03:28,250 --> 00:03:31,410 And you can see over here it says Google APIs. So we're able, 49 00:03:31,500 --> 00:03:33,380 we've got full access to that, root access to that, 50 00:03:33,570 --> 00:03:35,790 and in fact that's the emulator I've got running at the moment. 51 00:03:35,850 --> 00:03:38,090 And you can see up here, the difference there is it's got Google Play. 52 00:03:38,110 --> 00:03:40,590 So bottom line here is if you want to follow along 53 00:03:40,590 --> 00:03:43,760 in this video and get access to the database from the command line, 54 00:03:43,920 --> 00:03:48,800 you'll need to make sure you're not running an emulator that has been set up with Google Play. 55 00:03:49,280 --> 00:03:49,740 OK. 56 00:03:51,090 --> 00:03:56,970 OK, so I'm back in Android Studio with the sqlite project loaded, and I've started the emulator that I was testing it on. 57 00:03:56,980 --> 00:04:01,320 You can see over here if I tab over to it. There's our sqlitetest app running. 58 00:04:01,320 --> 00:04:04,780 So what I'll do is I'll just run it one more time, just to make sure we're all on the same page and it's 59 00:04:04,790 --> 00:04:11,760 still working. I'll open up logcat, and we'll just show the emulator on the screen. And you can see we've got our data there, 60 00:04:11,790 --> 00:04:16,829 our two records coming back, and we've now got it showing with the record ID as 61 00:04:16,860 --> 00:04:19,060 Number 2 as well, as id 2. 62 00:04:19,410 --> 00:04:24,090 And by the way when you run an app on your emulator, Android studio installs it just like any app that you 63 00:04:24,090 --> 00:04:25,340 download on your phone. 64 00:04:25,590 --> 00:04:28,960 So what we're about to see applies to all Android apps. 65 00:04:29,070 --> 00:04:32,280 So we're going to open the terminal window - close this one first, 66 00:04:32,280 --> 00:04:34,190 the logcat. Open the terminal window 67 00:04:34,190 --> 00:04:40,830 down here by clicking on Terminal. And what I'm going to do is put that into Floating Mode, just so I can move this up here out 68 00:04:40,830 --> 00:04:44,940 of the way a bit and resize it a little bit, so it won't affect any subtitles if you happen to be running that. 69 00:04:46,630 --> 00:04:50,910 So you can see that you've got a fair bit of flexibility in how you organize these panes when you're working 70 00:04:50,910 --> 00:04:59,220 with them. Alright, so now about the command line. To check that there's a device available we use the command adb devices, 71 00:04:59,300 --> 00:05:06,390 adb devices. Press enter, and you can see there's a list of devices attached. So that command returns 72 00:05:06,390 --> 00:05:07,610 a list of devices attached. 73 00:05:07,620 --> 00:05:11,990 And you can see here that I've got an emulator connected, noting that an emulator just appears 74 00:05:12,000 --> 00:05:13,620 just as a physical device would, 75 00:05:13,830 --> 00:05:19,230 as far as the adb command is concerned. Now because I've only got the one device connected, I can type 76 00:05:19,250 --> 00:05:24,670 adb shell, and we get a prompt on the device now 77 00:05:24,680 --> 00:05:29,040 so I've gone into the emulator. Now on Linux the command to show a directory listing 78 00:05:29,040 --> 00:05:33,180 is ls, which is the equivalent of dir on windows. 79 00:05:33,220 --> 00:05:39,450 It'll give us a bit more information on each file, so I'm going to do ls space -l lower case. There's 80 00:05:39,450 --> 00:05:40,540 a list of files - 81 00:05:40,590 --> 00:05:42,550 this is on the actual emulator now. 82 00:05:42,870 --> 00:05:47,820 So even though we're effectively running with root access on the emulator, we still don't have permission 83 00:05:47,820 --> 00:05:49,740 to the files in the root directory. 84 00:05:49,920 --> 00:05:56,120 We still haven't got full access to everything, and we're not seeing a permission denied error, but basically there'll 85 00:05:56,130 --> 00:06:00,820 be some files that we won't be able to access until we give ourselves that full access. 86 00:06:00,820 --> 00:06:05,910 Now some emulators such as the Microsoft one will give you more permissions, so you might not get a 87 00:06:05,910 --> 00:06:09,870 permission denied message there. We know that Google changes things a bit 88 00:06:09,870 --> 00:06:12,060 so you may not see it with the Google emulators either. 89 00:06:12,120 --> 00:06:15,670 But you can see here that the bottom line is I haven't got that permission denied. 90 00:06:15,870 --> 00:06:20,510 But it's not a problem though because on an emulator, what we can do is request super user access. 91 00:06:20,640 --> 00:06:21,790 So I'm going to do that. 92 00:06:22,020 --> 00:06:29,340 Type su, that's the super user access, and do an ls space -l again. And it's very unlikely that you'd be able to 93 00:06:29,340 --> 00:06:36,150 use the su command on a physical device. Even if you've rooted the device, you still need to get the program that 94 00:06:36,150 --> 00:06:39,450 actually runs the su command onto it yourself. 95 00:06:39,790 --> 00:06:45,240 Alright, so now that we can see the file and directory names, the one we're interested in is the directory called 96 00:06:45,240 --> 00:06:52,710 data. Now on Linux, a d in the first position of that sequence of characters - we'll just have a look at that - 97 00:06:52,740 --> 00:06:57,110 d over here, this first sequence of characters, that indicates that it's a directory. 98 00:06:57,270 --> 00:07:00,480 If there's an l there that means we're looking at a symlink, 99 00:07:00,570 --> 00:07:02,700 sort of like a shortcut to another directory. 100 00:07:02,740 --> 00:07:05,180 So looking at etc for example, 101 00:07:05,180 --> 00:07:10,100 notice that that's got an l, and it's actually redirected to slash system slash 102 00:07:10,140 --> 00:07:12,570 etc as you can see over the right hand side there. 103 00:07:13,040 --> 00:07:14,650 So basically etc here, 104 00:07:14,850 --> 00:07:20,580 the folder etc, is a shortcut to the folder /system/etc. 105 00:07:20,580 --> 00:07:23,640 Now we're not really interested in most of the files and directories here. 106 00:07:24,020 --> 00:07:26,200 So let's have a look into that data directory. 107 00:07:26,520 --> 00:07:34,470 So I'm going to type cd space data, then I'm going to type ls space -l. And by the way, notice down 108 00:07:34,470 --> 00:07:39,530 the bottom that the prompt is changing to show the current directory. So we can see now that we've changed 109 00:07:39,550 --> 00:07:44,760 to the data directory - this is the prompt down here. Once again most of the stuff isn't relevant to what we're 110 00:07:44,760 --> 00:07:45,810 doing at the moment, 111 00:07:45,900 --> 00:07:51,190 but you can see how he can use change directory command cd to change into different directories. 112 00:07:51,660 --> 00:07:54,050 Alright, so let's change into the data directory again. 113 00:07:54,240 --> 00:07:57,290 So this will effectively be the data slash data directory. 114 00:07:57,420 --> 00:08:03,550 I'm going to type cd space data again, and notice now that the prompt is showing as data slash data. 115 00:08:03,570 --> 00:08:06,710 So again the prompt's changing to reflect the directory we're currently in, 116 00:08:06,780 --> 00:08:11,790 and that's very useful as a check so that you don't do something in the wrong directory. And I'll do an ls space -l 117 00:08:11,790 --> 00:08:12,940 there now. 118 00:08:13,610 --> 00:08:19,650 So now that we're in data data, and now things are starting to get a bit more interesting. We can see the storage 119 00:08:19,650 --> 00:08:24,310 directories now for all the apps listed, or installed rather, on this emulator. 120 00:08:24,330 --> 00:08:28,650 Now there's quite a few that came with the emulator, and we can also see some of the apps that I tested 121 00:08:28,650 --> 00:08:29,630 if we scroll up. 122 00:08:29,920 --> 00:08:31,480 So I'm just going to scroll up and have a look there. 123 00:08:32,669 --> 00:08:37,299 If you keep scrolling up you notice that we've got the academy.learnprogramming ones. We've got calculator, 124 00:08:37,409 --> 00:08:38,159 flickerbrowser, 125 00:08:38,240 --> 00:08:42,870 the sqlitetest, our current app, and also a top10downloader showing there as well. 126 00:08:43,470 --> 00:08:50,290 But basically every app that's installed has got its own folder for databases. 127 00:08:50,330 --> 00:08:53,030 So at this point we're interested in our sqlitetest app. 128 00:08:53,030 --> 00:08:59,970 So referring back to Android Studio briefly - we're scrolling up - notice that, you probably recall that our package 129 00:08:59,970 --> 00:09:03,510 is academy.learnprogramming.sqlitetest. 130 00:09:04,290 --> 00:09:09,120 So therefore we need to use that folder - we need to go into that directory and see what's in there. 131 00:09:09,120 --> 00:09:15,520 So I'm going to type cd space. Now I could type in academy.learnprogramming.sqlitetest, but all I really 132 00:09:15,530 --> 00:09:17,160 need to do is type in the first few letters, 133 00:09:17,190 --> 00:09:19,740 aca in this case, and press tab. 134 00:09:20,010 --> 00:09:24,670 And that gives me a list of all the directories that match what I've typed in so far. So academy 135 00:09:24,690 --> 00:09:30,480 dot learnprogramming dot, and what I could do now is just type an s, press tab again, 136 00:09:30,640 --> 00:09:34,030 and we've now got the full path and I can press enter there. 137 00:09:34,390 --> 00:09:42,150 And we're now, as you can see by the prompt, in academy.learnprogramming.sqlitetest. I'm going to do an ls space -l again. 138 00:09:42,270 --> 00:09:45,640 Now at this point we're really interested in the databases directory. 139 00:09:45,750 --> 00:09:50,660 So let's change into that directory and have a look at our database - cd space and type da again for databases 140 00:09:51,240 --> 00:09:53,880 and a space -l. 141 00:09:54,060 --> 00:09:59,040 And finally we've got to this place now where our database resides, and you probably remember that file 142 00:09:59,050 --> 00:10:03,370 name that we chose - sqlite-test-1.db. 143 00:10:03,510 --> 00:10:05,380 So basically we've found our database file. 144 00:10:05,590 --> 00:10:11,370 Now notice that in addition to the database file, there's a file with the same name and dash journal 145 00:10:11,370 --> 00:10:11,740 on the end. 146 00:10:11,790 --> 00:10:16,920 It's sometimes there, it's usually there, but it may not be there in your case. This dash journal file - this second 147 00:10:16,920 --> 00:10:17,590 one here - 148 00:10:21,380 --> 00:10:22,800 that's a transaction log 149 00:10:22,910 --> 00:10:26,260 that sqlite uses to handle database transactions. 150 00:10:26,360 --> 00:10:28,200 So it's used if something goes wrong 151 00:10:28,400 --> 00:10:31,060 and an update can't be completed for any reason. 152 00:10:31,100 --> 00:10:36,440 So using the transaction log, sqlite can undo all the changes and put the database back into the 153 00:10:36,440 --> 00:10:36,760 state 154 00:10:36,760 --> 00:10:42,290 it was in. If all goes well, it uses the journal file to commit the transaction. 155 00:10:42,290 --> 00:10:47,960 So at this point anyway, we've found our database file and we can see that I'm now looking at the prompt that's 156 00:10:47,960 --> 00:10:52,090 in the data/data/academy.learnprogramming.sqlite 157 00:10:52,100 --> 00:10:56,150 test/databases directory. 158 00:10:56,150 --> 00:11:00,330 So once you know your project's package name, you can find the database easily. 159 00:11:00,350 --> 00:11:01,960 It'll always be in the same path - 160 00:11:01,970 --> 00:11:04,940 it's just the package name part that varies. 161 00:11:05,080 --> 00:11:09,560 Alright, so now we've got to this stage, let's open the database and check that it's as we expect it will 162 00:11:09,560 --> 00:11:10,250 be. 163 00:11:10,330 --> 00:11:12,370 So I'm going to type sqlite 164 00:11:12,370 --> 00:11:19,850 3 space and then sqlite. We've got the same option there and I'm going to type select the db, which is selected 165 00:11:19,850 --> 00:11:21,250 for us by default, and just press enter there 166 00:11:21,250 --> 00:11:26,690 now when I press tab, and we're going into the database. So I could've also just typed in the whole 167 00:11:26,690 --> 00:11:28,510 file name but I typed sqlite, 168 00:11:28,670 --> 00:11:34,180 s q l and pressed tab, and we matched part of the name enough for it to open up anyway. Alright so that gives 169 00:11:34,190 --> 00:11:39,710 us the familiar sqlite prompt that we've used earlier in this section of the course, and we can use 170 00:11:39,710 --> 00:11:42,930 all the commands that we've seen in those earlier videos in this section. 171 00:11:43,250 --> 00:11:48,420 So firstly let's check the structure of our database, .schema. 172 00:11:48,710 --> 00:11:49,460 Now that's interesting. 173 00:11:49,460 --> 00:11:51,910 We've got the contacts table that we expected, 174 00:11:51,990 --> 00:11:56,490 but there's another table in there called android underscore metadata. 175 00:11:56,730 --> 00:12:03,630 Now that table's created automatically by the sqlite database class, and it's used for localization 176 00:12:03,730 --> 00:12:08,990 to allow searching for words that contain accented characters, for example. Now it contains a single field 177 00:12:08,990 --> 00:12:12,580 called locale with the locale to be used, 178 00:12:12,650 --> 00:12:16,490 but we don't normally have to worry about that table because Android creates it for us. 179 00:12:16,760 --> 00:12:18,370 So we're going to ignore that table. 180 00:12:18,500 --> 00:12:21,480 Instead we're going to have a look at our contacts data. 181 00:12:21,570 --> 00:12:31,930 So I'm going to type SELECT space * FROM, space * FROM and contacts, and add a semicolon on the end, and there's our 182 00:12:32,030 --> 00:12:32,990 two records. 183 00:12:33,340 --> 00:12:36,830 So let's add another one here to check this is all working properly. 184 00:12:37,040 --> 00:12:42,590 And by the way, if you're unable to run an emulator on your system and you're using a physical device instead, 185 00:12:42,620 --> 00:12:45,530 don't worry about not being able to perform this next step. 186 00:12:45,550 --> 00:12:51,140 Your database will have one less row than mine, but you can always modify the app to add the extra row 187 00:12:51,140 --> 00:12:52,090 if you want. 188 00:12:52,100 --> 00:12:54,830 So what I'm going to do is add a new record 189 00:12:54,830 --> 00:12:59,000 using the sqlite command line interface, and then we should be able to see it when we go back 190 00:12:59,030 --> 00:13:00,010 into our app. 191 00:13:00,370 --> 00:13:09,160 So I'm going to type INSERT space INTO space contacts space VALUES parentheses. 192 00:13:09,330 --> 00:13:15,920 Then I'm going to type 3 comma space and single quote bob single quote common 5678 comma 193 00:13:16,440 --> 00:13:19,590 and a single quote bob@hisemail 194 00:13:19,590 --> 00:13:27,660 dot com single quote right parentheses and a semi-colon. Press enter, and no output usually is a good sign 195 00:13:27,660 --> 00:13:34,920 that the command that we've typed has worked. We can confirm that by typing SELECT space * space FROM space contacts 196 00:13:35,520 --> 00:13:41,060 semicolon, and now we've got an extra record showing there so we're good to go. 197 00:13:41,340 --> 00:13:45,000 And by the way, if you're used to recalling previous commands by pressing the up arrow key - 198 00:13:45,210 --> 00:13:45,660 I'll try that 199 00:13:45,660 --> 00:13:51,630 now - this doesn't work in sqlite from the command line in the Linux shell on the emulators. And that's 200 00:13:51,630 --> 00:13:55,350 fair enough because there's not much point Google including all the bells and whistles, 201 00:13:55,500 --> 00:13:59,100 when we don't spend much time using the shell. It's just a waste of the device's storage. 202 00:13:59,120 --> 00:14:03,070 So you just do have to type the commands in each time to get them to work. 203 00:14:03,070 --> 00:14:08,100 Alright so let's now swing back to Android Studio, now that we've added that record to the database, or more 204 00:14:08,100 --> 00:14:09,990 specifically back to our code. 205 00:14:10,110 --> 00:14:15,090 Now we've got a problem here at the moment - a slight problem. If we run the app again it's going to drop 206 00:14:15,090 --> 00:14:15,890 the table 207 00:14:16,170 --> 00:14:19,170 and wipe out our data that we've just added - the new record. 208 00:14:19,170 --> 00:14:23,670 So what I'm going to do is comment out this code, and basically I'm going to comment out the code all the 209 00:14:23,680 --> 00:14:30,330 way after the val database definition on line 23, all the way down to the query. 210 00:14:32,200 --> 00:14:33,020 So right down here, 211 00:14:35,180 --> 00:14:38,290 right down to there. So I'm going to comment that out, 212 00:14:42,600 --> 00:14:48,670 and I'm also going to comment out this last line down here, because obviously now that code isn't going to work, 213 00:14:48,970 --> 00:14:55,930 given that we've already commented out the other code that created the generated ID variable. Now that 214 00:14:55,930 --> 00:15:03,960 I've done that, we should be able to run our application and see those entries from the database 215 00:15:03,970 --> 00:15:07,150 on our emulator. We'll open up logcat as well. 216 00:15:08,420 --> 00:15:13,110 Give it a moment to start, and this time you can see that we've successfully, 217 00:15:13,230 --> 00:15:17,710 we are successfully seeing three entries there, number one, two and three, 218 00:15:17,710 --> 00:15:22,450 and the third one was obviously Bob, was the entry that we just added from the sqlite3 command line 219 00:15:22,570 --> 00:15:23,910 on our emulator. 220 00:15:24,410 --> 00:15:29,770 Alright so that's a very basic introduction to the Android file system, and accessing the sqlite database 221 00:15:29,770 --> 00:15:31,910 that your Android app creates on an emulator. 222 00:15:32,170 --> 00:15:36,670 It's very useful to be able to do that so that you can check the data that your app's writing to the 223 00:15:36,680 --> 00:15:42,140 database. Being able to check what's being written to the database can make debugging a lot easier. 224 00:15:42,430 --> 00:15:47,410 Now this app didn't put very much in the database and, as I've said, it's certainly not the way you should write 225 00:15:47,470 --> 00:15:48,640 a database app, 226 00:15:48,640 --> 00:15:53,040 but if you're trying to debug a database app then this technique is very useful. 227 00:15:53,210 --> 00:15:59,890 Just before I finish, what we're going to do is we'll close this logcat window down. We'll go back to our terminal and 228 00:15:59,890 --> 00:16:06,160 we'll exit out of there. So I'm going to type dot exit, to exit sqlite3, then I'm going to type exit which exits from super 229 00:16:06,160 --> 00:16:10,350 user mode, exit again which exits from the shell. 230 00:16:10,540 --> 00:16:17,350 Then exit one more time which closes the terminal pane in Android Studio. 231 00:16:17,460 --> 00:16:22,000 Alright so in the next videos we're going to start to see how to do this all properly, using a content 232 00:16:22,000 --> 00:16:25,880 provider for working with databases in Android apps. 233 00:16:25,960 --> 00:16:27,060 See you in the next video.