In the previous videos we wrote a very simple app that created a database and inserted some data into
a Contacts table.
In this video I'm going to show you a little bit about the Android File System.
This can be useful so that we can check where our database file is,
then we'll open it and have a look at the data in there.
So Android is built on Linux. Android and Linux uses forward slashes rather than back slashes in paths.
File and Directory names are case sensitive:
so in other words /data is not the same as /Data with a capital D. Now Android
creates a new user account for each app, to keep each app secure. App data is stored under the package
name in /data/data, and Android emulators are rooted,
and I'll talk more about rooted shortly. The Android operating system is based on Linux.
That's right.
Essentially an Android device is really a Linux system.
So if you've already been using Linux, or used Linux, then you'll be already very familiar with
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
Linux, as both operating systems evolved from Unix.
Now if you're used to Windows on the other hand, remember that Linux uses the slash character in file
paths, the forward slash, rather than the back slash used by Windows.
And again as I mentioned, Android installs and runs each app under a separate user account, and it creates
a new account for every app that's installed. By default,
Linux doesn't allow users to access each other's data,
so this results in a great deal of security.
One app can't access the data belonging to another app, and that includes our database.
Now there are ways to share data, and we will be looking at that later in this section.
Now an app data is stored in a sub directory inside /data/data, and each app has
its own directory in there.
The app's directory name is just the package name, and we'll look at that shortly.
Now finally some of the emulators are rooted, and what that means - it doesn't mean that they're not
working - it means that you've got root access, or administrator access
if you prefer the Windows term, so you can access everything on the device. But unless you've rooted your
physical phone, much of what we're about to do here won't work on a physical Android device.
And the other thing to note is that it won't work on the Google Play emulators. I mentioned way back
in Section 3 that the Google Play emulators don't allow root access.
You can either have the ability to install apps from the Play Store with your emulators, or you can have root
access to the emulator.
You can't have both - at least not at the time I'm recording this video anyway.
So what that means is that it's important not to use a Google Play emulator if you want to examine your
apps database on the emulator. Now the Google APIs
emulators are fine.
Make sure you choose an image that doesn't have an entry in the Play Store column in the AVD manager.
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
we can update that in a few videos time.
But notice we've got the little Play Store icon.
So that's an example of a device that isn't rooted.
So in other words we wouldn't be able to access the database.
But this one down here, and I've actually made it clear that it has got root access, noting that it hasn't got
the Google Play icon there.
And you can see over here it says Google APIs. So we're able,
we've got full access to that, root access to that,
and in fact that's the emulator I've got running at the moment.
And you can see up here, the difference there is it's got Google Play.
So bottom line here is if you want to follow along
in this video and get access to the database from the command line,
you'll need to make sure you're not running an emulator that has been set up with Google Play.
OK.
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.
You can see over here if I tab over to it. There's our sqlitetest app running.
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
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,
our two records coming back, and we've now got it showing with the record ID as
Number 2 as well, as id 2.
And by the way when you run an app on your emulator, Android studio installs it just like any app that you
download on your phone.
So what we're about to see applies to all Android apps.
So we're going to open the terminal window - close this one first,
the logcat. Open the terminal window
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
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.
So you can see that you've got a fair bit of flexibility in how you organize these panes when you're working
with them. Alright, so now about the command line. To check that there's a device available we use the command adb devices,
adb devices. Press enter, and you can see there's a list of devices attached. So that command returns
a list of devices attached.
And you can see here that I've got an emulator connected, noting that an emulator just appears
just as a physical device would,
as far as the adb command is concerned. Now because I've only got the one device connected, I can type
adb shell, and we get a prompt on the device now
so I've gone into the emulator. Now on Linux the command to show a directory listing
is ls, which is the equivalent of dir on windows.
It'll give us a bit more information on each file, so I'm going to do ls space -l lower case. There's
a list of files -
this is on the actual emulator now.
So even though we're effectively running with root access on the emulator, we still don't have permission
to the files in the root directory.
We still haven't got full access to everything, and we're not seeing a permission denied error, but basically there'll
be some files that we won't be able to access until we give ourselves that full access.
Now some emulators such as the Microsoft one will give you more permissions, so you might not get a
permission denied message there. We know that Google changes things a bit
so you may not see it with the Google emulators either.
But you can see here that the bottom line is I haven't got that permission denied.
But it's not a problem though because on an emulator, what we can do is request super user access.
So I'm going to do that.
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
use the su command on a physical device. Even if you've rooted the device, you still need to get the program that
actually runs the su command onto it yourself.
Alright, so now that we can see the file and directory names, the one we're interested in is the directory called
data. Now on Linux, a d in the first position of that sequence of characters - we'll just have a look at that -
d over here, this first sequence of characters, that indicates that it's a directory.
If there's an l there that means we're looking at a symlink,
sort of like a shortcut to another directory.
So looking at etc for example,
notice that that's got an l, and it's actually redirected to slash system slash
etc as you can see over the right hand side there.
So basically etc here,
the folder etc, is a shortcut to the folder /system/etc.
Now we're not really interested in most of the files and directories here.
So let's have a look into that data directory.
So I'm going to type cd space data, then I'm going to type ls space -l. And by the way, notice down
the bottom that the prompt is changing to show the current directory. So we can see now that we've changed
to the data directory - this is the prompt down here. Once again most of the stuff isn't relevant to what we're
doing at the moment,
but you can see how he can use change directory command cd to change into different directories.
Alright, so let's change into the data directory again.
So this will effectively be the data slash data directory.
I'm going to type cd space data again, and notice now that the prompt is showing as data slash data.
So again the prompt's changing to reflect the directory we're currently in,
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
there now.
So now that we're in data data, and now things are starting to get a bit more interesting. We can see the storage
directories now for all the apps listed, or installed rather, on this emulator.
Now there's quite a few that came with the emulator, and we can also see some of the apps that I tested
if we scroll up.
So I'm just going to scroll up and have a look there.
If you keep scrolling up you notice that we've got the academy.learnprogramming ones. We've got calculator,
flickerbrowser,
the sqlitetest, our current app, and also a top10downloader showing there as well.
But basically every app that's installed has got its own folder for databases.
So at this point we're interested in our sqlitetest app.
So referring back to Android Studio briefly - we're scrolling up - notice that, you probably recall that our package
is academy.learnprogramming.sqlitetest.
So therefore we need to use that folder - we need to go into that directory and see what's in there.
So I'm going to type cd space. Now I could type in academy.learnprogramming.sqlitetest, but all I really
need to do is type in the first few letters,
aca in this case, and press tab.
And that gives me a list of all the directories that match what I've typed in so far. So academy
dot learnprogramming dot, and what I could do now is just type an s, press tab again,
and we've now got the full path and I can press enter there.
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.
Now at this point we're really interested in the databases directory.
So let's change into that directory and have a look at our database - cd space and type da again for databases
and a space -l.
And finally we've got to this place now where our database resides, and you probably remember that file
name that we chose - sqlite-test-1.db.
So basically we've found our database file.
Now notice that in addition to the database file, there's a file with the same name and dash journal
on the end.
It's sometimes there, it's usually there, but it may not be there in your case. This dash journal file - this second
one here -
that's a transaction log
that sqlite uses to handle database transactions.
So it's used if something goes wrong
and an update can't be completed for any reason.
So using the transaction log, sqlite can undo all the changes and put the database back into the
state
it was in. If all goes well, it uses the journal file to commit the transaction.
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
in the data/data/academy.learnprogramming.sqlite
test/databases directory.
So once you know your project's package name, you can find the database easily.
It'll always be in the same path -
it's just the package name part that varies.
Alright, so now we've got to this stage, let's open the database and check that it's as we expect it will
be.
So I'm going to type sqlite
3 space and then sqlite. We've got the same option there and I'm going to type select the db, which is selected
for us by default, and just press enter there
now when I press tab, and we're going into the database. So I could've also just typed in the whole
file name but I typed sqlite,
s q l and pressed tab, and we matched part of the name enough for it to open up anyway. Alright so that gives
us the familiar sqlite prompt that we've used earlier in this section of the course, and we can use
all the commands that we've seen in those earlier videos in this section.
So firstly let's check the structure of our database, .schema.
Now that's interesting.
We've got the contacts table that we expected,
but there's another table in there called android underscore metadata.
Now that table's created automatically by the sqlite database class, and it's used for localization
to allow searching for words that contain accented characters, for example. Now it contains a single field
called locale with the locale to be used,
but we don't normally have to worry about that table because Android creates it for us.
So we're going to ignore that table.
Instead we're going to have a look at our contacts data.
So I'm going to type SELECT space * FROM, space * FROM and contacts, and add a semicolon on the end, and there's our
two records.
So let's add another one here to check this is all working properly.
And by the way, if you're unable to run an emulator on your system and you're using a physical device instead,
don't worry about not being able to perform this next step.
Your database will have one less row than mine, but you can always modify the app to add the extra row
if you want.
So what I'm going to do is add a new record
using the sqlite command line interface, and then we should be able to see it when we go back
into our app.
So I'm going to type INSERT space INTO space contacts space VALUES parentheses.
Then I'm going to type 3 comma space and single quote bob single quote common 5678 comma
and a single quote bob@hisemail
dot com single quote right parentheses and a semi-colon. Press enter, and no output usually is a good sign
that the command that we've typed has worked. We can confirm that by typing SELECT space * space FROM space contacts
semicolon, and now we've got an extra record showing there so we're good to go.
And by the way, if you're used to recalling previous commands by pressing the up arrow key -
I'll try that
now - this doesn't work in sqlite from the command line in the Linux shell on the emulators. And that's
fair enough because there's not much point Google including all the bells and whistles,
when we don't spend much time using the shell. It's just a waste of the device's storage.
So you just do have to type the commands in each time to get them to work.
Alright so let's now swing back to Android Studio, now that we've added that record to the database, or more
specifically back to our code.
Now we've got a problem here at the moment - a slight problem. If we run the app again it's going to drop
the table
and wipe out our data that we've just added - the new record.
So what I'm going to do is comment out this code, and basically I'm going to comment out the code all the
way after the val database definition on line 23, all the way down to the query.
So right down here,
right down to there. So I'm going to comment that out,
and I'm also going to comment out this last line down here, because obviously now that code isn't going to work,
given that we've already commented out the other code that created the generated ID variable. Now that
I've done that, we should be able to run our application and see those entries from the database
on our emulator. We'll open up logcat as well.
Give it a moment to start, and this time you can see that we've successfully,
we are successfully seeing three entries there, number one, two and three,
and the third one was obviously Bob, was the entry that we just added from the sqlite3 command line
on our emulator.
Alright so that's a very basic introduction to the Android file system, and accessing the sqlite database
that your Android app creates on an emulator.
It's very useful to be able to do that so that you can check the data that your app's writing to the
database. Being able to check what's being written to the database can make debugging a lot easier.
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
a database app,
but if you're trying to debug a database app then this technique is very useful.
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
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
user mode, exit again which exits from the shell.
Then exit one more time which closes the terminal pane in Android Studio.
Alright so in the next videos we're going to start to see how to do this all properly, using a content
provider for working with databases in Android apps.
See you in the next video.