OPSC7311MM
OPSC7311MM
This manual enjoys copyright under the Berne Convention. In terms of the Copyright
Act, no 98 of 1978, no part of this manual may be reproduced or transmitted in any
form or by any means, electronic or mechanical, including photocopying, recording or
by any other information storage and retrieval system without permission in writing
from the proprietor.
Table of Contents
Introduction ............................................................................................................... 4
Learning Unit 1: Introduction to Android Development............................................... 5
1 Introduction ........................................................................................................ 5
2 Android Eco System ........................................................................................... 5
3 Git and GitHub ................................................................................................... 8
4 Recommended Digital Engagement and Activities ........................................... 12
5 Activities ........................................................................................................... 12
6 Revision Exercises ........................................................................................... 13
7 Solutions to Revision Exercises ....................................................................... 13
Learning Unit 2: Creating a Basic Application .......................................................... 14
1 Introduction ...................................................................................................... 14
2 The Android Studio User Interface ................................................................... 14
3 Creating an App ............................................................................................... 15
4 Building a User Interface .................................................................................. 24
5 Running an App ............................................................................................... 60
6 Internationalizing an App .................................................................................. 63
7 Recommended Additional Reading .................................................................. 64
8 Recommended Digital Engagement and Activities ........................................... 65
9 Activities ........................................................................................................... 66
10 Revision Exercises ........................................................................................... 66
11 Solutions to Revision Exercises ....................................................................... 66
Learning Unit 3: Introduction to Kotlin ...................................................................... 67
1 Introduction ...................................................................................................... 67
2 Kotlin Basics .................................................................................................... 67
3 Object-Oriented Programming in Kotlin ............................................................ 73
4 Recommended Additional Reading .................................................................. 76
5 Recommended Digital Engagement and Activities ........................................... 76
6 Activities ........................................................................................................... 76
7 Revision Exercises ........................................................................................... 76
8 Solutions to Revision Exercises ....................................................................... 76
Learning Unit 4: More Advanced Techniques .......................................................... 77
1 Introduction ...................................................................................................... 77
2 Layouts and Controls ....................................................................................... 77
3 Event Handling ................................................................................................. 82
4 Activity Life Cycle ............................................................................................. 92
5 Using Intents .................................................................................................... 99
6 Recommended Additional Reading .................................................................139
7 Activities ..........................................................................................................139
8 Revision Exercises ..........................................................................................139
9 Solutions to Revision Exercises ......................................................................139
Learning Unit 5: Modern Data Management Techniques ........................................140
1 Introduction .....................................................................................................140
2 NoSQL Databases ..........................................................................................140
3 Connect an App to Firebase ............................................................................146
4 Firebase Data Storage ....................................................................................155
Introduction
Welcome to Open Source Coding (Introduction). In this module, we will be focussing
on developing native apps for the Android Operating System (OS). We will make use
of the Kotlin programming language.
In 2022, the Android OS has a market share of 70.97% of mobile devices (G., 2022).
This means that the apps that we learn to develop here, will be able to run on most
mobile devices out there right now.
Throughout this module, you will create several apps to master all the basic skills
needed to build an Android app. It is important to get hands-on experience in any
programming module, so it is essential that you complete all the activities provided on
Learn.
We hope you will enjoy the module and take the opportunity to use the knowledge and
experience gained in both future modules, and in your career.
1 Introduction
In this module, we will learn how to create apps for Android phones. We will start by
creating a user interface that just uses hard coded data, and later in the module we will
also look at how to read data from and write data to a database. In the last learning
unit, we will do something different – creating a game from scratch using the APIs
provided by Android.
This introductory learning unit provides an overview the Android Operating System
(OS) and its features. We will also discuss Android software development and all the
parts of the system that are involved in creating and building a native Android app.
And finally, this learning unit will introduce the sample source code from the GitHub
repository for this module.
Note: All the sample source code in the GitHub repository, and in this Module
Manual, is written in Kotlin.
Each new version of the operating system introduced new features. And these are not
only features of the operating system apps that the user sees, but also features that
app developers can make use of.
The source code for Android is open source. Most of the code is licensed under the
Apache License, Version 2.0. There are exceptions though, like some kernel code that
is licensed under GPLv2. (Android Open Source Project, 2020b) When manufacturers
release devices running the Android OS, proprietary software is usually included too.
(Chen, 2020)
The licensing sounds like it is getting complicated. But, for our purposes as app
developers, working with Android means working with open-source software. So, for
example we can view the code that displays images on the screen. And we can make
use of tools that are completely free to develop our apps.
Installed together with Android Studio is the Android Software Development Kit (SDK).
The SDK is a bundle of the tools that are needed for Android development, such as
the emulator. Although you could use the SDK tools directly, Android Studio actually
integrates all of these things into a single user-friendly app. So, there is little need for
anybody to use those tools directly anymore. (Sinicki, 2019)
The Gradle build system is used to manage the libraries that are used to build software,
and to do the building and running of our apps.
Figure 2. Android Eco System (created using images from (nevoski, n.d.), (Google, 2014), (JetBrains, 2020),
(HowToDoInjava.com, n.d.), (Anon., 2018))
When you run an Android app during development, you need something running the
Android OS to run it on. The first possibility is running the app directly on your phone,
using USB debugging. Read more about how to do that in (Android Open Source
Project, 2019). Of course, that means that you need an Android phone. And it also
means that you are limited to running the version of the operating system that is
currently installed on your phone.
Another way to run an app, is to make use of the emulator (also called Android Virtual
Device). When using the emulator, an instance of the Android OS of your choice is run
in a virtual device on your computer. The benefit of doing that is that you could create
a virtual device that emulates hardware that you don’t own, running any Android OS
version. For phones and tablets, you can choose the screen resolution supported by
the emulator. So, it allows for much greater flexibility when testing your software.
The emulator does have limitations though, for example not being able to emulate
Bluetooth and device-attached headphones. (Android Open Source Project, 2020c)
The emulator also doesn’t support a step counter.
Whether you run the app on the emulator or on a phone, the Android Runtime (ART)
is the software that runs the app on the target OS. It fulfils similar functions to the Java
Virtual Machine (JVM) when you run a Java app on your computer. (Sinhal, 2017)
Earlier versions of the Android OS had a different runtime called Dalvik. (Android Open
Source Project, 2020d)
Git also allows developers to work together in teams and share code, while keeping
track of the work done by each team member.
Figure 3 shows how a distributed version control system such as Git works. Each
developer has a clone of the repository on their computer, and changes are pushed to
and pulled from a central repository that needs to be stored somewhere on a server.
GitHub is not the only option for hosted Git repositories. Other services include
Microsoft Azure DevOps Services (https://azure.microsoft.com/en-
us/services/devops/) and Bitbucket (https://bitbucket.org/product), both of which also
have free tiers. But for our purposes in this module, we will be making use of GitHub.
As with most things in programming, there are multiple ways to clone the repository to
your local computer.
2. In the GitHub Desktop app, click the File menu and then click Clone
Repository.
6. Click Clone.
1. On the command line, go to the folder where you want to clone the source code.
2. Execute the following command:
Now you can open any of the projects in the local working folder in Android Studio.
Open the file res\layout\activity_main.xml. In the Design view, the main activity
should appear as shown in Figure 8. If you see this, then you have successfully opened
the first sample program for this module. And that means that you are ready to jump
into creating your first app in Learning Unit 2!
For this learning unit, watch the following videos from that playlist:
5 Activities
Do the activities that appear on Learn.
6 Revision Exercises
Create your own GitHub account and upload one of your own applications done in
class to the repository.
1 Introduction
In the first learning unit, we explored the Android eco system. This includes Android
Studio, which is the Integrated Development Environment (IDE) that we are using in
the module. We encountered Android Studio for the first time when we opened a
sample project from the GitHub repository.
In this learning unit, we will be using Android Studio to build the user interface of an
app.
These are the areas of the main window as shown in Figure 9 (Android Open Source
Project, 2022b):
1. The menu bar lets you access all the actions that Android Studio can do.
2. The toolbar contains the most frequently used actions such as running the app.
This is context sensitive, so for example in Figure 9 the Git actions appear on
this toolbar since the project was created in a Git repository.
3. The navigation bar shows you a compact view of where the currently open is in
the project.
4. The tool window bar allows you to expand or collapse tool windows.
5. The editor window allows you to edit code and layouts. Depending on which
kind of file is currently open, this area will change.
6. The emulator window shows the app when it is running in the emulator.
7. The output windows display information about the compiling and running of an
app.
8. The status bar displays status messages about the project and builds, including
warnings and messages.
3 Creating an App
Now that we have seen the major areas of the Android Studio user interface, it is
time to create our very first new project.
In the next three learning units, we are going to work on an app called StarSucks. It is
an app for a coffee shop, and in each learning unit we will improve on the functionality.
In this learning unit, we are going to create the basic user interface that displays the
products sold by the coffee shop.
1. If you are on the Welcome to Android Studio window (see Figure 10), click
New Project.
2. If you are already in the main user interface of Android Studio, click the File
menu, then New and then New Project.
3. On the Select a Project Template page of the wizard, make sure that the Phone
and Tablet category is selected.
4. Then select Empty Activity and click Next.
Selecting Empty Activity will start the project off with only a very basic, single
screen. This is ideal for what we want to do here. The other activities create more
advanced starting points for your app that you may want to explore later.
Tip: If you ever want to publish your app on the Google Play Store, the package
name that you choose when creating the app needs to be unique. The default
com.example suggested by Android Studio will NOT be allowed by the Play Store.
So, you must choose something that is going to be unique.
The Kotlin naming convention for packages is to use your organisation’s website
since that is already guaranteed to be unique. You could use for example:
com.vegaschool.st98765432.weatherapp
or
za.co.varsitycollege.st98765432.weatherapp
if st98765432 was your student number. Note how the top-level domain is first in
the package name. It starts with com or za – the opposite of the website address.
6. Click Finish
The project will now be displayed in the main Android Studio user interface. Click the
Build tab (bottom of the user interface) to see what is happening in the background
when the project is created. You will see a Gradle sync process that will be started.
This may take a while when you first create the project, since it retrieves all the libraries
that you need for this project from central artifact repositories online.
Once the initial build is complete, the files in the project will be displayed as shown in
Figure 15.
Side Note: You may notice that the filenames in Figure 15 are displayed in red. This
is because the files have not yet been committed to the repository.
We selected the empty activity template when we created the app, to keep things
simple. But there are several other activity templates that are available out of the box
in Android Studio. Read more about all the templates in (Rout, 2022).
Just as with any other programming work, it is important to run the app early and often,
to make sure it works as expected. If you write a ton of code and then it doesn’t compile,
or doesn’t work, it is much harder to debug than fixing a small piece of code.
Before you can run the app for the first time, you need to set up a Virtual Device. This
is where you can choose what device to emulate.
2. On the Device Manager window, on the Virtual tab, click Create device.
3. Select the Phone category since our app is meant to run on a phone.
4. Select the device that you want to emulate. Let’s use the Pixel 2 device.
Tip: The Play Store icon indicates whether the operating system will have the Play
Store pre-installed. If it is installed, you can log in with your Google login and
download apps on the emulator, just like you would for your phone.
5. Click Next.
6. Next, we select the operating system (see Figure 19) that we are going to use.
Click the Download link next to any of the system images to download it. Once
it is downloaded, it can be selected.
7. Select Oreo or newer.
8. Click Next.
Tip: The system images are quite large. Make sure that you are connected to wi-fi
and not a metered network before you start the download!
9. Lastly, we can name the virtual device (see Figure 21). This will be useful if you
have multiple devices with different configurations. For now, the default will be
fine.
10. Click Finish.
Now that the virtual device has been set up, you can run the app for the first time.
To run the app, click the Run app button on the toolbar ( ) or click Run and then Run
App on the main menu bar.
Tip: Minimise the Device Manager window to make more space for the Emulator
window.
When the Virtual Device is started up for the very first time, it will take some time to
start up. Eventually, you should see the app running in the emulator window in Android
Studio as shown in Figure 22.
Tip: Starting the emulator up takes a while, even if it is not the very first run. But
running the app on the emulator after that is quite fast. So, start the emulator early
and leave it running. Then you can quickly run the app as you make changes.
Tip: If the emulator screen switching off annoys you, you can change the timeout in
the Android operating system running in the emulator. It is under settings > Display
> Advanced > Sleep. The maximum timeout is 30 minutes, which is much better for
this use than the default 1 minute.
There are two ways in which you can create a UI in Android Studio: you can code your
UI in Extensible Markup Language (XML), or you can design it by using the Layout
Editor. If you use the Layout Editor, it will update the XML file for you.
The areas of the Layout Editor in Figure 23 are as follows (Android Open Source
Project, 2020f):
1. The Palette contains the components that you can drag onto your layout.
2. The Component Tree shows all the components that are already on the layout.
3. The toolbar contains tools to change the layout appearance and attributes. For
example, you could change the app’s theme to see how it would look.
4. The design editor shows the layout in design view and blueprint view.
5. The attributes window shows the attributes of the currently selected component.
6. The view mode buttons allow you to switch between the Code (XML) view,
Design view or a Split view showing both.
Let’s switch now to the Code view to see what that looks like.
In Figure 24, we see the XML representation of our design. The XML editor does
provide auto-complete functionality (by pressing Ctrl+Space in editor).
Some developers prefer using the Layout Editor to drag and drop and then customise
UI controls in Android. Other developers prefer to code up the UI in XML.
If we look at the structure below, we see the root element as a ViewGroup, we really
need to understand what a View is before we can understand a ViewGroup. Android
defines as a View as a UI element that draws something the user sees. For example,
a button is view, an ImageView is a view, a scrollbar is a view.
We create a hierarchical structure when we design our layouts, like what is shown in
Figure 25. We will compare this diagram to the image of the XML layout below that.
Root: LinearLayout
ImageView
TextView
In Figure 26, we have our root view LinearLayout which contains two views: an
ImageView and a TextView. Below that is a ScrollView. In Figure 27, we see that
ScrollView expanded to show its contents: a LinearLayout with multiple
ImageViews.
This ViewGroup that makes up our UI looks like the image below.
You cannot see the LinearLayouts (they are invisible) nor the ScrollView – but you
can see the ImageViews and TextViews and how they fit into the hierarchical structure
discussed above.
Tip: It is incredibly important to consider good UI and UX when you develop Android
apps. Users are likely to abandon even the best developed app if it does not look
good and flow well. First impressions matter!
Let us have a look at the different layouts that we have available in an Android App.
4.2.1 LinearLayout
LinearLayout is a root view that will stack all its children either horizontally next to
each other or vertically on top of each other.
4.2.2 RelativeLayout
RelativeLayout aligns UI components relative to each other on the screen and does
not need nested layouts.
4.2.3 ConstraintLayout
You can learn more about ConstraintLayout in (Android Open Source Project,
2020i).
You can learn more about these layouts and how they function in (Lake, 2016) and
(Android Open Source Project, 2020g).
Each activity has two files that get created by Android Studio: a This split is like
Kotlin source file, and a layout XML file. The Kotlin file contains Windows
the behaviour of the activity, and the XML file the layout. The XML Presentation
file is a kind of resource file. So, to understand that we need to Foundation
take a closer look at resources. (WPF) when the
UI is declared in
4.3.1 The res Folder eXtensible
Application
Definition Markup Language
(XAML) and the
“Resources are the additional files and static content that your behaviour in C#.
code uses, such as bitmaps, layout definitions, user interface
strings, animation instructions, and more.” (Android Open Source Project, 2020h)
Your Android resources are contained in the res folder, which correlates to the R class
in Kotlin. You can think of the R class as the glue to combines your Kotlin code and
any resource stored in the res folder. We will store our XML files as well as our images,
colours, strings, and app icons in here. The res folder is broken down into the following
folders:
• drawable will contain all our images, shapes, bitmaps, and vectors etc.
• layout contains the layouts for all our activities, fragments etc.
• mipmap will house our app icon and various place holders.
• values folder holds our String values, Colours, Themes etc.
We need to store all the images we want to use in our app in the drawable folder. We
can store this using Windows Explorer, or we can just copy our images straight into
the drawable folder.
Make sure that the dialog title says Copy as shown in Figure 34. Otherwise, it will
move the files, which might not be what you intended. The files should appear in your
res\drawable folder once you have copied them over.
We are now ready to start building our first app that will display our images. There are
just some rules that we need to discuss. Your app will crash if you use characters that
are not allowed when naming your images.
Image naming convention: You can use small letters from a-z, numbers, and
underscores.
No special characters are allowed because the image in the drawable folder is written
into your R class when your Gradle builds. Characters that are used in Kotlin will then
cause problems. For example, we use & in Kotlin to AND and || to OR etc.
The R class is auto generated by the Android Asset Packaging Tool (AAPT) and
contains all the resource ids to your resources in the res folder. The R class is
automatically updated as you add UI elements in XML files, images in the drawable
folder and strings in the strings.xml file. The R class is rebuilt every time you build
or run your Android project.
In Figure 36, we see how the R class is used in the MainActivity.kt file. We are calling
a method called setContentView here, which will of course set our view. This method
is available because we are inheriting form the AppCompatActivity class. (We will
look at Kotlin code in more detail in the next learning unit.)
We are also passing an argument into this method. We are telling Android where to
find the view that we would like to display to the user when the app opens. We are
passing in R.layout.activity_main. This means in the R class, there is nested class
called layout and it contains a variable that holds the ID for the activity that we would
like to load.
We don’t need to know that numerical value for the ID, because the compiler takes
care of it for us. What is useful to know, is that this is the line of code that links the XML
file to the source code that specifies the related behaviour.
The Constraint
Widget that allows
you to constrain
your UI elements to
the edges of your
screen or other
element
The default
ConstraintLayout as Hello world
the default TextView
Android Studio will have ConstraintLayout as its default layout when you create a
new empty activity. We are going to design our first UI using LinearLayout because
we want our elements vertically aligned. When you open your Layout Editor you will
see the view shown in Figure 37.
We are going to change our layout to LinearLayout for now. There are two ways of
doing this: using the Layout Editor or doing it in the XML file.
3. Start typing a capital letter L. You should see a pop-up menu that lists
LinearLayout near the top of the list.
4. Double click on LinearLayout.
You can simply select the correct orientation from the attributes for your layout in the
Layout Editor. We are selecting Vertical for this example.
You can also just add the following attribute to your XML by typing in the following
attribute. (There will be IntelliSense – IDE pop-ups – to help you.)
android:orientation="vertical"
We will now have all our UI elements vertically stacked on top of each other in the
order that we add them to XML file or Layout Editor.
Now that we have our layout ready, we can start adding in our UI components (Views).
For our first app we are only adding a TextView and an ImageView. We will start with
the ImageView. Once again, this is possible through the Layout Editor or XML.
1. Look for the Palette which contains the Views that can be added to the Layout.
2. Click the Common category to find the most used views. You should see
ImageView listed there.
4. You will see the little guy shown in Figure 47 as you drag the ImageView onto
the preview. Drop this image anywhere on the preview, we are going to move it
where we like it while we design this UI.
Tip: Do you see the checkered background for these images? That means that the
images have a transparent background. It is important to design good UIs so
please use images with transparent backgrounds!
Now the ImageView will appear on your preview. There are a couple of things we
should note here:
This is image is currently too big. We can resize this image by dragging the blue
borders until we get the size that we want.
That is much better, but now our image is stuck to the left of our screen, and we
would like it right smack in the middle. We need to set some attributes for this.
Android has a lot of attributes for Views. You need to expand the drop-down arrow
next to All Attributes and scroll quite a bit down to find the layout_gravity
attribute.
1. Open an XML tag by typing < and then start typing ImageView. IntelliSense
should pop-up and you can simply press Enter on your keyboard to accept the
suggestion.
2. Your ImageView will be inserted and Android Studio will prompt you to add the
layout_width and layout_height as discussed above. You can click on
wrap_content for now. wrap_content means the ImageView will wrap itself
around the actual size of the image.
3. You will notice that the IDE is displaying a small error by showing a red squiggly
line behind the wrap_content entry for the layout height. That is because we
need to close the XML tag.
4. Just enter a forward slash (/) and Android will autocomplete the closing of the
ImageView tag for you.
5. We next need to tell Android Studio where to find our image. We do this with
the src attribute. The full attribute is:
android:src="@drawable/starsuckslogo"
6. There should be IntelliSense popups that will assist you in adding in this entry
quite easily. Add the src attribute.
7. Choose the correct image from the correct resources folder (drawable).
8. Next, we need to centre our ImageView. The full XML attribute is:
android:layout_gravity="center_horizontal"
9. We lastly need to change the height and width so that our image is the correct
size compared to the screen. (See Figure 62.)
Let’s have a look if the ImageView displays correctly. Run the app in the emulator. If
you look to the bottom of your screen you will see the Layout Inspector window in its
minimised state. Click on it to display a window that shows what our layout looks like
right now, with details as in the running app.
A TextView holds text. The text in your TextView can be set programmatically and
using the Layout Editor or XML. Developers need to reuse as much as they can as
well as change the look feel and information of applications quite quickly to remain
competitive. There are shortcuts and easier ways to work String values and Colours in
Android Studio. These however come with a cost later in time. It is worth our while to
store our Strings and Colours in places where we can easily change them when
necessary. We will cover adding a TextView as well as how to store our Strings and
Colours in the values folder under the res folder. We will add our TextView and then
we will add a String value in the correct colour.
You can follow the exact same process we followed to add a UI element (View) as we
did for the ImageView. You can drag and drop it onto your preview in your Layout
Editor or you can add the button using XML. The choice is yours. The truth is that you
will probably jump between the Layout Editor and XML as you go along. I will focus on
XML for the remainder of this module and jump to the Layout Editor where it is just
easier to do. You can follow any pattern that works for you. Every attribute that is
available in XML will also be available in the Layout Editor.
Let’s start with the Layout Editor. You can find the TextView in the Palette, just as we
did with the ImageView. You can now drag and drop this onto your preview.
Remember the Layout Editor will apply a default layout_width and layout_height
attribute. In this case it chose match_parent for the width and wrap_content for the
height. Which makes a rather ugly TextView.
We can off course just change this with the attributes, as shown in Figure 66.
Remember to set
descriptive IDs for
your UI elements
Declared
attributes that are
already set: they
are the same in
XML
The most
commonly used
attributes – you
can define these
here or in XML
Which brings us to an important point – the id. Remember we spoke about the R class
earlier and we discussed how the R class is the glue between our XML UI and our
Kotlin code? That it stores a memory location usually as an int variable? We can only
find our XML UI elements in our Kotlin code if we know the id. We need to set this
value to a value that we will recognise – you will see why when we add some logic to
this application.
The Layout Editor will set a default value as the ID, you are not that lucky in XML, you
need to define your own. It is best practice to give your UI elements easy to understand
descriptive names.
Here the exact same TextView in XML with the ID set correctly and the attributes we
want to use defined.
If we run the app window, we see that the TextView is where we want it and the text
is the correct size.
It is bad practice to hardcode the text that is displayed in the TextView in the XML file.
What if you have used this value 10 000 times, and then the customer decides it needs
to change? A better way is to define the value in strings.xml and reuse that everywhere.
Then you can make the change in one place. The same is true for defining colours in
color.xml too.
There is a folder called values under your res (resources) folder. If you expand it, you
will see that it has three .xml files as shown in Figure 69.
These are used to store the colours, string values and styles of your app in one central
place. We can define our values here and then make a single change that could take
effect in multiple places in our application.
For example, if we used the string “StarSucks originator of the mochaccino” on every
single activity of our app. Let’s say we end up being sued by Luigi who is the originator
of the mochaccino, and we need to chance it to “StarSucks originator of the
chocciechino” if we ever want to sell coffee again. We could change this value instantly
if we stored in strings.xml. Not so much if we hard coded it into every TextView…
Open the strings.xml file. The first string was created by Android. It is your apps name
and used in your Manifest file (more on this later). Add the second entry to use as the
string value for our TextView
We can now use this value in our XML. Instead of the literal value TextView, start
typing an @ (see Figure 71). From the autocomplete pop-up, select our new string
resource.
Whenever we now need these same “Order Now” words in the app, we can make use
again of this same string.
Customers change the look and feel of their brands and products to stay relevant. You
as a developer will often have to update your application’s look and feel to keep up
with logo and slogan changes etc. from your customers. Figure 73 shows how
dramatically different some well-known brands looked before their rebranding.
Rebranding often involves entire new colour palettes too. It would be wise to have our
colours stored so that they are easy to change.
Applications need good user interfaces that are easy to use and provide a good user
experience. It does not matter how brilliant the code behind is. If the interface is not
intuitive, lovely to look at and pleasing to use – chances are that the application will
fail. It is important to carefully consider the colours and placement of UI elements. Let’s
start with colour palettes. For those of us that are not trained designers, there are
beautiful free colour palettes online that we can use.
Hovering over any of the colours will provide a hex value that you can use in colours
resource file.
Colours and the correct use of colours go a long way to assist with designing
applications that are both pretty to look at and possibly easy to use. Let’s start with
Materials Design. Google provides the Materials Design website (available at
https://material.io/design) that deals with everything from icons to colours to navigation.
The good part about this is that Google has hired experts to provide developers with
the know how so that we can create good applications.
For example – if we look at the following colour palette for the Google site, we see
the colour palette as well as how to apply it to an application.
You will also find best practices as to how one should code up the navigation through
your application. Please take the time to refer to this website.
Lastly, we need to carefully consider the placement of our UI elements so that our app
is comfortable and easy to use. Look at the image below:
Abu Experience, 2017. 10 Mobile UX Design Principles You Should Know. [Online]
Available at: http://uxbert.com/10-mobile-ux-design-principles/ [Accessed 17
November 2022].
Creative Bloq, 2012. The 10 principles of mobile interface design. [Online] Available
at: https://www.creativebloq.com/ mobile/10-principles-mobile-interface-design-
4122910 [Accessed 17 November 2022].
Now that we have looked at good use of colours and design principles, we can finally
add some colours to our colors.xml file and use them.
We can “borrow” the Starbucks colours which you can find on the following website:
https://usbrandcolors.com/starbucks-colors/ [Accessed 17 November 2022].
Open your colors.xml file and add the hex value to this file. You will notice that there
are some default android colours available already.
You will note that the colour appears in the margin. You can edit the colour here by
clicking on the block and using the slider as shown in Figure 81.
This makes it quite easy to add your own colours – just copy over a colour, change the
name, and edit it using the colour mixer.
You can now apply the colour to the text in the edit text as shown in Figure 82.
Our text is now Starbucks green but still fairly simple. We will change that next by
adding a font.
We will be using the Layout Editor to add our fonts. It is easier and quicker to do it here
and not in XML. Click on the TextView and search for the fontFamily attribute.
Click More Fonts to get access to the Google fonts. (Scroll down to see that option.)
Select any font you like from the list. You will notice that there are two options when
you select a font, these are:
The downloadable font might not work if there is no internet connection as the font
needs to be downloaded. If you add the font to the project it will always be available,
but this creates large apk (Android install) files.
Android Studio will automatically create the font files in the res folder.
5 Running an App
Now we can run the app in the emulator again to see what it looks like. And so far, it
looks good, even though it doesn’t do much yet.
Let’s look at what happens behind the scenes when the app is built and executed.
Gradle is the build system that creates your Android Package Kit (APK). The APK is
what is installed on your emulator or phone when you run your app. Gradle takes all
your XML files in the res folder as well as all your Java files in the src folder as well
as any dependencies that you have added to your project (you will see later in
Firebase) and runs a script to build your APK.
A script is a coding file that automates processes – in this case creating the APK. It is
completely possible to create your own build script. You could use a language such as
Groovy or bash scripting to do so. For now, we will rely on Gradle.
The Gradle configuration is made up of several files which can be divided into two
categories:
Top level
build.gradle
Module level
build.gradle
The top level Gradle script contains the settings for your entire project and the module
layer Gradle script contains the settings for just this application.
You will notice that Android uses Maven for libraries. Maven is repository that
automates a lot of the build process for us. Including creating the folder structure below.
You should be familiar with it by now.
The module Gradle file contains information specific to our application from the
compiled SDK version, the min SDK version, the version code of our app to the external
libraries (dependencies) that we import.
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 32
defaultConfig {
applicationId "za.ac.iie.opsc7311.starsucks"
minSdk 26
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
Figure 94. Module Level Gradle Script
Gradle can break spectacularly – don’t worry too much if this happens. You should
easily find a solution if you Google the error that Gradle throws.
When the app is just being run on the emulator, or on your phone, you can successfully
use an APK file. But when we get to publishing the app (more about that in
OPSC7312), apps are built as a bundle instead. It is a different format that allows the
Play Store to do smart things like deliver game assets. Read more in (Android Open
Source Project, 2022d).
6 Internationalizing an App
We next want to make translations available to our users. Android displays applications
in information based on the language settings of the device it runs on. We would like
to translate the values in our app for different language settings. You start by setting
the string values that you are willing to translate to translatable="true" for the
values that you want to translate and then translatable="false" for the values you
wish to not translate.
See https://developer.android.com/guide/topics/resources/localization?hl=en
[Accessed 17 November 2022].
Click Open editor (top-right corner of the editor window). This can also be accessed
by right-clicking on the strings.xml file and choosing Open Translations Editor.
Click Add Locale ( ) and then select the language you would like to translate your
values to.
And that is all we need to do. The label already uses the string resource, and Android
will take care of loading the resources for the right language when the app runs.
Tip: You can change the language of the Android operating system running on the
emulator to see the translation in action.
Creative Bloq, 2012. The 10 principles of mobile interface design. [Online] Available
at: https://www.creativebloq.com/ mobile/10-principles-mobile-interface-design-
4122910 [Accessed 17 November 2022].
Lake, I., 2016. Layouts, Attributes, and you. [Online] Available at:
https://medium.com/androiddevelopers/layouts-attributes-and-you-9e5a4b4fe32c
[Accessed 17 November 2022].
For this learning unit, watch the following videos from that playlist:
[YouTube] Add a Textview and work with Strings Colors and Fonts
https://youtu.be/zJU0UmOeTck [Accessed 17 November 2022].
[YouTube] Running app and working with colours and thumb reach
https://youtu.be/rspEeRZ6wqA [Accessed 17 November 2022].
9 Activities
Do the activities that appear on Learn.
10 Revision Exercises
Create your own application that displays a list of funny cat pictures (or any kind of
meme that you enjoy). Make sure you include a caption (using a TextView) for each
image.
1 Introduction
In the first two learning units, we have only really looked at using Android Studio to
build the user interface of our app. This is of course a very important part of an app,
since the user interface affects very directly the user experience of the app. But a user
interface without code behind it that handles the logic can only go so far.
In this module, we are using the Kotlin programming language. Unless you have done
Android development before, you are not likely to have used this language before. The
purpose of this learning unit is to introduce you to the basic features of the language.
Whether you consider your main programming language to be Java or C#, you will see
lots of familiar concepts in Kotlin.
2 Kotlin Basics
2.1 What is Kotlin?
Definition
Looking at this definition, we see that Kotlin was designed with Android development
in mind. That is good news for use, since it means that it is particularly well suited to
what we want to achieve in this module.
Another point is that the language is statically typed. This means that the types of
variables are known at compile time, and the compiler will be able to catch a lot of
errors before you even run the program for the first time. (Bhatnagar, 2018)
The last point that is important is that it has features from object-oriented programming
as well as functional programming. You have done a lot of object-oriented
programming already, so the concepts will be familiar even if the syntax is slightly
different.
Kotlin has great documentation that describes all the features of the language. If you
want to dive straight into the docs, start here: https://kotlinlang.org/docs/basic-
syntax.html [Accessed 17 November 2022].
There is also quite a useful tool for learning Kotlin - the Kotlin Playground. It is an online
environment where you can write and run basic Kotlin programs without having install
anything. We will do most of our coding for this module in Android Studio, of course.
But for the purpose of writing simple Hello World kind of programs, the Kotlin
Playground is useful. You can access it here: https://play.kotlinlang.org/ [Accessed 17
November 2022].
The code will compile with semi-colons too, but that isn’t considered good style in
Kotlin.
Just like Java, Kotlin has the concept of a package that contains related classes (called
a namespace in C#). And just like Java it uses the import keyword to make use of a
package (like using in C#). (Kotlin Foundation, 2022)
The starting point for a Kotlin program is a function called main. An example of that is
shown in Figure 98. This is the first place where we encounter a functional aspect of
the language. You can have a function that exists outside of a class.
You will recall that we said that Kotlin is statically typed. So, the types of the variables
are known at compile time. However, that doesn’t mean that you need to specify the
type – the compiler can infer the type if you assign a value.
In Figure 99, we have a very small Kotlin program. It declares a variable called
favouriteNumber and sets the value to 14. Because the value is assigned, the compiler
infers that the variable must be an integer.
If we wanted to, we could also specify the type of the variable explicitly when it is
declared, like the example in Figure 100.
Recall that if a variable is declared with the val keyword, the value can only be assigned
once. If we try to change the value later, we get an error at runtime indicate that we
cannot do this. So, let us change the declaration to var instead.
Yep, that works as expected. All the normal arithmetic operators like +, -, *, / work just
like they would in Java and C#.
No surprises there. We see the curly brackets around the if and else blocks just like in
Java and C#.
There is no ternary operator (?:) in Kotlin, because you can use an if instead. (Kotlin
Foundation, 2022b) The syntax look like this:
The when statement in Kotlin works a lot like switch in Java and C#. (Kotlin Foundation,
2022b) It is ideal when you have a variable that can have different values, and you
need to do something different for each value.
The interesting thing here is the syntax. The first line matches both 0 and 1. This
illustrates the conciseness of the language.
2.5 Loops
For-loops in Kotlin can only be used for looping over something that provides an iterator
(like a collection or a range). These behave a lot like a foreach loop in C# or a for-loop
in Java that loops over a collection. Let us look at two simple examples.
The difference between the loops is that the for-loop example uses a range expression
to create something the loop can iterate over. And the while-loop example has a more
traditional control variable that we control ourselves.
Kotlin supports the break and continue keywords just like Java and C#.
For more details about the other language features of Kotlin not described here, do
read through the official documentation. It is a concise description of the language,
building on existing programming knowledge of the reader. Perfect for you with your
Java and/or C# skills.
Now is a good time for you to write a few small programs in Kotlin, just so you can get
used to the differences in syntax.
Encapsulation is about hiding “the internal state of one object from the others”.
(Shaukat, 2016) The idea is to separate the parts of the program from one another,
which helps to make our programs easier to debug and maintain.
3.1.2 Inheritance
“Inheritance is an “is-a” relation, which inherits the attributes and behaviors from its
parent class.” (Shaukat, 2016) For example, we could have a vehicle class that
specifies behaviour which can be inherited by the car and truck classes.
3.1.3 Polymorphism
“Polymorphism is the ability of one object to be treated and used like another object.”
(Shaukat, 2016) In our vehicle example, all vehicles could have a turn method. And we
can call the method in the same way for any vehicle. But what the vehicle does in its
turn method would be quite different between a motorcycle and a big rig truck, for
example.
Let us look again at the code from learning unit 2. We very briefly just mentioned that
we have Kotlin code that specified behaviour. Let us look at the generated MainActivity
class in Figure 108.
A class is declared using the class keyword, just like you would expect in Java or C#.
Inheritance is specified using : just like in C#. But there is a difference though. You will
see that there are round brackets () after the parent class name, in this case
AppCompatActivity. That means that the default constructor of the parent class is
called then this MainActivity class is instantiated.
Android Studio makes it easy to navigate between different classes. If you hold Ctrl
and click on the name of the AppCompatActivity class in the above code, Android
Studio will take you to the code for that class. Recall that the Android code is open
source, so we have access to all the code that our program is calling.
In our example in Figure 108, we have a method that is declared. It happens to also
be an override of a method in AppCompatActivity. But here we do see the syntax for
declaring a method. The fun keyword is used to declare a function. It can be either a
top-level function (outside a class), or a method (inside a class).
The syntax for parameters follows the format name: type, which is unlike Java and C#.
But you will recognise the format from when we declared variables with explicit types.
3.2.3 Properties
Properties in Kotlin work a lot like properties in C#. A property is a member variable of
a class that allows access to a field by means of a getter and setter. Auto-implemented
properties in C# automatically create a backing variable without you having to specify
it. (Wagner, et al., 2022) Properties in Kotlin work like that too.
For the property greeting, we defined a custom setter, that checks if the value is empty,
and only sets the value of the backing field if it is in fact not empty. We don’t want to
end up with an empty greeting message in our app, after all.
Remember, for more details about the Kotlin language, read the official documentation.
Now we are ready to use Kotlin code in our apps in the next learning unit.
Work through the Introduction to Kotlin training material on the android.com website
at: https://developer.android.com/ courses/pathways/android-basics-kotlin-one
[Accessed 17 November 2022].
6 Activities
Do the activities that appear on Learn.
7 Revision Exercises
Write a small Kotlin program that prints out the following text pattern:
1 Introduction
Now that we can design a UI and run an application, and we know some Kotlin too, the
time has come to add logic to our app. We are going to slowly build up to an application
that has two activities and that can pass data between the two activities. We are also
going to delve deeper into the linear layout and create a nested hierarchy. We will use
toasts and intents on our second activity.
And finally, we are going to add a navigation drawer to the app to improve the user
experience.
The first thing we need to do, is to remove the action bar. The action bar is the ugly
looking bar on the top of your app that shows your application name.
You could have actions appearing there in your app. But we are not going to do that.
So, the action bar needs to go.
The easiest way to remove the action bar is to access the themes.xml file from the
values\themes folder and to edit the style entry. Change the parent attribute to:
Theme.MaterialComponents.DayNight.NoActionBar
Make a similar change to the themes.xml (night) file too, setting the parent of the style
to:
Theme.MaterialComponents.DayNight.NoActionBar
Now when we run the app again, the action bar no longer appears.
You can find the ScrollView component under the Common category on the Palette.
Next, we add six ImageViews – one for each of the image assets sb1, sb2, sb3, sb4,
sb5 and sb6.
Tip: If you are using the Layout Editor, drag the ImageView onto the LinearLayout
in the Component Tree. If you drag it onto the visual representation, it will not add
it.
Go ahead and create the UI (either using the Layout Editor or the XML view – it is your
choice). The completed UI should look like the one shown in Figure 115. Look
specifically at the hierarchy of components shown in the Component Tree. We have
a LinearLayout that contains a ScrollView that contains a LinearLayout that
contains the six ImageViews.
Note that the order that the components appear in the Component Tree will be the
order that they will appear in the LinearLayout at runtime too.
Another important thing to note here is the naming convention that is used for the
various components. There is no standard naming convention that is specified by the
Android Open Source Project for components in the XML file. But it is important to
stick to a naming convention throughout the app. And if you name your components
well, it will be easy to spot mistakes when you access these from the code a little later.
For this module manual, we will make use of the convention of adding a prefix followed
by an underscore followed by an easy-to-understand name. The prefixes that we use
are as follows (inspired by (Jethro, 2018)):
• ImageView: img
• TextView: tv
• Button: btn
• EditText: et
• FloatingActionButton: fab
Here is the complete layout in XML. Pay careful attention to how the elements are
nested.
<ImageView
android:id="@+id/starsuckslogo"
android:layout_width="232dp"
android:layout_height="152dp"
android:src="@drawable/starsuckslogo"
android:layout_gravity="center_horizontal"/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:fontFamily="@font/hind_guntur_light"
android:text="@string/order_now_label"
android:textColor="@color/starsucksGreen"
android:textSize="30sp" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="@+id/img_sb1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/sb1" />
<ImageView
android:id="@+id/img_sb2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/sb2" />
<ImageView
android:id="@+id/img_sb3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/sb3" />
<ImageView
android:id="@+id/img_sb4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/sb4" />
<ImageView
android:id="@+id/img_sb5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/sb5" />
<ImageView
android:id="@+id/img_sb6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/sb6" />
</LinearLayout>
</ScrollView>
</LinearLayout>
3 Event Handling
We now have plenty UI elements (Views) and it is time to add some logic and event
handling to our application. We have previously discussed how the R class and the
resource (res) folders work. We will now put this information to work.
The MainActivity is created by default when you create your application and the
corresponding two files that make up the activity is immediately available for use.
• MainActivity.kt which is a Kotlin class that allows us to code up the logic of our
application.
• activity_main.xml: Which you by now know is the XML file where we create the
UI for the activity.
To get the variables in the old-fashioned way, we need to declare fields for them and
then initialise them too.
Open the MainActivity.kt file and add the following properties to it:
We don’t have a value for these properties when we declare them, so we add the
lateinit keyword to indicate that we will initialise these later.
You will notice that we use the UI elements (Views) much like data types such as
String, int, float and double. You should also notice that the “data types” (class names)
start with a capital letter. If you think back to the naming conventions that you have
learned, you will remember that class names start with capital letters in Kotlin. The
ImageView “data type” is named in Pascal case (starts with a capital letter) because it
is a class. If you have the sources installed, and you press Ctrl on your keyboard and
click on the ImageView “data type”, the ImageView class will open as shown in Figure
118.
If you look at this code, you will notice that it is written in Java, not Kotlin.
This class contains almost 2000 of lines of code which defines constructors, and all
the methods and properties that we can programmatically use for an ImageView.
Luckily, the Android UI classes abstracts away the complexities of drawing user
interfaces in the Android Operating System. It is sometimes useful to be able to read
the code when something is not working, but we don’t need to understand all the details
to be able to make good use of an ImageView.
When you declare the ImageView fields shown in Figure 117, you may run into the
issue shown in Figure 120.
This error happens when the import is missing and is most likely to happen if you copy
and paste code rather than typing it out. As the blue tooltip suggests, press Alt +
Enter. This will add the import as shown in Figure 121.
Right now, all the variables are still uninitialized. So, we now need to initialise our
variables. We do this by pointing our Kotlin class to the correct XML ID which is stored
in our R class. We do this in the onCreate() method, which is one of the activity life
cycle methods that we will discuss in more detail in section 4. We will use the
findViewById() method to link our XML and Kotlin.
We access that int value by accessing our R class. Inside the R class we will find the
nested (inner) class called id, and inside that we find the IDs for all our components in
the app.
Note that component IDs need to be unique in the whole app, not just on the specific
layout where it is used.
All the initialisation code in the onCreate() method is shown in Figure 123.
I am sure you will agree that this is quite tedious. We have already created the
ImageViews in the XML – why do we need to create a property for each one? Well,
the good news is there is a more modern and easier way, using View Binding. (Leiva,
2020)
The first step is to change something in a gradle.build file. Open the gradle.build file
for the Module: StarSucks.app. In this file, there are a whole bunch of properties used
by Gradle during the build process. Add the below highlighted row to the file, save it,
and rebuild the project.
Now we can change the code to use View Binding. You can delete the properties and
delete all the rows to find the views. Instead, replace the setContentView line with
the two lines shown Figure 125.
Much less code to write. And we don’t need to add code to get components if we add
more of those to the view later.
An OnClickListener reacts when the user clicks or taps on one of our UI elements.
We are going to set an OnClickListener on each of our ImageViews and pop up a
Toast message when a user taps on the ImageView. We will optimise this code later.
We are going to practice for now.
It is easy to add an OnClickListener. In the onCreate method, we can now use the
binding to access our controls. Simply type binding. followed by the name we gave
the ImageView and start typing .setOnClickListener.
Auto complete will pop up with the list of possible methods that can be called (see
Figure 126). With the setOnClickListener method selected on the autocomplete
pop-up, press Enter.
binding.imgSb1.setOnClickListener()
Add {} so we have a space to put the code that gets executed when the image is
tapped.
This syntax makes use of a Lambda in Kotlin. (al3c, 2022) so, we can avoid having to
use anonymous inner classes.
Start typing Toast and select the second option from the IntelliSense pop-up.
• A context (telling Android which activity the toast should appear in)
The Toast message will appear on the MainActivity, for a short duration. Also note
the show() method. Without this our Toast will never appear!
Note: Kotlin, like C#, does have the concept of named arguments. But the context:
label here is just something that is displayed by the IDE for convenience, not
something that you should type! Named arguments in Kotlin use an = not a colon.
Now when we run the app and we tap the first ImageView we will see our message.
Go ahead and add the Toast message for all the other images too. The messages
should be as follows:
Compare your code to the code in the sample repository if you struggle to make it work.
You might be thinking right now that having so many copies of these anonymous inner
classes can’t possibly be the best way to do this. And you would be right. We will
improve this implementation in section 5.1.
Any activity has four essential states and are essentially stacked in the memory. When
you click off one app and onto another the activity you left is placed “behind” the activity
you are currently on. These states can be explained as:
• Active/ Running: This occurs when the activity is on the top of the stack and
currently being used.
• Lost Focus: This activity is still visible to user but not currently being used.
• Stopped: This activity is completely taken over by another activity and no longer
visible to the user. The window is hidden until the user recalls it.
• Destroyed: The activity is dropped from the memory (killed)
As previously mentioned, the activity life cycles are methods that we use to provide
logic for user actions when using, pausing, and stopping the application. These
methods are listed in Figure 134.
Figure 134. Life Cycle Methods (Android Open Source Project, 2020j)
These methods are described below. From (Android Open Source Project, 2020j).
Method Function
onCreate() Called when the activity is first created. This is where you should
do all of your normal static set up: create views, bind data to lists,
etc. This method also provides you with a Bundle containing the
activity's previously frozen state, if there was one.
Always followed by onStart()
onRestart() Called after your activity has been stopped, prior to it being started
again.
Always followed by onStart()
onStart() Called when the activity is becoming visible to the user.
Followed by onResume() if the activity comes to the foreground,
or onStop() if it becomes hidden.
onResume() Called when the activity will start interacting with the user. At this
point your activity is at the top of its activity stack, with user input
going to it.
Always followed by onPause().
onPause() Called when the activity loses foreground state, is no longer
focusable or before transition to stopped/hidden or destroyed state.
The activity is still visible to user, so it's recommended to keep it
visually active and continue updating the UI. Implementations of
this method must be very quick because the next activity will not be
resumed until this method returns.
Followed by either onResume() if the activity returns back to the
front, or onStop() if it becomes invisible to the user.
Method Function
onStop() Called when the activity is no longer visible to the user. This may
happen either because a new activity is being started on top, an
existing one is being brought in front of this one, or this one is being
destroyed. This is typically used to stop animations and refreshing
the UI, etc.
Followed by either onRestart() if this activity is coming back to
interact with the user, or onDestroy() if this activity is going away.
onDestroy() The final call you receive before your activity is destroyed. This can
happen either because the activity is finishing (someone
called Activity#finish on it), or because the system is temporarily
destroying this instance of the activity to save space. You can
distinguish between these two scenarios with
the Activity#isFinishing method.
Adding a new activity is very easy to do. To create a new empty activity:
1. Right-click on your package in the project folder where you want to create it.
2. Click New, then Activity and then Empty Activity (see Figure 135). The New
Android Activity dialog will be displayed.
3. On the New Android Activity dialog (see Figure 136), give the new activity a
name – call it OrderDetailsActivity.
4. Make sure that the Generate a Layout File checkbox is selected.
5. Double check that the package name is the one where you want to create it.
Click Finish.
The new Kotlin file and XML file will be added to the project, as shown in Figure 137.
This UI will display the Image of the product we selected, the name of the product and
allow us to enter our name and nell phone number for delivery.
You will design this UI in the same as we did for the first activity. We will have a nested
layout that contains our UI elements, as shown in Figure 140.
For now, we are just using @mipmap/ic_launcher for the image. It is just a place holder
– we will set it programmatically after the user choses their beverage.
Notice the hints that are set for the two EditTexts. The hint will only be displayed
when nothing has been entered yet.
The FloatingActionButton makes use of the smallheart.png image, the you will find
in the LearningUnit4\assets folder in the repository.
Add the FloatingActionButton by using the Layout Editor. If it prompts you to add
a dependency, accept it. This will add the library to your project that you need for the
FloatingActionButton to work. Wait for the Gradle sync to complete, then the button
will appear.
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="221dp"
app:srcCompat="@drawable/starsuckslogo" />
<TextView
android:id="@+id/tv_placedOrder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:fontFamily="@font/hind_guntur_light"
android:text="You Ordered"
android:textAlignment="center"
android:textColor="@color/starsucksGreen"
android:textSize="30sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/img_orderedBeverage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@mipmap/ic_launcher" />
<EditText
android:id="@+id/et_customerName"
android:layout_width="148dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:ems="10"
android:hint="You are?"
android:inputType="textPersonName" />
<EditText
android:id="@+id/et_customerCell"
android:layout_width="148dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:ems="10"
android:hint="Cellphone"
android:inputType="number" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab_order"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:clickable="true"
app:backgroundTint="@color/starsucksRed"
app:srcCompat="@drawable/smallheart" />
</LinearLayout>
</LinearLayout>
For guidelines about using floating action buttons in your user interfaces, read
https://material.io/components/buttons-floating-action-button [Accessed 17 November
2022].
5 Using Intents
Now that we have our UI ready, we can add the necessary logic to our application. We
want to click on one of our products in the MainActivity and use an Intent to open
the new activity and to pass the name of the product over to the
OrderDetailsActivity. We are also going to start by optimising our code on the
We previously discussed the OnClickListener and the fact that it is an interface that
lives in the View class. Android enables use a lambda created from that interface into
the setOnClickListener(). That is one way of using an onClickListener. It works
perfectly – most of the time.
But we have multiple ImageViews and we only want one OnClickListener to fire
when we click the any of the ImageViews. We would also like to avoid redundant and
repeated code.
© The Independent Institute of Education (Pty) Ltd 2023 Page 100 of 200
IIE Module Manual OPSC7311
Now our onClick() method needs to be implemented to do the same work that the
individual onClick() methods did before. For that, we need to be able to determine
which View was clicked. Luckily, the method takes a parameter which is the View, so
we can use the id of that view to determine what to do. This is the perfect opportunity
to use the when statement.
© The Independent Institute of Education (Pty) Ltd 2023 Page 101 of 200
IIE Module Manual OPSC7311
This might not feel like much of a win right now, but when the event handlers get more
complex later, you will appreciate this improvement!
The four properties declared here are public, even though that is not explicitly stated
here. But we don’t need to make these private to maintain encapsulation. The getters
and setters are automatically created, just like in C#. So, there is no need for get and
set methods. (Agrawal, n.d.)
We do still want a few different constructors that we can use, depending on what data
we have available when we create the instance. The syntax for constructors is probably
the strangest thing if you are used to Java or C#.
Each Kotlin class has a primary constructor and (potentially) secondary constructors.
The primary constructor forms part of the header of the class. (Programiz, 2022)
© The Independent Institute of Education (Pty) Ltd 2023 Page 102 of 200
IIE Module Manual OPSC7311
Our app currently gets the product name from our first activity (MainActivity). Here
is what we would like to happen:
© The Independent Institute of Education (Pty) Ltd 2023 Page 103 of 200
IIE Module Manual OPSC7311
The process above is completed with Intents. Our first Intent will simply open a new
activity and pass a single value over to the new activity.
Our second Intent will open the share hub and use a bundle to pass multiple values
to which ever app choose to use to share our order.
We can use Intents and extras to share information quickly and easily between
activities and applications.
Intents are not only used to share information, they are also used to open new
activities, send broadcasts and to start services. You can read up more about this here:
https://developer.android.com/guide/components/intents-filters [Accessed 17
November 2022].
There are two types of Intents namely explicit and implicit Intents. We will be using
both. They can be described as:
Explicit Intents: Specify which application or activity they will open. We will be using
an explicit Intent to open our Order Details activity and to pass our product to this
Activity using an Explicit Intent. Explicit Intents are often used within your own
application since you will know the class name of the Activity that you would like to
open.
Implicit Intents: These Intents do not specify a specific application or Activity. They
declare a general action instead. For example, we will create an Implicit Intent that
will allow us to open the Android share sheet and share the product name the
customer has selected as well as other information via any of the installed
applications that we choose.
https://vogella.com/tutorials/AndroidIntent/article.html[Accessed 17 November 2022].
© The Independent Institute of Education (Pty) Ltd 2023 Page 104 of 200
IIE Module Manual OPSC7311
Definition
“Helper classes contains functions that help in assisting the program. This Class
intends to give quick implementation of basic functions such that programmers do
not have to implement again and again.” (sahilkhoslaa, 2018)
We are going to create a helper class that will help our application with Intents.
The first thing we need to accomplish is opening the Order Details activity using an
explicit intent. You can go ahead and add a new Kotlin Class and call it IntentHelper.
We will add our first function called openIntent(). This method accepts the Context,
a String value and the Class to open (the activity class) as parameters.
Notice that the function isn’t inside a class. Kotlin supports having functions that are
visible in the package where they are declared. (Doan, 2020) And that is what we are
doing here.
© The Independent Institute of Education (Pty) Ltd 2023 Page 105 of 200
IIE Module Manual OPSC7311
Looking at the code of the intent class shown in Figure 148, we see that the second
parameter is the class that we want to open. Kotlin makes use of generics here. But
we don’t know which class we will be passing to our function yet. So, the Class<*>
indicates that it can be any class. (Foundation, 2022c)
You will see Context everywhere in Android development. There are lots of
explanations on the internet as to what a Context really is. These can be incredibly
confusing. The Android documentation defines a Context as:
A Context is often called a God object. A God object is an object that knows too
much and does too much. That is because Contexts are so integral to Android
Development. You can read more about Context here:
https://www.freecodecamp.org/ news/mastering-android-context-7055c8478a22/
[Accessed 17 November 2022].
A very simple explanation is that a Context provides context to the newly added
components of an Android application. It allows us to tell an activity where it is
originating form or to tell a Toast message in which activity it should pop up. Don’t let
this break your head for now.
We next need to create an Implicit Intent to share our order. We will use polymorphism
to create two methods that will provide the functionality to use implicit Intents to our
application. This is because we can send a single value with an Intent and an Extra
(putExtra) or we can send multiple values with a Bundle. We will start by sending just
a single value to any application the user selects form the Android share sheet. We will
later optimise this code to send a bundle of data to the android app that we call with
the Implicit Intent.
© The Independent Institute of Education (Pty) Ltd 2023 Page 106 of 200
IIE Module Manual OPSC7311
The MIME type defines the format of our Data – plain Text in our case. You can read
more about MIME types here: https://developer.mozilla.org/en-
US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
Finally we will create the overloaded shareIntent() method. This method accepts all
the same parameters as the original shareIntent() method, but adds the
customerName and customerCell as further data that we would like to share.
© The Independent Institute of Education (Pty) Ltd 2023 Page 107 of 200
IIE Module Manual OPSC7311
We can now update the onClick() method to make use of the order and the
IntentHelper.
If you run the app now, our new activity will be opened when you tap on one of the
products. But it won’t do anything with the data yet.
© The Independent Institute of Education (Pty) Ltd 2023 Page 108 of 200
IIE Module Manual OPSC7311
Have a close look at the last two lines of code in Figure 154. We can get the value that
we passed through from the intent, by calling the getStringExtra() method.
The last thing we need to do, at the end of the onCreate method, is to change the
image based on what the customer picked.
If we run the app now, and click on one of the products, the order details will be
displayed correctly including the picture for the product.
© The Independent Institute of Education (Pty) Ltd 2023 Page 109 of 200
IIE Module Manual OPSC7311
Now when we tap the FloatingActionButton, the Android share sheet is show,
where the user can choose which app to use for sharing.
© The Independent Institute of Education (Pty) Ltd 2023 Page 110 of 200
IIE Module Manual OPSC7311
When a new app is created, there is an option for creating a Navigation Drawer
Activity as the starting point for the app. But the code generated for that is fairly
complex, so let’s see how to implement this from scratch.
© The Independent Institute of Education (Pty) Ltd 2023 Page 111 of 200
IIE Module Manual OPSC7311
1. Right-click on the res folder in your app project and click New followed by
Android Resource Directory.
© The Independent Institute of Education (Pty) Ltd 2023 Page 112 of 200
IIE Module Manual OPSC7311
2. On the New Resource Directory dialog, select the Resource Type menu.
3. Click OK.
This will create the menu folder under res, as shown in Figure 162.
Next, we need to create the menu. It is the XML file that tells the navigation drawer
which items need to be displayed on the menu.
1. Right-click on the menu folder that we just created. Click New and then Menu
Resource File (see Figure 163).
© The Independent Institute of Education (Pty) Ltd 2023 Page 113 of 200
IIE Module Manual OPSC7311
2. On the New Resource File dialog, enter the File name navigation_menu.
3. Click OK.
You will see the design view for the menu, and the XML file with only the top-level
menu tag created can be viewed using the Code view. Next, we will create the icons.
And then we will return here to add the menu items.
© The Independent Institute of Education (Pty) Ltd 2023 Page 114 of 200
IIE Module Manual OPSC7311
We are going to need two icons: one for the main page where we are placing our order,
and one for the photo activity that we will add later.
To create an icon:
1. Right-click on the drawable folder, click New and then Vector Asset.
© The Independent Institute of Education (Pty) Ltd 2023 Page 115 of 200
IIE Module Manual OPSC7311
6. Check the directory where the resource will get created – it should be in drawable.
Then click Finish.
Create another vector asset for the photo activity and call it ic_menu_photo.
Now we can get back to creating the menu structure. This can be done either in the
XML or the Design view. Here we will describe how to do this using the Design view.
So, open the navigation_menu.xml file, and switch to the Design view (top-right
corner).
1. Drag a Group from the Pallet into the Component Tree (see Figure 169).
2. Set the checkableBehaviour attribute of the group to single. This is to ensure
that only one page at a time will be highlighted in the menu.
© The Independent Institute of Education (Pty) Ltd 2023 Page 116 of 200
IIE Module Manual OPSC7311
3. Add two menu items to the group – one for the main activity and one for the
pending photo activity.
4. Set the id, title and icon for each of the items.
© The Independent Institute of Education (Pty) Ltd 2023 Page 117 of 200
IIE Module Manual OPSC7311
At the top of a navigation drawer, there is an area where you display something
graphical to make the menu look good. We are going to display the StarSucks logo
there.
We are going to create a layout resource file, that works just like the layouts that we
have used for activities so far.
1. Right-click on the layout folder, click New and then click Layout Resource File.
© The Independent Institute of Education (Pty) Ltd 2023 Page 118 of 200
IIE Module Manual OPSC7311
Now we have all the components created, and we can use these now to add the
Navigation View to the MainActivity.
DrawerLayout
• Top level layout for the activity
Main View
• Copy of our original controls
• Add at the top a toolbar
Navigation View
• Header
• Menu
Figure 173 shows all the components that we need eventually on the MainActivity.
We are going to implement the changes using the Layout Editor. The safest way to do
that, is to create a new layout and copy the existing controls into that. At the end you
can then delete the original layout.
Create a new layout now, following the same steps that we did for the navigation
drawer header, and call it activity_main_with_nav_drawer.
© The Independent Institute of Education (Pty) Ltd 2023 Page 119 of 200
IIE Module Manual OPSC7311
3. Copy and paste the components, starting from the top-level element, into the
new layout. The component tree should look like Figure 176.
4. Drag and drop a NavigationView above the LinearLayout (see Figure 177).
Hint: use the search function on the palette.
5. Set the id for the NavigationView to nav_view.
6. Set the fitsSystemWindows attribute to true.
7. Choose the headerLayout that we created earlier.
8. Choose the menu that we created earlier.
© The Independent Institute of Education (Pty) Ltd 2023 Page 120 of 200
IIE Module Manual OPSC7311
Tip: If you don’t see the content of the LinearLayout after this, check that the
layout_gravity isn’t set for the LinearLayout. It should not be.
© The Independent Institute of Education (Pty) Ltd 2023 Page 121 of 200
IIE Module Manual OPSC7311
11. Open the MainActivity Kotlin class and change the code that creates the
binding as shown in Figure 180.
If you run the app now, you will see the toolbar but not yet the menu or the navigation
drawer. We still need to add a little code for that. If you see your layout and it works,
you can now safely delete the original layout file.
To add the code that will enable the Navigation Drawer to work:
If you run the app now, you will see that the navigation drawer can appear and be
hidden again.
© The Independent Institute of Education (Pty) Ltd 2023 Page 122 of 200
IIE Module Manual OPSC7311
The menu now appears. But if the back button is pressed, the menu is not closed as
you would expect. Instead, the app is exited. Let’s see how we can fix that.
© The Independent Institute of Education (Pty) Ltd 2023 Page 123 of 200
IIE Module Manual OPSC7311
The menu looks lovely now, but it does not do anything yet. Now the time has come
to handle the menu actions. We need to implement another listener for that.
The menu item doesn’t have anything to do yet – the photo activity will be created next.
© The Independent Institute of Education (Pty) Ltd 2023 Page 124 of 200
IIE Module Manual OPSC7311
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/nav_toolbar"
© The Independent Institute of Education (Pty) Ltd 2023 Page 125 of 200
IIE Module Manual OPSC7311
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Light"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header_layout"
app:menu="@menu/navigation_menu">
</com.google.android.material.navigation.NavigationView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="189dp"
android:layout_height="189dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/starsuckslogo">
</ImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:fontFamily="@font/hind_guntur_light"
android:textColor="@color/starsucksGreen"
android:textSize="20dp"
android:padding="5dp"
android:text="SMILE :-)">
</TextView>
<androidx.cardview.widget.CardView
android:layout_width="270dp"
android:layout_height="167dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp">
<ImageView
android:id="@+id/img_cameraImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/ic_launcher_round">
</ImageView>
</androidx.cardview.widget.CardView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/photoFab"
android:layout_marginTop="20dp"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:src="@drawable/ic_menu_photo"
© The Independent Institute of Education (Pty) Ltd 2023 Page 126 of 200
IIE Module Manual OPSC7311
app:backgroundTint="@color/starsucksRed">
</com.google.android.material.floatingactionbutton.FloatingActionButton>
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>
Now we can update the navigation code in the MainActivity to open our new activity:
We can now add the code to CoffeeSnapsActivity that takes a photo and displays
it using the ImageView.
There are two ways of taking a photo in Android: using an intent or making use of a
camera API such as CameraX. Since we are working with Intents right now, we will
stick to that for a start. But if you want more control, use the CameraX API instead.
(Ndonga, 2021)
Use View Binding to get hold of the components. Now we can add an
OnClickListener for the FloatingActionButton that will make use of an Intent to
take the photo.
Many examples that you will find online will make use of the method
startActivityForResult. But if you look closely at the code, you will notice that
Android Studio will warn that the method is deprecated. Read more about the new way
of calling an intent in (Sharma, 2021)
© The Independent Institute of Education (Pty) Ltd 2023 Page 127 of 200
IIE Module Manual OPSC7311
Note that there are some issues with Android 11 (API level 30 or later) with using this
method. If the user disabled the built-in camera, this would not work as expected. Read
more in (Murphy, 2020) So, let us change our implementation to use CameraX instead.
If we used a Camera API instead, we would need to request the CAMERA permission.
Let’s have a quick look at that.
© The Independent Institute of Education (Pty) Ltd 2023 Page 128 of 200
IIE Module Manual OPSC7311
Android has a built-in permission system that deals with Normal and Dangerous
permissions (there are other types of permissions which are beyond the scope of this
module manual). Normal permissions should not affect the user’s privacy and are
granted without requesting the user’s explicit permission. Dangerous permissions can
affect a user’s privacy and needs the user to allow the functionality the permission
protects before it can be used.
© The Independent Institute of Education (Pty) Ltd 2023 Page 129 of 200
IIE Module Manual OPSC7311
It is important to know which the dangerous permissions are, so you can ask the user
if you need to access those features. Android considers the permissions in Figure 192
as dangerous.
The first thing we need to do is add dependencies to the project. We are going to make
use of a library that is not included by default in an Android app. The latest versions of
the CameraX libraries are list in (Android Open Source Project, 2022f). We are going
to use the latest stable release, which is 1.1.0 at the time of writing of this manual. Note
that we are copying the dependencies from the Groovy tab.
Open the build.gradle file (the one for the Module, in our case StarSucks.app). The
first thing we need to check is the minimum API version. Find the property under
android > defcaultConfig > minSdkVersion and change it to 26 if it is less than that.
© The Independent Institute of Education (Pty) Ltd 2023 Page 130 of 200
IIE Module Manual OPSC7311
Add the dependencies shown in Figure 194. And then click Sync Now at the top of the
file so Gradle can download the necessary files.
The next thing we need to do, is to ask for permission to use the camera. Now we will
no longer be able to get away without that.
Under the manifests folder, open the AndroidManifest.xml file, and add the two lines
shown in Figure 196.
Now we are ready to implement the new camera features. First, remove all the intent
code that we added before. Then, we change the ImageView where we displayed the
photo we took before, with a PreviewView as shown in Figure 197.
Run the app at this point. When you go to the coffee snaps activity, you should see a
black square where the image was before.
© The Independent Institute of Education (Pty) Ltd 2023 Page 131 of 200
IIE Module Manual OPSC7311
Now we can add the code to start up the camera and display the preview of the image
on the activity. First, add two new properties:
Then add the below function to start the camera. Note that the example code from
(Ndonga, 2021) needs to be updated to reflect our names of our controls. So, carefully
include the function as shown here in Figure 199.
And finally, we can add the code to ask for camera permissions and start the camera
preview.
© The Independent Institute of Education (Pty) Ltd 2023 Page 132 of 200
IIE Module Manual OPSC7311
Now run the app again. You will see that you are prompted to allow the app to take
pictures when you open the coffee snaps activity. And if you allow it, the preview of the
camera’s view will be displayed. Go ahead, try it out!
We don’t have to leave the app to take the photo, which is very convenient. But what
we are currently seeing is just the preview. Let’s add code to take the photo and save
it to a file.
© The Independent Institute of Education (Pty) Ltd 2023 Page 133 of 200
IIE Module Manual OPSC7311
When we click the button, the location of the photo that was taken is logged. Not super
exciting. Let us add an ImageView where we can display the captured photo.
© The Independent Institute of Education (Pty) Ltd 2023 Page 134 of 200
IIE Module Manual OPSC7311
Now we can add a line of code to display the image that we already have the Uri for.
However, if we do this, the app unceremoniously crashes. If we look at the Run window
in Android Studio, we see this exception:
If you look closely at the code that we used to capture the photo, you will see that there
is an executor involved. That starts the capture process on a different thread. And with
Android, just like with most user interface frameworks, you cannot modify the user
interface from a different thread. The method runOnUiThread will work in this instance.
(TutorialKart, 2021)
And that is it. Now the photo will get displayed on the ImageView. Go ahead and try it
out!
© The Independent Institute of Education (Pty) Ltd 2023 Page 135 of 200
IIE Module Manual OPSC7311
1. Right-click the res folder, click New and then Image Asset.
© The Independent Institute of Education (Pty) Ltd 2023 Page 136 of 200
IIE Module Manual OPSC7311
Figure 212. Foreground configuration with the icon called local cafe
Tip: If your colour is correct when you run the app, but the icon is wrong, delete the
file highlighted in Figure 213 in the Project view. Then recreate follow the steps again
to create the launcher icon.
© The Independent Institute of Education (Pty) Ltd 2023 Page 137 of 200
IIE Module Manual OPSC7311
© The Independent Institute of Education (Pty) Ltd 2023 Page 138 of 200
IIE Module Manual OPSC7311
7 Activities
Do the activities that appear on Learn.
8 Revision Exercises
Create a small quiz application where the user is asked a series of questions about
famous landmarks (use an ImageView to display these) and they must correctly
identify them using EditTexts. Once the user has answered all the questions, they
should be taken to a second activity that displays their score
© The Independent Institute of Education (Pty) Ltd 2023 Page 139 of 200
IIE Module Manual OPSC7311
1 Introduction
In all the learning units so far, we have built apps that only store their data in memory.
And while that can be quite enough, depending on the app, we usually need long term
storage as well. In this learning unit we will explore writing data to a NoSQL database.
2 NoSQL Databases
2.1 Firebase
Firebase is a mobile application development platform owned by Google since 2014.
The platform has a range of products which are very useful for mobile application
development. You can find out more about the available products here:
https://firebase.google.com/. You will probably find that you end up using most of them.
There are two database products in Firebase: the Realtime Database and Cloud
Firestore. We will look at both options.
The Firebase Realtime Database is also a NoSQL database. That stores data in a
JSON format. We will look a bit deeper into that next.
© The Independent Institute of Education (Pty) Ltd 2023 Page 140 of 200
IIE Module Manual OPSC7311
NoSQL stands for Not only SQL and is a different approach to database design. You
would have used mostly Relational Database Management Systems (RDBMS) such
SQL Express and MySQL until now. You have probably normalised and related a
database and in turn cried a little. SQL relies on schemas and highly structured data.
NoSQL accommodates a wide variety of data models and have only been around since
the early 2000s. The introduction of cloud and mobile computing created scenario’s
where the need for scalability and processing speed greatly outweighed the need for
a structured carefully planned database. There are different types of NoSQL
databases, which is beyond the scope of this course – you can read more about them
here: https://searchdatamanagement.techtarget.com/definition/NoSQL-Not-Only-SQL
[Accessed 17 November 2022].
JSON is an acronym for Java Script Object Notation. It is a text based, human readable
data interchange format used to pass data between database and applications,
between different applications etc. You will learn a lot more about JSON when you
code up an application that uses a REST- API. An easy way to think about it is that
JSON gives a structure to save our data in that is understood by a wide variety of
technologies. This makes it very easy of us to send data in this format to other
applications. Web API’s send large sets of data to all sorts of clients in JSON format.
Let’s look at the example shown in Figure 215, from the OpenWeather API
documentation. We are going to copy and paste the sample JSON into a JSON
formatter to check if it is Valid JSON, but also to get a better understanding of what we
are seeing in Figure 215.
© The Independent Institute of Education (Pty) Ltd 2023 Page 141 of 200
IIE Module Manual OPSC7311
© The Independent Institute of Education (Pty) Ltd 2023 Page 142 of 200
IIE Module Manual OPSC7311
Let’s look at what we can learn from this. Collapse all the entries (click on the [-]) and
you should see the following data structure.
JSON Array
JSON Object
JSON Objects: A JSON Object is a collection of key:value pairs, objects can also hold
other objects and JSON Arrays. I have expanded the main JSON object below and
you can see it holds key value pairs for temperature, pressure, and humidity.
© The Independent Institute of Education (Pty) Ltd 2023 Page 143 of 200
IIE Module Manual OPSC7311
© The Independent Institute of Education (Pty) Ltd 2023 Page 144 of 200
IIE Module Manual OPSC7311
We can export the data from Firebase into a JSON file by click Export JSON.
We can then copy and paste the JSON in the downloaded .json file into a JSON
formatter. We will see the following:
Json Formatter
Firebase
You can learn more about JSON and the related syntax here:
https://medium.com/omarelgabrys-blog/json-in-a-nutshell-7d638dfea7cc [Accessed
17 November 2022].
Choosing between the Realtime Database and Cloud Firestore for a real app is quite
complex. There are lots of difference between the two, some quite subtle. But you will
© The Independent Institute of Education (Pty) Ltd 2023 Page 145 of 200
IIE Module Manual OPSC7311
Now that you have a better understanding of NoSQL and JSON and Firebase Realtime
and Cloud Firestore, lets add Firebase to our Android Project. We will start with the
Realtime Database.
Note: You will need a GMAIL account for this – create one if you don’t have one.
2. This will open the Firebase assistant panel to the right of your screen. Here you
will see all the available Firebase products.
3. Find the Realtime Database and click on the arrow to expand it.
© The Independent Institute of Education (Pty) Ltd 2023 Page 146 of 200
IIE Module Manual OPSC7311
4. Click the Get started with Realtime Database [KOTLIN] link. This will change the
panel to look like Figure 227.
© The Independent Institute of Education (Pty) Ltd 2023 Page 147 of 200
IIE Module Manual OPSC7311
You will see the following confirmation message appear in when you return to Android
Studio.
© The Independent Institute of Education (Pty) Ltd 2023 Page 148 of 200
IIE Module Manual OPSC7311
We now need to add the Firebase Realtime database dependencies to our app. These
are class libraries that contains all the built-in logic that we would need to work with
Firebase.
Gradle can throw some scary errors at this stage – but don’t worry, it is usually just
a version conflict. You can just Google for the correct version of Firebase to use with
your Max API and change the entry in Gradle. It should work fine 99% of the time.
Android Studio will ask you to confirm that you want to add the dependencies to the
project. It will also list the dependencies that will be added to both your build.gradle
and app/build.gradle files (project and app (module level)). Click Accept Changes to
continue.
© The Independent Institute of Education (Pty) Ltd 2023 Page 149 of 200
IIE Module Manual OPSC7311
You will see the following confirmation message if your dependencies were set up
without any errors.
You can however only breathe easily when you have a successful sync and Gradle
build.
We can now go and open our Gradle files to inspect the changes made to them.
Navigate to Gradle Scrips and click on build.gradle (Module:StarSucks.app) first.
You will notice that the following entry was added to the Gradle script file.
© The Independent Institute of Education (Pty) Ltd 2023 Page 150 of 200
IIE Module Manual OPSC7311
If you scroll down further, you will find that the dependency has also been added
This matches up perfectly with the dependencies asked for earlier (see Figure 230).
You will find the remaining entry in the build.gradle (Project: StarSucks) script file:
© The Independent Institute of Education (Pty) Ltd 2023 Page 151 of 200
IIE Module Manual OPSC7311
Good, our dependencies are ready to go. We can now configure our database rules.
The default security settings for the Realtime Database is to only allow read and writes
to authenticated members (using Firebase Authentication). We want to change that
while we test our app. Just remember to change it back once you are ready to deploy
your application. This is fine for testing, but a bad idea for the security of your app
once it enters the production environment.
Go back to the Firebase panel. You will find the Configure Firebase Database Rules
section there. Click on the link for configure your rules for public access.
You need to log into your Firebase console to set your database settings. You can
access the console here: https://console.firebase.google.com/u/0/ [Accessed 17
November 2022].
© The Independent Institute of Education (Pty) Ltd 2023 Page 152 of 200
IIE Module Manual OPSC7311
Your project will open, you can go ahead and click on Realtime Database in the
Project Overview panel to the left of the screen, under the Build category.
© The Independent Institute of Education (Pty) Ltd 2023 Page 153 of 200
IIE Module Manual OPSC7311
The first option that appears asks you to choose a location for the database. South
Africa is not available as an option, so choose europe-west1 as the next-best option
and click Next.
The security rules for Realtime Database window will appear. Click Start in test mode.
Click Enable.
This will change your read and write rules to true – you can now write to this database
without first authenticating.
Your database will be created and ready for use:
© The Independent Institute of Education (Pty) Ltd 2023 Page 154 of 200
IIE Module Manual OPSC7311
We are now ready to start adding the logic to our application so that we can write to
the Firebase Realtime Database from our application. Firebase provided a guided
tutorial in the Firebase panel within Android Studio. We will now follow that tutorial.
Let’s add the new floating action buttons shown in Figure 245 to our app. The images
smallcloud.png and date.png can be found in the assets folder for leaning unit 4 in the
repository.
© The Independent Institute of Education (Pty) Ltd 2023 Page 155 of 200
IIE Module Manual OPSC7311
Note that the months returned by the date picker are from 0 to 11. (Android Open
Source Project, 2022g) So, to get a month that makes sense to users, we add 1.
© The Independent Institute of Education (Pty) Ltd 2023 Page 156 of 200
IIE Module Manual OPSC7311
Now we add the OnClickListener to the fabCloud button to write the data to the
database.
© The Independent Institute of Education (Pty) Ltd 2023 Page 157 of 200
IIE Module Manual OPSC7311
Let’s try it out. We enter Mike Peters and his cell number. We next select the date and
click the cloud button. We should see the corresponding values in our Realtime
Database. So, let’s go look in the Firebase console.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/img_starsucksLogo"
android:layout_width="207dp"
android:layout_height="177dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/starsuckslogo"></ImageView>
© The Independent Institute of Education (Pty) Ltd 2023 Page 158 of 200
IIE Module Manual OPSC7311
<TextView
android:id="@+id/tv_lblOrderHistory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:fontFamily="@font/hind_guntur_light"
android:text="Your Order History"
android:textColor="@color/starsucksGreen"
android:textSize="20dp"></TextView>
<ListView
android:id="@+id/lstv_OrderHistory"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
</LinearLayout>
</LinearLayout>
We are now ready to add the logic to retrieve our data from the Realtime Database.
We need to add our DatabaseReference and FirebaseDatabase references here
too. Make sure to pass in the same path as the path you used when you pushed your
values up to Firebase - “orders” in our case.
We can now use our Database reference by adding a ValueEventListener to it. The
ValueEventListener will fire every time we add a value to the Firebase Realtime
Database, but it will also fire once after we add it. We will pull down a DataSnapshot
every time the listener fires. We will then ask the DataSnapshot to pull down all its
children.
© The Independent Institute of Education (Pty) Ltd 2023 Page 159 of 200
IIE Module Manual OPSC7311
And the last thing that we still need to do is to override the toString() method for
class Order.
• navigation_menu.xml
• MainActivity.onNavigationItemSelected
Then we can run the app and view the order history.
© The Independent Institute of Education (Pty) Ltd 2023 Page 160 of 200
IIE Module Manual OPSC7311
Our writing to and reading from the database is working using the Realtime Database.
Now, let us do the same using Cloud Firebase.
When connecting our app to Firebase, we choose Cloud Firestore this time. Follow
the same process to connect and add the dependencies.
In the Firebase console, under Build select Firestore Database, and click Create
database.
© The Independent Institute of Education (Pty) Ltd 2023 Page 161 of 200
IIE Module Manual OPSC7311
Start the database in test mode and select a European region. Now we are ready to
add the code to use Cloud Firestore.
And if we look in the console, we can spot our very first entry in the Cloud Firestore.
© The Independent Institute of Education (Pty) Ltd 2023 Page 162 of 200
IIE Module Manual OPSC7311
Read more about accessing data from Cloud Firestore in (Google, 2022b)
6 Activities
Do the activities that appear on Learn.
7 Revision Exercises
Create a similar application (to the example in this learning unit) that allows a user to
order from a different fast-food brand. Extend the app to have a login and registration
functionality.
© The Independent Institute of Education (Pty) Ltd 2023 Page 163 of 200
IIE Module Manual OPSC7311
1 Introduction
Now that we have created a fully functional app, it is time to do something different. In
this learning unit, we are going to create a game from scratch.
But there are more types of resources that we haven’t yet encountered. The two rows
highlighted in yellow in Figure 262 are the ones most familiar to us by now.
© The Independent Institute of Education (Pty) Ltd 2023 Page 164 of 200
IIE Module Manual OPSC7311
Why should we make use of resources? Let’s see what the Android Open Source
Project documentation says about it.
“You should always externalize app resources such as images and strings from your
code, so that you can maintain them independently. You should also provide
alternative resources for specific device configurations, by grouping them in
specially-named resource directories. At runtime, Android uses the appropriate
resource based on the current configuration. For example, you might want to
provide a different UI layout depending on the screen size or different strings
depending on the language setting.” (Android Open Source Project, 2020h)
2.2 Animation
In the Android world, there are several different ways to do animation. An overview of
all of these is shown in Figure 263. We are going to focus on using a canvas and
drawables.
© The Independent Institute of Education (Pty) Ltd 2023 Page 165 of 200
IIE Module Manual OPSC7311
© The Independent Institute of Education (Pty) Ltd 2023 Page 166 of 200
IIE Module Manual OPSC7311
You may get a red squiggly line because you need to import the class. Select the class
name and press Alt+Enter on your keyboard, then select Import.
The next error message will inform us that we cannot extend this class to the View
class if we do not create a constructor that matches the super class.
Click the red lightbulb, and choose to add the constructor parameters that take just a
context.
You can go ahead and inspect the View class (Ctrl+click on the word View in the
class definition). You will see that this class has all the methods we need to draw UI
elements or to animate them.
© The Independent Institute of Education (Pty) Ltd 2023 Page 167 of 200
IIE Module Manual OPSC7311
Any Android device screen is divided into a grid with an X (horizontal) and Y (vertical)
axes. The grid lines are 1 pixel apart (this is very small). In Figure 270, the blue
rectangle is drawn at 3 pixels on the x axis (toward the right) and 2 pixels on the y axis
(downwards).
We need to tell Android exactly where to draw our images, we do this with onDraw()
method. There are also built-in methods that we can use to work with coordinates.
You will need two bitmap images to draw and animate the bird in our game. One bitmap
with the bird’s wings up and one bitmap with the bird’s wings down. We are going to
start by drawing our bird with its wings up at the 0,0 position on the screen. We need
to override the onDraw() method for this. You can do this by staring to type onDraw
below your constructor in the BirdieGameView class. You will get a popup that allows
you to override the method.
© The Independent Institute of Education (Pty) Ltd 2023 Page 168 of 200
IIE Module Manual OPSC7311
We next need to get access to our bird image from the res folder. We do this by
declaring our bitmap and then by using the BitmapFactory to decode our resource
and give us access to the images in the drawable folder through R class.
You will notice that this method accepts a canvas as an argument. We will use this
canvas to draw our bitmap to the canvas.
The Canvas.drawBitmap() method has many overloads, some of these are not
nullable – this means that we must provide that particular argument, regardless of
which overload we are using. There are also some arguments marked as nullable (?
in Kotlin). This means that we can pass in null instead of an actual value. We will be
making use of the overload highlighted below. We need to provide: a bitmap image,
the x and y coordinates and we can pass in null as an argument for paint – since we
are not filling our bitmap with a colour.
We complete the method as indicated below, we pass in our bird bitmap – we pass in
0 for the x value and 0 for the y value (the hints in the method will say left (x) and top
(y) . We finally pass in null for the paint colour.
© The Independent Institute of Education (Pty) Ltd 2023 Page 169 of 200
IIE Module Manual OPSC7311
All that is left to do, is to inform our MainActivity Kotlin class that we are not going
to be using the activity_main.xml layout file since we are creating our own. We start
this process by creating an instance of our BirdieGameView class.
We instantiate the birdieGameView object in the onCreate method (see Figure 277).
We need to pass a Context in our constructor since we overloaded the constructor to
ask for this in the BirdieGameView class. We can pass in this as we want to apply our
changes to the Main Activity. We finally replace the layout file in the setContentView
method with our birdieGameView object.
You can now safely delete the activity_main.xml layout file that we are no longer
using.
© The Independent Institute of Education (Pty) Ltd 2023 Page 170 of 200
IIE Module Manual OPSC7311
The ActionBar on this app looks a bit out of place, open the themes.xml file and set
the entire app to NoActionBar.
© The Independent Institute of Education (Pty) Ltd 2023 Page 171 of 200
IIE Module Manual OPSC7311
We start by declaring the bitmaps and Paint objects that we will need. Paint objects
can create Text or simple shapes such as circles, rectangles, and squares – we can
also assign these shapes a colour. We will be using Paint to provide our score and
level counters, and the text needed to display them properly. We will also declare a
bitmap array that will hold our two values for lives (either alive or dead).
We then set up our Paint objects. We start by setting the colour we would like to use,
we then set the text size, typeface and anti-alias.
© The Independent Institute of Education (Pty) Ltd 2023 Page 172 of 200
IIE Module Manual OPSC7311
Tip: You need to be careful of the order in which you draw bitmaps onto the canvas.
The bitmaps are drawn in the order that they are coded. The background file we are
using fills the entire screen. You need to draw that first and then draw the other
bitmaps on top of it. Your bitmaps will be stuck behind it if you do not follow this rule.
We first draw our background and then we draw our bird on top of the background.
You might get the following error if the background bitmap that you are trying to draw
is too big for android studio and any device to handle – you can resize the image if this
is the case. This takes some trial and error, but you will get there in the end.
You should see the below screen if we managed to draw the background with the bird
op top of it.
© The Independent Institute of Education (Pty) Ltd 2023 Page 173 of 200
IIE Module Manual OPSC7311
We would like to display the lives remaining, score and level at the top of the screen.
We are going to hard code the X and Y values for now – we will change that later so
that we can manage our images better. Canvas.drawText() method expects a String
value that contains the text that we would like to display as well as the x and y
coordinates. You will note that the Paint object is required in this case – that is because
we need to pass in the colour, textsize and fontFaceType that we set up earlier.
We provide the String values, x and y coordinates and our paint objects here.
We want the Level 1 text to appear in the middle of the screen. We do not currently
know the ending x value of the screen. Luckily, we can make use of the canvas.width
property. This will return and int value that contains the ending x value. We then divide
that by 2 to find the middle of the screen.
© The Independent Institute of Education (Pty) Ltd 2023 Page 174 of 200
IIE Module Manual OPSC7311
We finally need to draw our bitmaps. We draw our lives on the screen by providing the
following x and y coordinates.
© The Independent Institute of Education (Pty) Ltd 2023 Page 175 of 200
IIE Module Manual OPSC7311
1. We must set a flag that tells if the bird is touched so that we can animate the bird
flapping its wings by drawing either the Bitmap with its wings up or down.
2. We need to set bounds on our screen in the form of a MinY (top of screen) and
MaxY (bottom of screen) values. Our bird will drop off the bottom or fly of the top
of our screen if we do not do this.
3. We simulate the bird flying by redrawing the bird at different Y values. We do this
by changing the birdY value by 10 pixels every time the onDraw method is
called. This is done every 30 milliseconds with a Timer Event.
We start by setting initial birdX and birdY values, we also set the value by which we
would like to alter the Y coordinates of the bird in a variable called birdSpeed. We start
off by stating that the bird will not move because it was not clicked. We do this by
setting a Boolean touch flag to false. We finally create a Bitmap array that will hold the
two images that simulate our bird flying by drawing a bitmap image of the bird with its
wings up and then down every time we click on the bird.
We next start preparing the bounds of the screen to ensure that our bird does not fly
off the screen. We need the screen’s overall coordinates to do this.
© The Independent Institute of Education (Pty) Ltd 2023 Page 176 of 200
IIE Module Manual OPSC7311
We set the minBirdY (as high as the bird can go on the screen) value to one bird’s
height from position 0.0. We finally set the the maxBirdY value to three bird heights
above the very bottom of the screen. We do this by getting the height of the screen
and then subtracting the height of the bird *3 from the canvas Height. We finally set
our birdY to increase with our birdSpeed variable every time the onDraw method is
called.
Now that we have the bitmaps and the bounds of our screen ready, we can go ahead
and draw our bird. We start by checking if the bird has been clicked. If the bird has not
been clicked, we draw the bird with its wings up at the initial X and Y values that we
have set. We set the touch field back to false after we have drawn the bird. We draw
the bird with its wings down in the else clause.
© The Independent Institute of Education (Pty) Ltd 2023 Page 177 of 200
IIE Module Manual OPSC7311
We now need to code up our onTouchEvent. We can override the onTouchEvent. The
onTouchEvent accepts and event as an argument. We use this event to determine if
the bird has been clicked (event.action == MotionEvent.Action_Down). We set
the touch flag to true and we change the birdSpeed to -20, this means that our bird
will move up the screen every time we click it.
Our bird should drop all the way down to the MaxY value when the game starts. That is
because we increase the value of birdY by 10 pixels every time we call the onDraw
method.
We still have not added the logic that will call our onDraw method every 30 milliseconds.
We will do this now. This is done in the MainActivity.java class.
There are different ways to call a piece of code after a delay in Kotlin. We are going to
make use of an Executor. Read more in (Baeldung, 2022)
© The Independent Institute of Education (Pty) Ltd 2023 Page 178 of 200
IIE Module Manual OPSC7311
© The Independent Institute of Education (Pty) Ltd 2023 Page 179 of 200
IIE Module Manual OPSC7311
We begin by declaring the X and Y properties that we will need for Pugicorn as well as
his speed:
We first check if Pugicorn has moved off the left side of the screen, if he did, we redraw
him 20 pixels off the screen (to the right) on the x axis. We use quite a complicated line
of code to provide the pugiY axis. We start by converting whatever the line of code
returns to int value, we then use Math.floor to round whatever value we receive up to
the highest number. We pass Math.random to the Math.floor method. We use
Math.random to generate any random Y value, BUT this value must be within the
bounds we set for the bird, these are MinY and MaxY.
We need to determine if our bird and Pugicorn collided to increase our score by 10
points. We create a Boolean collisionCheck() method for this. This method accepts
an int x and y value. We then check if our bird’s X value is smaller than x and if x is
smaller than current X value of our bird + the bird bitmap’s width. We do the same for
the bird’s Y values, except we use bird.height to get the height of the bird. This
basically gives us the outline of our bird. If x is smaller than the outline – a collision as
taken place as we will pass Pugicorn’s x and y values in as arguments.
© The Independent Institute of Education (Pty) Ltd 2023 Page 180 of 200
IIE Module Manual OPSC7311
We call the collisionCheck() method in the onDraw method. You will notice that we
do in fact pass Pugicorn’s X and Y values into this method. We increase our score,
pop a Toast message and reset Pugicorn’s X value to -100 (off the screen) if a collision
did occur.
Create a property to store the score and change the display to make use of that
property.
© The Independent Institute of Education (Pty) Ltd 2023 Page 181 of 200
IIE Module Manual OPSC7311
Pugicorn now
appear at
random Y values
Our Toast
message appears,
and our score is
increased when a
collision occurs
The BirdieGameView class now contains quite a bit of logic, here is the completed
class so far:
package za.ac.iie.opsc7311.birdiegame
import android.content.Context
import android.graphics.*
import android.view.MotionEvent
import android.view.View
import android.widget.Toast
// bitmaps
private var bird : Bitmap = BitmapFactory.decodeResource(resources, R.drawable.wingsup)
private var birdDown : Bitmap = BitmapFactory.decodeResource(resources, R.drawable.wingsdown)
private var greengrassbackground : Bitmap = BitmapFactory.decodeResource(resources,
R.drawable.villagescreensize)
private var pugicorn : Bitmap = BitmapFactory.decodeResource(resources, R.drawable.puggicorn)
private var cuppicake : Bitmap = BitmapFactory.decodeResource(resources, R.drawable.cuppicake)
private var lifealive : Bitmap = BitmapFactory.decodeResource(resources, R.drawable.smallalive)
private var lifedead : Bitmap = BitmapFactory.decodeResource(resources, R.drawable.smalldead)
// paint
private var scoreCounter = Paint()
private var levelCounter = Paint()
// screen size
© The Independent Institute of Education (Pty) Ltd 2023 Page 182 of 200
IIE Module Manual OPSC7311
// pugicorn state
private var pugiX = -1f
private var pugiY = 0f
private var pugiSpeed = 15
// player state
private var score = 0
init {
scoreCounter.color = Color.BLACK
scoreCounter.textSize = 30f
scoreCounter.typeface = Typeface.DEFAULT_BOLD
scoreCounter.isAntiAlias = true
levelCounter.color = Color.BLUE
levelCounter.textSize = 30f
levelCounter.typeface = Typeface.DEFAULT_BOLD
levelCounter.textAlign = Paint.Align.CENTER
levelCounter.isAntiAlias = true
}
// calculate the minimum Y value for the bird - one size below the top of the screen
var minBirdY = bird.height
// calculate the maximum Y value for the bird - one size above the bottom of the screen
var maxBirdY = canvasHeight - bird.height
© The Independent Institute of Education (Pty) Ltd 2023 Page 183 of 200
IIE Module Manual OPSC7311
Let’s start by declaring the variables that we will need for Rainbowcuppicake.
© The Independent Institute of Education (Pty) Ltd 2023 Page 184 of 200
IIE Module Manual OPSC7311
We change the value of your X axis so that our cuppicake can move across the screen,
the same as we did for Pugicorn.
We next check if our cupcakes X axes is less than 0, which means that that our
cuppicake has veered off the screen on the left. We then redraw the cuppicake by
setting the X value to +200 so that it will be redrawn off the right side of the screen.
We once again set a Random Y value that is within the bounds we set earlier.
© The Independent Institute of Education (Pty) Ltd 2023 Page 185 of 200
IIE Module Manual OPSC7311
We next need to check for a collision and decrease our life count if a collision has
occurred. We start by setting declaring our lifecount variable under our class definition
and setting the variable within our constructor.
We also want our unicorn life icons to change when we lose a life. We do this by
implementing a for loop.
You can now run your app – your unicorn should turn into a ghost every time the bird
is hit and a game over toast should pop up when we have run out of lives.
© The Independent Institute of Education (Pty) Ltd 2023 Page 186 of 200
IIE Module Manual OPSC7311
We finally want to handle the Game Over event a bit better. We are going to draw the
words GAME OVER, and stop all the animations from happening.
© The Independent Institute of Education (Pty) Ltd 2023 Page 187 of 200
IIE Module Manual OPSC7311
© The Independent Institute of Education (Pty) Ltd 2023 Page 188 of 200
IIE Module Manual OPSC7311
Also have a look at the videos on the clientuser.net channel on YouTube, available
at https://www.youtube.com/channel/ UCWTzjwD6ps1GELhvubxLb2Q [Accessed 17
November 2022].
5 Activities
Do the activities that appear on Learn.
6 Revision Exercises
Add a second level to the game. The game needs to enter Level 2 when the player
reaches 100 points. Level two should have a different background, a bat that
immediately kills your bird as well as a Taco that is worth 50 points. In fact, add as
many levels as you like and push the final score up to Firebase.
© The Independent Institute of Education (Pty) Ltd 2023 Page 189 of 200
IIE Module Manual OPSC7311
Bibliography
Abu Experience, 2017. 10 Mobile UX Design Principles You Should Know. [Online]
Available at: http://uxbert.com/10-mobile-ux-design-principles/ [Accessed 17
November 2022].
Agrawal, S., n.d.. Property, Getter and Setter : Kotlin. [Online] Available at:
https://agrawalsuneet.github.io/blogs/property-getter-and-setter-kotlin/ [Accessed 17
November 2022].
Android Open Source Project, 2019. Run your app. [Online] Available at:
https://developer.android.com/training/basics/firstapp/running-app [Accessed 17
November 2022].
Android Open Source Project, 2020c. Run apps on the Android Emulator. [Online]
Available at: https://developer.android.com/studio/run/emulator [Accessed 17
November 2022].
Android Open Source Project, 2020d. Android Runtime (ART) and Dalvik. [Online]
Available at: https://source.android.com/devices/tech/dalvik [Accessed 17 November
2022].
Android Open Source Project, 2020f. Build a UI with Layout Editor. [Online] Available
at: https://developer.android.com/studio/write/layout-editor [Accessed 17 November
2022].
Android Open Source Project, 2020h. App resources overview. [Online] Available at:
https://developer.android.com/guide/topics/resources/providing-resources [Accessed
17 November 2022].
© The Independent Institute of Education (Pty) Ltd 2023 Page 190 of 200
IIE Module Manual OPSC7311
Android Open Source Project, 2022. Android 13 Beta. [Online] Available at:
https://developer.android.com/about/versions/13 [Accessed 17 November 2022].
Android Open Source Project, 2022b. Meet Android Studio. [Online] Available at:
https://developer.android.com/studio/intro [Accessed 17 November 2022].
Android Open Source Project, 2022c. Run apps on a hardware device. [Online]
Available at: https://developer.android.com/studio/run/device [Accessed 17 November
2022].
Android Open Source Project, 2022d. About Android App Bundles. [Online] Available
at: https://developer.android.com/guide/app-bundle [Accessed 17 November 2022].
Ayub, N., 2017. Android Linear Layout Example. [Online] Available at:
https://javatutorial.net/android-linear-layout-example [Accessed 17 November 2022].
Ayub, N., 2017b. Android Relative Layout Example. [Online] Available at:
https://javatutorial.net/android-relative-layout-example [Accessed 17 November 2022].
Baeldung, 2022. Calling a Kotlin Function After a Delay. [Online] Available at:
https://www.baeldung.com/kotlin/call-function-after-delay [Accessed 17 November
2022].
Bhatnagar, M., 2018. Magic lies here - Statically vs Dynamically Typed Languages.
[Online] Available at: https://medium.com/android-news/magic-lies-here-statically-
typed-vs-dynamically-typed-languages-d151c7f95e2b [Accessed 17 November 2022].
© The Independent Institute of Education (Pty) Ltd 2023 Page 191 of 200
IIE Module Manual OPSC7311
Ernst, M., 2018. Version control concepts and best practices. [Online] Available at:
https://homes.cs.washington.edu/~mernst/advice/version-control.html [Accessed 17
November 2022].
Foundation, K., 2022c. Generics: in, out, where. [Online] Available at:
https://kotlinlang.org/docs/generics.html [Accessed 17 November 2022].
G., N., 2022. Android: Market Share & Other Stats for 2022. [Online] Available at:
https://techjury.net/blog/android-market-share/ [Accessed 17 November 2022].
Google, 2022b. Get data with Cloud Firestore. [Online] Available at:
https://firebase.google.com/docs/firestore/query-data/get-data [Accessed 17
November 2022].
Heller, M., 2022. What is Kotlin? The Java alternative explained. [Online] Available at:
https://www.infoworld.com/article/3224868/what-is-kotlin-the-java-alternative-
explained.html [Accessed 17 November 2022].
© The Independent Institute of Education (Pty) Ltd 2023 Page 192 of 200
IIE Module Manual OPSC7311
Lake, I., 2016. Layouts, Attributes, and you. [Online] Available at:
https://medium.com/androiddevelopers/layouts-attributes-and-you-9e5a4b4fe32c
[Accessed 17 November 2022].
Leiva, A., 2020. View Binding: The Definitive way to access views on Android. [Online]
Available at: https://antonioleiva.com/view-binding-android/ [Accessed 17 November
2022].
Ndonga, R., 2021. How to Implement CameraX API in Android Using Kotlin. [Online]
Available at: https://www.section.io/engineering-education/how-to-implement-
camerax-api-in-android/ [Accessed 17 November 2022].
© The Independent Institute of Education (Pty) Ltd 2023 Page 193 of 200
IIE Module Manual OPSC7311
Raphael, J., 2020. Android versions: A living history from 1.0 to 11. [Online] Available
at: https://www.computerworld.com/article/3235946/android-versions-a-living-history-
from-1-0-to-today.html [Accessed 17 November 2022].
Rout, A. R., 2022. Different Types of Activities in Android Studio. [Online] Available at:
https://www.geeksforgeeks.org/different-types-of-activities-in-android-studio/
[Accessed 17 November 2022].
sahilkhoslaa, 2018. Java | How to create your own Helper Class?. [Online] Available
at: https://auth.geeksforgeeks.org/user/sahilkhoslaa/articles [Accessed 17 November
2022].
Sinhal, A., 2017. Closer Look At Android Runtime: DVM vs ART. [Online] Available at:
https://android.jlelse.eu/closer-look-at-android-runtime-dvm-vs-art-1dc5240c3924
[Accessed 17 November 2022].
Sinicki, A., 2019. How to install the Android SDK. [Online] Available at:
https://www.androidauthority.com/how-to-install-android-sdk-software-development-
kit-21137/ [Accessed 17 November 2022].
TFPP Writer, 2018. 5 Examples Of Successful Rebranding That Will Blow Your Mind.
[Online] Available at: https://thefederalistpapers.org/us/5-examples-successful-
rebranding-will-blow-mind [Accessed 17 November 2022].
TutorialKart, 2021. Only the original thread that created a view hierarchy can touch its
views. [Online] Available at: https://www.tutorialkart.com/kotlin-android/original-
thread-created-view-hierarchy-can-touch-views/ [Accessed 17 November 2022].
© The Independent Institute of Education (Pty) Ltd 2023 Page 194 of 200
IIE Module Manual OPSC7311
Wagner, B., Lieben, G., Warren, G. E. & Dykstra, T., 2022. Properties (C#
Programming Guide). [Online] Available at: https://learn.microsoft.com/en-
us/dotnet/csharp/programming-guide/classes-and-structs/properties [Accessed 18
October 2022].
© The Independent Institute of Education (Pty) Ltd 2023 Page 195 of 200
IIE Module Manual OPSC7311
Intellectual Property
Plagiarism occurs in a variety of forms. Ultimately though, it refers to the use of the
words, ideas or images of another person without acknowledging the source using the
required conventions. The IIE publishes a Quick Reference Guide that provides more
detailed guidance, but a brief description of plagiarism and referencing is included
below for your reference. It is vital that you are familiar with this information and the
Intellectual Integrity Policy before attempting any assignments.
‘Plagiarism’ is the act of taking someone’s words or ideas and presenting them as your
own.
What is ‘Referencing’?
‘Referencing’ is the act of citing or giving credit to the authors of any work that you
have referred to or consulted. A ‘reference’ then refers to a citation (a credit) or the
actual information from a publication that is referred to.
Referencing is the acknowledgment of any work that is not your own, but is used by
you in an academic document. It is simply a way of giving credit to and acknowledging
the ideas and words of others.
When writing assignments, students are required to acknowledge the work, words or
ideas of others through the technique of referencing. Referencing occurs in the text at
the place where the work of others is being cited, and at the end of the document, in
the bibliography.
The bibliography is a list of all the work (published and unpublished) that a writer has
read in the course of preparing a piece of writing. This includes items that are not
directly cited in the work.
• Quote directly: when you use the exact words as they appear in the source;
• Copy directly: when you copy data, figures, tables, images, music, videos or
frameworks;
• Summarise: when you write a short account of what is in the source;
• Paraphrase: when you state the work, words and ideas of someone else in your
own words.
© The Independent Institute of Education (Pty) Ltd 2023 Page 196 of 200
IIE Module Manual OPSC7311
It is standard practice in the academic world to recognise and respect the ownership
of ideas, known as intellectual property, through good referencing techniques.
However, there are other reasons why referencing is useful.
Sources
• Books,
• Chapters from books,
• Encyclopaedias,
• Articles,
• Journals,
• Magazines,
• Periodicals,
• Newspaper articles,
• Items from the Internet (images, videos, etc.),
• Pictures,
• Unpublished notes, articles, papers, books, manuscripts, dissertations, theses,
etc.,
• Diagrams,
• Videos,
• Films,
• Music,
• Works of fiction (novels, short stories or poetry).
What You Need to Document from the Hard Copy Source You
are Using
(Not every detail will be applicable in every case. However, the following lists provide
a guide to what information is needed.)
© The Independent Institute of Education (Pty) Ltd 2023 Page 197 of 200
IIE Module Manual OPSC7311
Referencing Systems
There are a number of referencing systems in use and each has its own consistent
rules. While these may differ from system-to-system, the referencing system followed
needs to be used consistently, throughout the text. Different referencing systems
cannot be mixed in the same piece of work!
© The Independent Institute of Education (Pty) Ltd 2023 Page 198 of 200
IIE Module Manual OPSC7311
Usually, all of the above examples would not be referenced. The equation 𝐸 = 𝑚𝑐 2
is Einstein’s famous equation for calculations of total energy and has become so
familiar that it is not referenced to Einstein.
Sometimes what we think is ‘common knowledge’, is not. For example, the above
statement about the sky being blue is only partly true. The light from the sun looks
white, but it is actually made up of all the colours of the rainbow. Sunlight reaches the
Earth's atmosphere and is scattered in all directions by all the gases and particles in
the air. The smallest particles are by coincidence the same length as the wavelength
of blue light. Blue is scattered more than the other colours because it travels as shorter,
smaller waves. It is not entirely accurate then to claim that the sky is blue. It is thus
generally safer to always check your facts and try to find a reputable source for your
claim.
If you fail to acknowledge the work or ideas of others or do so inadequately this will be
handled in terms of the Intellectual Integrity Policy (available in the library) and/ or the
Student Code of Conduct – depending on whether or not plagiarism and/ or cheating
(passing off the work of other people as your own by copying the work of other students
or copying off the Internet or from another source) is suspected.
Your campus offers individual and group training on referencing conventions – please
speak to your librarian or ADC/ Campus Co-Navigator in this regard.
© The Independent Institute of Education (Pty) Ltd 2023 Page 199 of 200
IIE Module Manual OPSC7311
Please ask for assistance prior to submitting work if you are at all unsure.
© The Independent Institute of Education (Pty) Ltd 2023 Page 200 of 200