162
Zenva Academy – Online courses on game, web and mobile app development ©2017 Zenva Pty Ltd all rights reserved Page 1 Android App Development for Human Beings Mohit Deshpande

Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

  • Upload
    others

  • View
    9

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 1

Android App

Development for

Human Beings

Mohit Deshpande

Page 2: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 2

Table of Contents

Hola World – First Steps with Android ................................................................................................3

Basic UI Widgets – TextViews, EditTexts, and Buttons ....................................................................... 12

Creating a Unit Converter App – Part 1 ............................................................................................. 18

Creating a Unit Converter App – Part 2 ............................................................................................. 27

How to Create Simple Lists using ListViews ....................................................................................... 36

How to Create Lists using RecyclerView ............................................................................................ 52

Introduction to SQLite Databases on Android Devices ....................................................................... 63

How to Create Toolbars and Menus in Android ................................................................................. 71

How to Use Contextual Toolbar and ActionBar in Android ................................................................. 87

How to get the User Location in Android Tutorial .............................................................................. 95

Beginners Guide to Material Design ................................................................................................ 102

How to Use Loaders in Android ...................................................................................................... 108

How to Accessing the Camera and Take Pictures on Android ........................................................... 114

How to Use Android Sensors in Games ........................................................................................... 121

How to Use the Android Notification System .................................................................................. 129

How to Pass Data between Activities using Intents ......................................................................... 136

Android Networking Tutorial with AsyncTask ................................................................................. 156

Page 3: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 3

Hola World – First Steps with Android Hello World! In this post we’re going to create our very first Android application! We’re going to

download Android Studio and other prerequisites. Then we’re going to create a new Android Studio

project and write a little app such that the user can type in his or her name, press a button, and the app

will display “Hello ” and the name of the user in the middle of the screen.

Prerequisites Before we start, we’re going to need to install some software that will allow us to develop Android apps.

First, go to this link and download and install Android Studio. With that installation, we have everything

we need to write Android apps! To verify, open up Android Studio and click Configure → SDK Manager.

In the dialog that pops up, on the bottom left, click Show Package Contents, and, under Android

6.0, you’ll want to make sure the following things are checked:

Android 6.0 Platform

Intel x86 Atom_64 System Image

Under the SDK Tools tab, Intel x86 Emulator Accelerator (HAXM installer). Follow this guide to

install HAXM to boost emulator performance. (For Windows, replace <sdk> with

C:\Users\<username>\AppData\Local\Android\sdk. For Mac, replace <sdk>

with /Users/<username>/Library/Android/sdk where <username> is your login name.

Creating a New Project Now that we have everything we need for Android Studio, we’re going to create our very first Android

app! Opening Android Studio, click “Start a new Android Studio project” and type in something like

MyFirstAndroidApp for the project name. We can type in anything we want for the company domain,

but we can use lastname.com where lastname is your last name (i.e. deshpande.com). This company

domain is just used to uniquely identify your app in the Google Play Store. The project location can just

be any path in your filesystem where you want to store the project.

After clicking next, change the minimum SDK to Android 6.0 Marshmallow. Choose Empty Activity and

we’ll just hit next past the following screen since we’re ok with just a single MainActivity.

Then click Finish and Android Studio should create our project!

Page 4: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 4

Creating an Android Virtual Device Now that we’ve created our project, we want to run it on the emulator so we can see it on our

computer. The Android emulator is essentially a barebones version of the Android operating system

running in a window on your computer. If we had an Android phone running Android 6.0, we could

configure it to enable USB debugging and run it directly on the device. However, this post won’t assume

you have one so we’re going to use the emulator instead.

On the top toolbar, find the app icon that corresponds to the AVD Manager (looks like a phone with an

Android peeking up from the bottom) and a dialog should pop up with a button: Create Virtual Device.

Afterwards, we can choose any device to emulate, such as the Nexus 5X or Galaxy Nexus or Nexus 6P.

We can even customize our device’s screen size and density, but we’ll go with the Nexus 5X for now.

Feel free to choose whatever device you’d like! On the next page, we need to select the Intel x86

Atom_64 System Image. After naming the device anything we want, we can click Finish. After some

time, we should have a new virtual device we can run our apps on! We can click the green arrow in the

dialog and Android Studio will launch the device. Note that it will take some time for Android Studio to

launch the emulator!

Page 5: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 5

If the emulator is too large, we can always decrease the size of it by clicking the pencil icon in the AVD

dialog and changing the size, as well as any other specs we want to change, like screen resolution. We

can then exit out of the AVD window and then click the green Run icon on the top toolbar of

Android Studio to compile our app to run on an emulator or other connected device. When the “Choose

Page 6: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 6

A Device” dialog box pops up, then select the emulator and click OK. In a few seconds, our app should be

running on the emulator!

Page 7: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 7

Personalized Hello World Now that we’ve created a very simple Hello World app, we can start to make it a bit more complex by

adding UI elements. Let’s open up the activity_main.xml file in the Project view under app → res →

layout. If you don’t see the Project view, there’s a small tab on the left titled Project, or you can

press Ctrl + 1 or Cmd + 1. In the design view that comes up, we can click on the text (called a

TextView ) and delete it. Then, on the palette on the left, we can drag-and-drop an Person Name

EditText to the top left of the screen under the ToolBar that says “MyFirstAndroidApp.” When

dragging it to that position, make sure the semi-transparent overlay says alignParentLeft and

alignParentTop before you drop it in the view. Drag the right handle until the

EditText reaches the far right of the screen and the overlay says alignParentRight.

These overlays help to anchor our view to it’s parent’s view, the screen in this case. To summarize,

alignParentLeft will align the current view’s left side flush with its parent’s left side. This works

similarly for the other properties.

Similarly, drag out a Button and position in below the EditText and centered on the screen

(overlay should say centerHorizontal and below=editText ). We can change the text of

the button to “Submit” by double-clicking on the Button and changing the text in the popup. Finally,

we can drag-and-drop a Large Text TextView to the dead center of the screen (popup should say

centerHorizontal and centerVertical ). To get rid of the text in the TextView , we

can double-click the TextView and clear it out.

Page 8: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 8

Wire Up the Connections Now that we have these UI elements, we actually want to do something with them. We want our user to

enter their name, click the button, and the name will appear in the center of the screen. From this, it

seems like all of our work will be done when the button is clicked. We need to wire our Button so

that when it’s clicked, we want to execute code that extracts the text from the EditText and puts it

in the TextView . Let’s go back to our layout file and click on the Button. In our MainActivity.java

(located in app → java → com.lastname.myfirstandroidapp), after onCreate(Bundle

savedInstanceState) , add the following method definition:

public void buttonClicked(View button) {

}

1

2

3

public void buttonClicked(View button) {

}

Page 9: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 9

When typing it in, you’ll notice that Android Studio will help by providing autocomplete suggestions. You

should press enter when you find the one you need so that Android Studio can automatically add import

statements (like pressing enter when typing View ). Now we can go back to our layout file and click on

the Button. In the properties pane on the bottom right, find the onClick property and click in the box.

A dropdown should be available and have our method signature in there. We can select our method

signature, and that’s all it takes to wire our button to call the code in our buttonClicked method

when the button is pressed.

Coding the Button Click Now we can go back to the method in our source code and fill it in with the following lines:

1

2

3

4

EditText editText = (EditText) findViewById(R.id.editText);

TextView textView = (TextView) findViewById(R.id.textView);

String name = editText.getText().toString();

textView.setText("Hello " + name + "!");

The first line retrieves a reference to the EditText we created. The call to

findViewById(int) takes an integer key. There is a class that Android Studio manages and

creates simply called R (stands for resources) and allows us to access all of the XML data like layouts, UI

elements, and images that are in the res (also stands for resources) folder. This is the mechanism that

Android Studio uses to access XML elements in Java. In our case, we didn’t change the ids of the

EditText and TextView so they are editText and textView by default, and, since

they’re ids, they’re in the id inner class of R . It should be noted to NEVER modify this class! It’s auto-

generated and managed by Android Studio’s unique id references so any changes will break all of our

references!

The findViewById(int) method returns an object of class View and we can typecast it to what

we want it to be. It’s helpful to give useful ids to our UI elements so that we can be sure what subclass

of View it is, whether it’s an EditText , TextView , Button , or other UI elements. Similarly,

the second line of the code snippet grabs a reference to our TextView .

In the third line, we grab the text out of the EditText using it’s getText() method. However,

the getText() method returns a CharSequence , which is an interface. We can convert this to a

String (which actually implements CharSequence ) by calling toString() on that variable.

Finally, we can set the text of the TextView to be “Hello ” plus the name plus an exclamation point

using the setText(CharSequence) method. This is all it takes to create our app! Now we can

run our app using the same green run icon and view the results!

Page 10: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 10

Bonus: You might notice that when clicking on the EditText, we have to manually clear it out first. A

way to prevent this is to clear it like we did for the TextView , and changing the hint property of the

EditText to say something like “Enter your name” for example. The hint property shows up as a

transparent overlay on top of the EditText that disappears when you click on the EditText .

Conclusion In this post, we created our very first Android app! We first started by installing Android Studio and

the necessary tools we needed to code our Android app. Then we created a virtual device so that we

could run our application on it. After creating a blank Android Studio project, we first ran it on the

Page 12: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 12

Basic UI Widgets – TextViews, EditTexts, and Buttons Hello World! In this post, we’re going to be going in-depth into several of the most common UI elements

that we’ll encounter in Android: TextViews, EditTexts, and Buttons. We’ll be looking into their properties

and some of Java’s language features like anonymous inner classes.

TextView The simplest way to show the user text is through the TextView element. Since this is the simplest

element, we’ll also be covering some topics that are common to all Views.

Using a TextView is a really simple thing to do. All it requires is a height and width (required by all UI

elements) and some text to go inside. The TextView also allows for all sorts of formatting for text as

well. In XML, this is what a simple hello world TextView would look like.

1

2

3

4

5

<TextView

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:text="Hello World!"

/>

As a side note, the android: prefix corresponds to the Android XML namespace, where Android will

look for of our XML properties. layout_width and layout_height are required for all views

and view containers and can only have two possible values: wrap_content and match_parent.

Using the former means to make the View as big as the content of that View, whether it be a Button or

EditText. However, the latter means that the width or height will be the same as its parent’s width or

height.

Page 13: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 13

Another important property and distinction we should make is between padding and margin. The above

figure illustrates the different between the two. Padding is internal to the border of the View. Margin,

on the other hand, is external to the border to the View. We use a combination of padding and margin

to prevent the content of our views from being flush with the edge of the phone. It makes our content

easier to read for the user’s sake and that’s always important! In fact, Google’s Material Design

guidelines provide keylines in units of dp’s, which stand for density-independent pixels. For layouts, it’s

more common to use padding since the layout contains other views; for single UI elements, it’s more

common to use a combination of both.

The most important property, however, is the id property. This is the id that allows us to grab a

reference to that view via its id. We also need to tell Android that we’re creating an id for a new UI

element and not referring to an existing one. This is why we use “@+id/someView” when creating an id

for a particular UI element and “@id/someView” is referring to another View. On a side note,

referring to Views is something that we need to do when strategically placing UI elements. Creating ids

will let us access them using the findViewById(int) method. When we save any XML file,

Android Studio automatically updates the R.id file.

EditText If TextViews are the simplest way for users to view text, EditTexts are the simplest way for users to

enter text. They are actually a subclass of TextView that is editable. The XML example for an EditText is

similar to a TextView:

Page 14: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 14

1

2

3

4

5

<EditText

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:hint="Hello World!"

/>

A useful property of EditText for text input is the hint property. It provides us with a transparent overlay

that sits on top of the textbox and disappears when the user taps on it to input text. If we had used the

text property for this purpose, the user would have to clear out that text before they could input their

own. The hint property allows us to tell the user what data is supposed to go into this EditText.

One of the greatest properties of an EditText is that it can bring up a keyboard that’s most relevant to

the kind of input we want our user to enter. Take the Contacts app for example. When entering a phone

number, you’ll notice that the entire QWERTY keyboard won’t show up, but we’ll just get the numpad

instead. This is the inputType property on EditTexts. Below is a list that describes the possible values for

the inputType property:

1. “text” – Brings up the plain text QWERTY keyboard

2. “textEmailAddress” – Like “text”, except with the @ (at) character

3. “textUri” – Like “text”, except with the / (forward slash) character

4. “number” – Brings up standard number input keypad

5. “phone” – Brings up the dialer keypad

In addition to those values, we can even specify other characters of plain text input. For example,

suppose we were entering someone’s name. It would be nice of the keyboard could automatically

capitalize the first and last name. Or suppose we were typing an email; then we’d want the keyboard to

capitalize each sentence. Luckily, these inputType constants are also very explicitly named:

“textCapSentences”, “textCapWords”, “textAutoCorrect”, “textPassword”, “textMultiline”. To be even

more explicit, “textPassword” changes all of the characters to • (dots), and “textMultiline” allows the

user to use line breaks.

Speaking of line breaks, it may be the case that you’d want multiple lines for text entry for things like

emails, for example. To force the EditText to span multiple lines, we can set the minLines property on it

to some positive integer. This will for the EditText to be at least that number of lines tall, prompting your

user to enter text that’s longer than a single line.

Page 15: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 15

Button The Button is the most common way for users to begin or end some activity. For example, we might use

buttons to allow the user to submit a form, download an in-app purchase, or end the level of a

game. Therefore, the most common action associated with buttons is tapping on them! There are

several ways for us to detect a button press and to run code on a button click. The first way is the

simplest way and that uses the onClick property that Buttons have. We can declare a Button whose

onClick property is the name of a method with a very particular method signature in any Activity that

sets that XML layout to be its content view:

1

2

3

4

5

6

<Button

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:text="Submit"

android:onClick="buttonClicked"

/>

This button is a small UI element defined in a bigger layout view, which in turn is defined in a layout file.

Activities can present a view to the user through the setContentView(int) method and pass in

the id of a layout file using the R class. Now, in any Activity that uses the layout file as the main content

view will have to implement a method that looks EXACTLY like this:

1

2

3

public void buttonClicked(View view) {

...

}

The method must be public void and take in a single View parameter. It might be easier to define all

of your button click actions first, then associate them with a Button in the layout since the property’s

autocomplete will help you find a particular method. As a rule of thumb, if autocomplete can’t find your

method, that’s a sign the method signature is incorrect in some way. The reason the method is public

void is so Android Studio can see it and because button event listeners don’t generally have return

values. The View method parameter corresponds to which View was clicked. This can be helpful because

instead of declaring multiple methods for different Buttons, we could wire all of the Buttons to one

Page 16: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 16

method and use view.getId() to differentiate between the Buttons using their unique id that we

would set.

There is another way to do event handling for Button clicks and that involves a language feature of Java

called anonymous inner classes. Instead of setting the listener in the XML layout, we could do it

in Java source code. Suppose we have some Button whose id is submitButton. The follow code snippet

will grab a reference to that and setup an event handler for the Button’s onClick event:

1

2

3

4

5

6

7

Button submitButton = (Button) findViewById(R.id.submitButton);

submitButton.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

...

}

});

The more interesting portion of the code snippet is the next line that sets the listener. All listeners in

Android are interfaces, meaning we can’t instantiate them. However, we can set them to a new object

whose’s class implements that particular interface. Anonymous inner classes is a shorthand way of doing

this. Instead of creating an inner class that implements the View.OnClickListener interface

and passing in new SomeClassImplementingTheListener, we can just do that in-place by

“instantiating” a new nameless class that automatically implements that interface and provide method

bodies on the spot. This works equally well. In fact, there’s a third way we could do this even. We could

pass in this and have the activity in which this code is in implement

the View.OnClickListener interface and force it to have a @Override public void

onClick(View) method. The rule of thumb you can use is “If the method contents are going

to have many lines of code, then it looks cleaner to pass in this , make the Activity implement the

interface, and give it a method body as a regular method on the same level of the class, rather than to

add a lengthy method body to an existing method. It’s just more lines of indentation you have to

manage.”

Conclusion In this post, we looked at TextViews, EditTexts, and Buttons. When looking at TextViews, we also

glanced at some of the key properties that are central to all Views. We learned that we can configure

the keyboard that EditTexts pull up to suite our data input needs, as well as make them span multiple

Page 17: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 17

lines high for longer text input. Buttons are useful for starting or stopping something and we primarily

learned about event handling when it came to Buttons. As a bonus, we learned about Java’s anonymous

inner classes and how we can use them for event handling.

Page 18: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 18

Creating a Unit Converter App – Part 1 In this post (split into two), we’re going to build a unit converter app. We’ll be learning many things

along the way like the Model-View-Controller (MVC) pattern, Java Enums, and Spinners. By the end

of this post, we’ll have a working app that will allow us to convert to and from various units of distance

like miles, centimeters, kilometers, and other units. Feel free to append more types of units as well!

As a side note, it’ll be helpful if you’ve read over how to setup Android Studio, create projects, and some

of the basic Android UI elements. You can get up to speed very quickly by following the link here.

You can pull the source code for this project here.

Model-View-Controller (MVC) Pattern When dealing with a system that has many moving parts it’s helpful to have some form of system design

that helps us keep everything distinct. Imagine the mess our app would be if we had XML views, Java

source code, and other components wildly about in our Android project! To prevent this disaster from

occurring, we have design patterns we follow to try to keep our code as segmented as possible. Similar

to the concept of encapsulation in Java, we want to make sure our components are separated from each

other. For this, we use the Model-View-Controller (MVC) pattern. The MVC Pattern is now ubiquitously

used in both mobile and desktop development.

The above figure is an illustration of the components of the MVC pattern. There’s the model, view, and

controller. The model can be any kind of backend such as a database or web server. It can also be any

kind of structure that holds or stores data somewhere, like a local key-value pairing system. The view is

pretty self-explanatory: it’s the UI that’s presented to the user. The controller is the most crucial

Page 19: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 19

component that allows for communication between the model and the view. However, the view and the

model don’t even know the other exist! This is so we can make changes to the model or the view and we

only need to update the controller instead of all three components! (The view in most case is

the component that is updated the most frequently.) The MVC Pattern is now ubiquitously used in both

mobile and desktop development.

Specifically, Android supports the MVC pattern and we’re going to be using it throughout this app and all

other apps. In fact, Android mandates the view and the model are all separate because the view is in

written in an XML layout file (although it is possible to manually instantiate views in Java source code).

In Java, Activities act as the controller and mediate between the XML views whatever model backend we

decide to use. In our case, our model will just be a utility class that we’ll store the constants needed for

converting from one kind of unit to another.

Creating the UnitConverter Project Let’s get started! First of all, we’ll want to create an Android project called UnitConverter with any

package name we want. We’ll want to keep this to Android 6.0 and creating a blank activity named

MainActivity will suffice for us. The first component we’ll create is the model. We’ll need to right-click on

the main package (not the one ending with (androidTest)!) and create a new class called Converter. This

will be used to convert the different units. However, we’ll need to keep some way to represent

units. There are several ways we can do this: String constants with the name of the units, distinct integer

constants that represent those values, or we can use a language feature of Java called enums.

Java Enums Enums in Java were introduced to the language after it was created and was not a part of it’s

original language features. There’re really usefully however! Essentially, we can use them to create

groups of related constants. An enum is also a kind of class in the sense that we can declare variables

and methods in an enum. One of the greatest benefits of using enums is the fact that they’re type-safe!

Meaning that we can’t assign an enum variable to just any value, it must be to a valid constant in the

variable’s enum. It also prevents us from performing any arithmetic operations. It doesn’t make any

sense to add constants representing something like units! If we used String or integer constants, we

could do something KILOMETER + MILE and that wouldn’t make any sense! Once we declare an enum,

we can use it as a type like we would with a class or interface. However, as I mentioned before, the

value of the enum variable must be in the enum class that defines that variable. Under the hood, Java

essentially creates objects with static memory addresses so when we refer to an enum constant, there’s

only one! This is great because we can do equality checks with == since the only way the two enum

pointers are the same is if they point to the same object in memory, of which there is only

one! Similarly, we can use the assignment operator since that will also allow us to set the pointers to the

same static object in memory. To sum up, enums are a kind of class that allow us to group related

constants in a type-safe way much better than integer or String constants.

We’re going to nest our enum inside our Converter class, but to do that, we need to create our

Converter class! Right-click on our main package (not the green highlighted one that ends with

Page 20: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 20

“(androidTest)” since that’s the test suite) and select New Java Class. We’ll call it Converter. Inside it,

let’s declare the following enum:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

public enum Unit {

INCH,

CENTIMETER,

FOOT,

YARD,

METER,

MILE,

KILOMETER;

// Helper method to convert text to one of the above constants

public static Unit fromString(String text) {

if (text != null) {

for (Unit unit : Unit.values()) {

if (text.equalsIgnoreCase(unit.toString())) {

return unit;

}

}

}

throw new IllegalArgumentException("Cannot find a value for " + text);

}

}

Page 21: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 21

We can see that an enum can be declared in a similar fashion to a class. The first thing in an enum is the

comma-delimited list of constants. If we wanted to write methods, we have to terminate our list of

constants with a semicolon. Then we’re free to write any methods. In this case, we’re writing a small

utility method that will return us a enum value given a String. We’re doing our null check as the first

step. Then we go through each value of the enum and if our input equals the name of the enum

constant, then return that enum constant. At the end of the method, we’re going to throw an exception

saying that the user didn’t input a valid unit String. Enum checking is exhaustive, meaning that if we get

an enum of type Unit, we know that its value MUST be one of the constants. We can access those

constants by Unit.MILE for example. You’ll see in the next post that Spinners only allow the user to input

a finite set of options. This, along with the fact that enums are exhaustive, means that we’ll never reach

that exception and it’s just there for our debugging purposes. Now we can start using our enums in our

model.

Model: Converter class In the same Converter class, we’re going to need to design a way to convert from one unit to another.

Essentially, a user would input a starting unit, an ending unit, and a value to convert. There are several

design approaches we could take. For example, we could have a static method that takes in two Unit

objects and a double and converts between the two. However, to demonstrate OOP even further, we’ll

have the Converter class take the to and from Units as part of the constructor and have an instance

method called convert(double) that takes in a double and returns an output. We can convert

from any unit to another valid unit by multiplying it by some constant. Since we’re following the

constructor approach, we can set that constant in the constructor to make our method very simple. To

set the constant, we need to check the value of the the to and from units and set the constant equal to

some value that will properly convert from one to the other. We can initially set the constant to 1 in the

case that the to and from Units are equal to help reduce a case. Here’s what this would look like: (put

this code after the enum declaration)

1

2

3

4

5

6

7

8

9

// What can I multiply by to get me from my fromUnit to my toUnit?

private final double multiplier;

public Converter(Unit from, Unit to) {

double constant = 1;

// Set the multiplier, else if fromUnit = toUnit, then it is 1

switch (from) {

case INCH:

if (to == Unit.CENTIMETER) {

Page 22: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 22

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

constant = 2.54;

} else if (to == Unit.FOOT) {

constant = 0.0833333;

} else if (to == Unit.YARD) {

constant = 0.0277778;

} else if (to == Unit.METER) {

constant = 0.0254;

} else if (to == Unit.MILE) {

constant = 1.5783e-5;

} else if (to == Unit.KILOMETER) {

constant = 2.54e-5;

}

break;

case CENTIMETER:

if (to == Unit.INCH) {

constant = 0.393701;

} else if (to == Unit.FOOT) {

constant = 0.0328084;

} else if (to == Unit.YARD) {

constant = 0.0109361;

} else if (to == Unit.METER) {

constant = 0.01;

} else if (to == Unit.MILE) {

constant = 6.2137e-6;

} else if (to == Unit.KILOMETER) {

constant = 1e-5;

}

Page 23: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 23

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

break;

case FOOT:

if (to == Unit.INCH) {

constant = 12;

} else if (to == Unit.CENTIMETER) {

constant = 30.48;

} else if (to == Unit.YARD) {

constant = 0.333333;

} else if (to == Unit.METER) {

constant = 0.3048;

} else if (to == Unit.MILE) {

constant = 0.000189394;

} else if (to == Unit.KILOMETER) {

constant = 0.0003048;

}

break;

case YARD:

if (to == Unit.INCH) {

constant = 36;

} else if (to == Unit.CENTIMETER) {

constant = 91.44;

} else if (to == Unit.FOOT) {

constant = 3;

} else if (to == Unit.METER) {

constant = 0.9144;

} else if (to == Unit.MILE) {

constant = 0.000568182;

Page 24: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 24

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

} else if (to == Unit.KILOMETER) {

constant = 0.0009144;

}

break;

case METER:

if (to == Unit.INCH) {

constant = 39.3701;

} else if (to == Unit.CENTIMETER) {

constant = 100;

} else if (to == Unit.FOOT) {

constant = 3.28084;

} else if (to == Unit.YARD) {

constant = 1.09361;

} else if (to == Unit.MILE) {

constant = 0.000621371;

} else if (to == Unit.KILOMETER) {

constant = 0.001;

}

break;

case MILE:

if (to == Unit.INCH) {

constant = 63360;

} else if (to == Unit.CENTIMETER) {

constant = 160934;

} else if (to == Unit.FOOT) {

constant = 5280;

} else if (to == Unit.YARD) {

Page 25: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 25

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

constant = 1760;

} else if (to == Unit.METER) {

constant = 1609.34;

} else if (to == Unit.KILOMETER) {

constant = 1.60934;

}

break;

case KILOMETER:

if (to == Unit.INCH) {

constant = 39370.1;

} else if (to == Unit.CENTIMETER) {

constant = 100000;

} else if (to == Unit.FOOT) {

constant = 3280.84;

} else if (to == Unit.YARD) {

constant = 1093.61;

} else if (to == Unit.METER) {

constant = 1000;

} else if (to == Unit.MILE) {

constant = 0.621371;

}

break;

}

multiplier = constant;

}

Page 26: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 26

118

119

120

121

// Convert the unit!

public double convert(double input) {

return input * multiplier;

}

Now the convert method is really simple. We just return the constant times the input. One downside to

this approach is if we wanted to convert another set of units, we’d have to create a new Converter

object. However, in our case, we’ll only initialize the Converter object after the user has clicked the

“Convert” Button. But now our model is ready and we can use it to convert units!

In this post, we covered the MVC pattern and how we’ll be using it in our apps. We also completely

created the model of our Unit Converter app and learned about Java enums and how we can use them

to label constants in a type-safe manner. In the follow post, we’ll be building the View

and implementing the Controller to interact between the Model and View.

Page 27: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 27

Creating a Unit Converter App – Part 2 This is Part 2 of the series on creating a Unit Converter app (you can view part 1 here). In this final

section, we’re going to work on the View and Controller of our Unit Converter and learn about how we

can design a UI with Spinners to allow the user the convert units.

View

Since we have a relatively simple app, we’re going to have a relatively simple UI. We’ll limit our

application to just a single screen for simplicity. We need an EditText for the user to enter values in and

another, immutable one to show the result of the conversion. Instead of an EditText, we could have

used a TextView since they’re meant to be immutable, but for the sake of consistency in our app, we can

Page 28: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 28

easily force an EditText to be immutable and use it to only display values, not enter them. A Button that

will allow the user to start the conversion process. Most of our work will be done when the Button is

pressed since it’s the primary action for our app. However, we need constructs to allow the user to

choose a single option from a finite list of possibilities. If you’ve used a web browser, you’re probably

familiar with selection boxes. Android’s method of doing this is called a Spinner.

Spinner For our view however, we’ll need some kind of selection method to give the user a chance to

choose the unit they want to start at and the one they want to end with. For this purpose, we have

Spinners in Android. Given an array of elements, we can populate a Spinner with elements and, at any

point in time, get the option that the user selected.

We’re going to add some Spinners and other UI components to our layout. Our final layout file (called

activity_main.xml in res/layout should look something like the following.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<RelativeLayout

android:layout_width="match_parent"

android:layout_height="match_parent"

android:padding="16dp">

<Spinner

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:id="@+id/spinner_from"

android:layout_alignParentTop="true"

android:layout_alignParentStart="true"

android:layout_alignParentEnd="true" />

<EditText

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:inputType="numberDecimal"

Page 29: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 29

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

android:ems="10"

android:id="@+id/editText_from"

android:layout_below="@+id/spinner_from"

android:layout_alignParentStart="true"

android:layout_alignParentEnd="true" />

<Spinner

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:id="@+id/spinner_to"

android:layout_below="@+id/editText_from"

android:layout_alignParentStart="true"

android:layout_alignParentEnd="true" />

<EditText

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:inputType="numberDecimal"

android:clickable="false"

android:focusable="false"

android:focusableInTouchMode="false"

android:cursorVisible="false"

android:ems="10"

android:id="@+id/editText_to"

android:layout_below="@+id/spinner_to"

android:layout_alignParentStart="true"

android:layout_alignParentEnd="true" />

Page 30: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 30

45

46

47

48

49

50

51

52

53

54

<Button

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Convert"

android:id="@+id/button_convert"

android:layout_centerVertical="true"

android:layout_centerHorizontal="true"

android:onClick="convert" />

</RelativeLayout>

There are a few properties that we might not have seen before. For example,

layout_alignParentStart and layout_alignParentEnd are similar to

layout_alignParentLeft and layout_alignParentRight except they work with

right-to-left layout styles of text (such as Arabic) as well. The ems property on EditTexts allows us to

change the font size essentially. To prevent users from entering text in the EditText, we have a slew of

properties that will only allow the EditText’s text to be changed programatically. This is done in the

lines starting with android:clickable="false" and ending

with android:cursorVisible="false". The Spinners are the more interesting part. As we

can see, they’re set up like any view, with any number of layout properties. However, they need to be

populated with values.

There are several ways to populate a Spinner. The first, and preferred, method is to store the contents

of the Spinner entries inside of the strings.xml file in a string array element. Another way we could do

this is to hard-code an array, but there are downsides to this approach. For example, we won’t be able

to localize the strings to a particular language. If we have it in the XML file, then we can have it

translated to another language and create another strings.xml file to store the strings of that particular

language and the Android system will decide at runtime which one to use, depending on the locale of

the device. This is partly how the Android resource system works, but we’ll save that topic for another

time.

To add a string array to the strings.xml file, we need to navigate to that file located in our res/values

directory. There should be a file called strings.xml in that directory. There should already be some

content inside it, but we can add a string array by typing in the following code as the last XML element in

the file:

Page 31: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 31

1

2

3

4

5

6

7

8

9

<string-array name="units">

<item>Inch</item>

<item>Centimeter</item>

<item>Foot</item>

<item>Yard</item>

<item>Meter</item>

<item>Mile</item>

<item>Kilometer</item>

</string-array>

This will declare all of our valid units. Now that this is done, we can grab a reference to our Spinner and

create an ArrayAdapter to get the elements from the XML array and format in a way that the Spinner

can understand it. The purpose of adapters is to take text or other data and format it in a way that it can

be displayed in UI elements. We use adapters for Spinners, Lists, Grids, and many other Views. This

whole process only takes a few quick lines of code to do and we can use the same adapter for both of

our Spinners since they both will have the same information displayed in the same fashion. We need to

do this in the onCreate(Bundle) method so that right after our view is associated with

this Activity, the layout’s Spinners will be populated with text. In our MainActivity’s

onCreate(Bundle) method, add the following code snippet.

1

2

3

4

5

6

7

8

9

// An adapter to convert the String[] into something that can go in the Spinner

ArrayAdapter&lt;CharSequence&gt; adapter = ArrayAdapter.createFromResource(this, R.array.units, android.R.layout.simple_spinner_item);

adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

fromSpinner = (Spinner) findViewById(R.id.spinner_from);

toSpinner = (Spinner) findViewById(R.id.spinner_to);

fromSpinner.setAdapter(adapter);

toSpinner.setAdapter(adapter);

Page 32: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 32

In the above code, we have an ArrayAdapter of CharSequence, but since String implements

CharSequence, we can use it. The ArrayAdapter.createFromResource(Context,

int, int) method takes a Context object, which is, in almost all cases, the current Activity. The two

integers are the reference to the array we created in the strings.xml file and the second is the layout we

want to use. We could create our own custom layout in the layout folder, but we can

use Android’s spinner layout instead since it’s just a single TextView displaying our items. The next line

sets the view that will be shown when a user taps on a Spinner and the dropdown appears with all of

the options. We can use Android’s default spinner dropdown layout as well. The next two lines grab a

reference to the Spinners. The final two lines set the Spinner’s adapter to be the adapter we created.

This is all it takes to configure our adapter! When we run the app, the Spinner will be populated with the

values of our adapter and will display them in the layout we specified.

Wiring Up the Button Now that we’ve set up our View, we can configure the Button to do something when it is clicked. If you

remember from the previous part, we used the onClick property of our Button and the name of our

method is convert(View) . Let’s break down what we need to do. We first need a reference to the

Spinners and the EditTexts. Then we need to extract the text from the Spinner item and map it to a Unit.

This will be easy since it’s one of the core functionality of our model. Then we can instantiate a new

Converter object, given the to and from units, and perform the conversion. The final step is setting the

output EditText’s text to be the converted value. In Java source code, this looks like the following.

1

2

3

4

5

6

7

8

9

10

11

12

13

public void convert(View view) {

Spinner fromSpinner, toSpinner;

EditText fromEditText, toEditText;

fromSpinner = (Spinner) findViewById(R.id.spinner_from);

toSpinner = (Spinner) findViewById(R.id.spinner_to);

fromEditText = (EditText) findViewById(R.id.editText_from);

toEditText = (EditText) findViewById(R.id.editText_to);

// Get the string from the Spinners and number from the EditText

String fromString = (String) fromSpinner.getSelectedItem();

String toString = (String) toSpinner.getSelectedItem();

double input = Double.valueOf(fromEditText.getText().toString());

Page 33: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 33

14

15

16

17

18

19

20

21

22

23

// Convert the strings to something in our Unit enu,

Converter.Unit fromUnit = Converter.Unit.fromString(fromString);

Converter.Unit toUnit = Converter.Unit.fromString(toString);

// Create a converter object and convert!

Converter converter = new Converter(fromUnit, toUnit);

double result = converter.convert(input);

toEditText.setText(String.valueOf(result));

}

There may be points of improvement that we can make for performance or efficiency. For example,

instead of reinitializing the views, we could just declare them as private member variable and only call

findViewById(int) once in onCreate(Bundle) . This is because calls to

findViewById(int) are expensive operations so calling them the least amount of times possible

is definitely a good thing! Now we can click the green button and run our app! We should get something

like the following screenshot in our emulator!

Page 34: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 34

Conclusion Throughout the course of the previous two posts, we’ve successfully created a unit converter

application. Along the way, we learned about the Model-View-Controller (MVC) pattern, which allows

the Controller to interact as the mediator between the Model and View. We also learned about Java

enums, which group related constants together. We created our Converter class model and moved on to

the View. We learned about Spinners and adapters as well as how to use them effectively in Android.

Finally, we implemented the Controller to convert the input value from one unit to another.

Page 35: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 35

Page 36: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 36

How to Create Simple Lists using ListViews Hello World! In this post, we’re going to learn how to use one of the most useful views in Android: the

ListView. We can use ListViews to present data in the form of a list. We can choose any kind of data as

input and display it however we want. That’s the power of a ListView. In this post, we’ll be creating a

simple app that presents a list showing all of the countries of the world.

Note: While Android now has a much more generic RecyclerView, since our task is going to be fairly

simple, we’ll stick to the ListView so we don’t have to deal with the additional complexities of the

RecyclerView. To summarize, a RecyclerView is more generic version of a GridView and ListView. It

allows developers to have greater power and control over the presentation of data and makes things

like animations easier to do. However, with this greater control, we have to implement many things

ourselves, such as a custom adapter, item layout, and view holder. For our purposes, a plain old ListView

will suffice. With great power comes great responsibility!

All of source code for this project is in a ZIP file here.

Creating the Project Let’s start up Android Studio and create a new project titled ListViewDemo. We can give any package

name we want and select Android 6.0 Marshmallow as our minimum SDK version. We’ll just need an

empty activity and we’ll leave the default names as is. We won’t need too much code to get our ListView

working. First, we’ll need open up the Activity’s layout file in res/layout. We can replace

the entire contents of the file with just the following code snippet:

1

2

3

4

5

6

7

8

9

<?xml version="1.0" encoding="utf-8"?>

<ListView xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

tools:context=".MainActivity"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingTop="@dimen/activity_vertical_margin"

android:paddingBottom="@dimen/activity_vertical_margin"

android:id="@+id/listView" />

The above code will create a ListView for us and give it some properties. By setting the height and width

of a top-level UI element to be match_parent , we are telling Android to make this UI element take up

the entire screen, which is exactly what we want our ListView to do. We have some padding to the top

Page 37: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 37

and bottom so that the text in the list items aren’t right up against the top of the screen, making it

difficult to read. Finally, we have the id property so that we can refer to this ListView when we get to

our source code.

For our model, we’ll be displaying all of the countries in the world, but we need a place to store that

information. We’ll keep it in our strings.xml file in res/values. Open up that file and paste the

following between the resources tag:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<string-array name="countries_array">

<item>Afghanistan</item>

<item>Albania</item>

<item>Algeria</item>

<item>American Samoa</item>

<item>Andorra</item>

<item>Angola</item>

<item>Anguilla</item>

<item>Antarctica</item>

<item>Antigua and Barbuda</item>

<item>Argentina</item>

<item>Armenia</item>

<item>Aruba</item>

<item>Australia</item>

<item>Austria</item>

<item>Azerbaijan</item>

<item>Bahrain</item>

<item>Bangladesh</item>

<item>Barbados</item>

<item>Belarus</item>

<item>Belgium</item>

Page 38: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 38

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

<item>Belize</item>

<item>Benin</item>

<item>Bermuda</item>

<item>Bhutan</item>

<item>Bolivia</item>

<item>Bosnia and Herzegovina</item>

<item>Botswana</item>

<item>Bouvet Island</item>

<item>Brazil</item>

<item>British Indian Ocean Territory</item>

<item>British Virgin Islands</item>

<item>Brunei</item>

<item>Bulgaria</item>

<item>Burkina Faso</item>

<item>Burundi</item>

<item>Cambodia</item>

<item>Cameroon</item>

<item>Canada</item>

<item>Cape Verde</item>

<item>Cayman Islands</item>

<item>Central African Republic</item>

<item>Chad</item>

<item>Chile</item>

<item>China</item>

<item>Christmas Island</item>

<item>Cocos (Keeling) Islands</item>

<item>Colombia</item>

Page 39: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 39

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

<item>Comoros</item>

<item>Congo</item>

<item>Cook Islands</item>

<item>Costa Rica</item>

<item>Cote d\'Ivoire</item>

<item>Croatia</item>

<item>Cuba</item>

<item>Cyprus</item>

<item>Czech Republic</item>

<item>Democratic Republic of the Congo</item>

<item>Denmark</item>

<item>Djibouti</item>

<item>Dominica</item>

<item>Dominican Republic</item>

<item>East Timor</item>

<item>Ecuador</item>

<item>Egypt</item>

<item>El Salvador</item>

<item>Equatorial Guinea</item>

<item>Eritrea</item>

<item>Estonia</item>

<item>Ethiopia</item>

<item>Faeroe Islands</item>

<item>Falkland Islands</item>

<item>Fiji</item>

<item>Finland</item>

<item>Former Yugoslav Republic of Macedonia</item>

Page 40: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 40

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

<item>France</item>

<item>French Guiana</item>

<item>French Polynesia</item>

<item>French Southern Territories</item>

<item>Gabon</item>

<item>Georgia</item>

<item>Germany</item>

<item>Ghana</item>

<item>Gibraltar</item>

<item>Greece</item>

<item>Greenland</item>

<item>Grenada</item>

<item>Guadeloupe</item>

<item>Guam</item>

<item>Guatemala</item>

<item>Guinea</item>

<item>Guinea-Bissau</item>

<item>Guyana</item>

<item>Haiti</item>

<item>Heard Island and McDonald Islands</item>

<item>Honduras</item>

<item>Hong Kong</item>

<item>Hungary</item>

<item>Iceland</item>

<item>India</item>

<item>Indonesia</item>

<item>Iran</item>

Page 41: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 41

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

<item>Iraq</item>

<item>Ireland</item>

<item>Israel</item>

<item>Italy</item>

<item>Jamaica</item>

<item>Japan</item>

<item>Jordan</item>

<item>Kazakhstan</item>

<item>Kenya</item>

<item>Kiribati</item>

<item>Kuwait</item>

<item>Kyrgyzstan</item>

<item>Laos</item>

<item>Latvia</item>

<item>Lebanon</item>

<item>Lesotho</item>

<item>Liberia</item>

<item>Libya</item>

<item>Liechtenstein</item>

<item>Lithuania</item>

<item>Luxembourg</item>

<item>Macau</item>

<item>Madagascar</item>

<item>Malawi</item>

<item>Malaysia</item>

<item>Maldives</item>

<item>Mali</item>

Page 42: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 42

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

<item>Malta</item>

<item>Marshall Islands</item>

<item>Martinique</item>

<item>Mauritania</item>

<item>Mauritius</item>

<item>Mayotte</item>

<item>Mexico</item>

<item>Micronesia</item>

<item>Moldova</item>

<item>Monaco</item>

<item>Mongolia</item>

<item>Montenegro</item>

<item>Montserrat</item>

<item>Morocco</item>

<item>Mozambique</item>

<item>Myanmar</item>

<item>Namibia</item>

<item>Nauru</item>

<item>Nepal</item>

<item>Netherlands</item>

<item>Netherlands Antilles</item>

<item>New Caledonia</item>

<item>New Zealand</item>

<item>Nicaragua</item>

<item>Niger</item>

<item>Nigeria</item>

<item>Niue</item>

Page 43: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 43

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

<item>Norfolk Island</item>

<item>North Korea</item>

<item>Northern Marianas</item>

<item>Norway</item>

<item>Oman</item>

<item>Pakistan</item>

<item>Palau</item>

<item>Panama</item>

<item>Papua New Guinea</item>

<item>Paraguay</item>

<item>Peru</item>

<item>Philippines</item>

<item>Pitcairn Islands</item>

<item>Poland</item>

<item>Portugal</item>

<item>Puerto Rico</item>

<item>Qatar</item>

<item>Reunion</item>

<item>Romania</item>

<item>Russia</item>

<item>Rwanda</item>

<item>Sqo Tome and Principe</item>

<item>Saint Helena</item>

<item>Saint Kitts and Nevis</item>

<item>Saint Lucia</item>

<item>Saint Pierre and Miquelon</item>

<item>Saint Vincent and the Grenadines</item>

Page 44: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 44

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

<item>Samoa</item>

<item>San Marino</item>

<item>Saudi Arabia</item>

<item>Senegal</item>

<item>Serbia</item>

<item>Seychelles</item>

<item>Sierra Leone</item>

<item>Singapore</item>

<item>Slovakia</item>

<item>Slovenia</item>

<item>Solomon Islands</item>

<item>Somalia</item>

<item>South Africa</item>

<item>South Georgia and the South Sandwich Islands</item>

<item>South Korea</item>

<item>South Sudan</item>

<item>Spain</item>

<item>Sri Lanka</item>

<item>Sudan</item>

<item>Suriname</item>

<item>Svalbard and Jan Mayen</item>

<item>Swaziland</item>

<item>Sweden</item>

<item>Switzerland</item>

<item>Syria</item>

<item>Taiwan</item>

<item>Tajikistan</item>

Page 45: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 45

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

<item>Tanzania</item>

<item>Thailand</item>

<item>The Bahamas</item>

<item>The Gambia</item>

<item>Togo</item>

<item>Tokelau</item>

<item>Tonga</item>

<item>Trinidad and Tobago</item>

<item>Tunisia</item>

<item>Turkey</item>

<item>Turkmenistan</item>

<item>Turks and Caicos Islands</item>

<item>Tuvalu</item>

<item>Virgin Islands</item>

<item>Uganda</item>

<item>Ukraine</item>

<item>United Arab Emirates</item>

<item>United Kingdom</item>

<item>United States</item>

<item>United States Minor Outlying Islands</item>

<item>Uruguay</item>

<item>Uzbekistan</item>

<item>Vanuatu</item>

<item>Vatican City</item>

<item>Venezuela</item>

<item>Vietnam</item>

<item>Wallis and Futuna</item>

Page 46: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 46

238

239

240

241

242

243

<item>Western Sahara</item>

<item>Yemen</item>

<item>Yugoslavia</item>

<item>Zambia</item>

<item>Zimbabwe</item>

</string-array>

The above XML just creates a string array that holds all of the countries of the world. One of the benefits

of putting this in the res folder is that we can localize the strings to any particular language. This is just

one of the many benefits of the Android resource system. To summarize the Android resource

system, we can provide string files in different languages, layouts in different orientations, and other

specifications and Android will choose the one that pertains to the user’s current situation at runtime.

We just have to be thorough in providing Android with all of these resources. We can do this

by appending a very specific sequence of characters after the “main” name of the folder (i.e. values,

layout, drawable). For example, suppose we want to have a different dimensions file for tablet screens

or screens with a width of 820 density-independent pixels (dp). We can create another folder called

values and append “-w820dp” to the folder name. Then we can add any files to this folder and Android

will only use these values if the device which runs our app has a width of 820dp.

Now that we have our data, we can actually link up our model and our view. Open up

the MainActivity.java file and we’ll create a few member variables to hold data. We’ll create one for the

ListView and another for the ArrayAdapter:

1

2

private ListView listView;

private ArrayAdapter<CharSequence> adapter;

The reason that the ArrayAdapter is a generic of CharSequence instead of String is because we’ll be

grabbing string array from the strings.xml file. We can have a String array since CharSequence is an

interface and String implements CharSequence, hence we can use String. Now that we have our

member variables set up, we actually need to configure our adapter and ListView. Doing this setup in

onCreate(Bundle) is ideal because that method is going to be called before the screen is actually visible

to the user, so data will be ready as soon as the view is presented. In our onCreate(Bundle) method,

let’s add the following code:

Page 47: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 47

1

2

3

listView = (ListView) findViewById(R.id.listView);

adapter = ArrayAdapter.createFromResource(this, R.array.countries_array, android.R.layout.simple_list_item_1);

listView.setAdapter(adapter);

The first line grabs a reference to the ListView. Then, we need to create a new adapter using a static

utility method on ArrayAdapter called ArrayAdapter.createFromResource(Context, int, int) .

The purpose of the method is to take the contents of the given string array and put it in the layout. The

first parameter is the Context. In Android, the Context is the current state of the application. We use it

to initialize views or to get something from our app resources or the system’s resources. Since Activity is

a subclass of Context, we can pass in this as a valid object. The second parameter is the string array of

countries. Since this is in our resources system and an array, we need to use the R class to access it via

R.array.countries_array . The final parameter is the layout that we want to populate with the string

array. In our case, we’re just using Android’s simplest ListView layout that consists of just a single

TextView. Finally, we set the ListView’s adapter to be the one we just created. Now we should be able to

run our application and see the results!

Page 48: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 48

Page 49: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 49

Setting up a ListView to display data is great, but we want some user interaction in our ListView. For

example, when a user taps on a list item, we want to do something about it. To do this, we need to set

up an event listener to notify us when the user taps on a list item. Event listeners work by allowing us to

register and run a callback method when the event occurs. That callback method is in the form of an

interface we pass in to the listener. There are several ways we can choose to implement an event

listener: create a separate class that implements that interface and pass in a new instance of that

class; use Java’s anonymous inner classes; or pass in this and force our Activity to implement the

interface and the callback method. For our case, it’ll look cleaner if we do the latter. Note that there are

many different listeners so we have to choose the appropriate one for the event we want to receive

information about. We can set the listener in the onCreate(Bundle) method

by executing listView.setOnItemClickListener(this); to set up our listener. This will make Android

Studio throw an error and so we have to implement the interface in our Activity. Our class declaration

changes to public class MainActivity extends AppCompatActivity implements

AdapterView.OnItemClickListener. We also have to implement the callback method for in our class on

the class level like the following.

1

2

3

4

@Override

public void onItemClick(AdapterView&lt;?&gt; adapterView, View view, int position, long id) {

Toast.makeText(this, adapter.getItem(position), Toast.LENGTH_SHORT).show();

}

You’ll notice we use Toasts in the above code. A Toast just shows a transparent overlay. We need to

pass in a Context, which is just this again. The second parameter is the text we want to show.

We’re essentially grabbing the text at that position in the ListView. This means that when the user taps

on a ListView item, we’ll just have a Toast that displays what’s on the ListView. The final parameter is

just a constant corresponding to how long we want to show the Toast. However, the makeText(Context,

CharSequence, int) method just creates a Toast, we have to show it by calling show() on the newly

created Toast message. This is all it takes to configure our ListView! We can see the final result below.

Page 50: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 50

Conclusion

Page 51: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 51

In this post, we covered the basics of ListView and how to populate it with items from an adapter. For

our purposes, we just used a string array in our strings.xml file. As a side note, we learned more about

the Android resource system as well. In addition to populating a ListView, we also learned how to

configure event listeners to be notified when some event happens regarding the ListView. We used that

to display a Toast message to the user.

Page 52: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 52

How to Create Lists using RecyclerView In this post, we’re going to look at the newer RecyclerView to build more complicated lists and list items.

RecyclerView was a recently added UI item that gave developers fine-grain control and power over their

lists or grids. However, as we’ll find out, that great power comes with great responsibility. RecyclerView

doesn’t provide much of the basic functionality that ListView does, so we’ll have to implement it

ourselves. In this post, we’ll be implementing a layout with an icon on the left and descriptive text on

the right.

Note: Before we create the project, we’ll need to make sure we have the support library downloaded.

The support library was released to allow for greater backwards-compatibility among the range of

physical devices and their different Android versions in the ecosystem. Instead of waiting for a software

update to the latest version of Android, a backwards-compatible version would be released in the

support library that developers can use right away. Open up the SDK manager and click on the SDK Tools

tab. Make sure Android Support Library and Android Support Repository are checked. If not, check

them, wait for the packages to download, and restart Android Studio. Now we can begin!

All of the source code for this project can be found here.

Creating the Project Let’s open up Android Studio and create a new project called RecyclerViewDemo (give it any package

name you want!) The minimum SDK version should be Android 6.0 Marshmallow and we can created an

empty activity with the default values. Before we can use RecyclerView, we need to add that component

to our build files since it’s in the support library. In the Project view on the left, open up the Gradle

Scripts node and the build.gradle (Module: app) file. Note that there is a build.gradle (Project:

RecyclerViewDemo), but that serves a different purpose! Towards the bottom, there should be a section

labeled dependencies. This tells Android what our app needs to function properly. Between the curly

braces, add the following line of code: compile 'com.android.support:recyclerview-v7:23.1.+' .

This line will tell Android to include RecyclerView in our project. The first number MUST correspond to

the compileSdkVersion number we see at the top of the file. When you type that line, it might be

highlighted in yellow and we can see the suggestion if we hover our cursor over it. This warning can

generally be discarded since it just provides us with the warning that we should be using the

absolute latest version of RecyclerView. We can change the plus (+) symbol to the same version as the

dependency on the appcompat-v7 library in the same dependencies block. After we make changes to

this file, towards the top of the main coding area, we should have an option to “Sync Now” and gradle

will recompile our project with the modified dependencies.

Now we can start building the view, which turns out to be as simple as ListView. Open up the

activity_main.xml layout file in res/layout and replace the contents with the following:

1 <?xml version="1.0" encoding="utf-8"?>

Page 53: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 53

2

3

4

5

6

7

8

9

10

11

<android.support.v7.widget.RecyclerView

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingTop="@dimen/activity_vertical_margin"

android:paddingBottom="@dimen/activity_vertical_margin"

android:scrollbars="vertical"

android:id="@+id/recyclerView"

tools:context=".MainActivity" />

This looks strikingly similar to the ListView, however, we have to specify the scrollbars property since

RecyclerView is flexible to be used either horizontally or vertically. This is all we’ll need for our main

view.

We need to create a layout for each of our list items, but, before we do that, we need to define a border

for each of our list items. ListView did this for us, but we need to do this as well. Right-click on the

res/drawable folder and go to New → Drawable Resource File. We’ll name it border and replace its

contents with the following XML code to define a border and background.

1

2

3

4

5

6

7

8

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"

android:shape="rectangle">

<solid android:color="#FFFFFF" />

<stroke

android:width="1dp"

android:color="#CCCCCC" />

</shape>

Now we need to create a layout for each list item in our RecyclerView. To do this, we can right-click on

the res/layout folder and go to New → Layout Resource File. We can call it list_item and make the Root

Element a RelativeLayout. Afterwards, we’ll click OK and we should have a new file generated for us in

Page 54: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 54

the the design view. In this view, we can simply drag-and-drop UI items from the palette on the left and

change any properties in the properties pane on the bottom left. This will generate the underlying XML

code for us. We’ll need an ImageView for the icon and a TextView for the description. Click on the Text

tab at the bottom of the main pane and replaced the contents with the following.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="?android:attr/listPreferredItemHeightLarge"

android:background="@drawable/border">

<ImageView

android:id="@+id/imageView"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerVertical="true"

android:layout_alignParentStart="true"

android:layout_marginStart="@dimen/activity_horizontal_margin"

android:layout_marginEnd="@dimen/activity_horizontal_margin"

android:contentDescription="Icon" />

<TextView

android:id="@+id/textView"

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:layout_toEndOf="@id/imageView"

android:gravity="center_vertical"

android:textSize="16sp"/>

Page 55: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 55

24

25

</RelativeLayout>

The above code will properly place the ImageView and TextView within the RelativeLayout and set the

background of the RelativeLayout to the border we defined. Now we can work on the model. We’ll need

some object to represent an image and a text description. We can create a class to encapsulate this

data. Find the MainActivity.java file, and, in the package above it (NOT ending in (androidTest)), go

to New → Java Class and we’ll call it IconData. We’ll need two simple fields: a String text and an int

resource id. Put the following in the IconData class.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

public class IconData {

private String description;

private int imgId;

public IconData(String description, int imgId) {

this.description = description;

this.imgId = imgId;

}

public String getDescription() {

return description;

}

public void setDescription(String description) {

this.description = description;

}

public int getImgId() {

return imgId;

Page 56: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 56

20

21

22

23

24

25

}

public void setImgId(int imgId) {

this.imgId = imgId;

}

}

Suppose we have member variables in a class and we want getters and setters for these fields. We can

actually have Android Studio generate them AND parameterized constructors as well! On the top menu

bar, we can go to Code → Generate, then select Getters and Setters, and select both fields (using Shift

key) and click OK. We can also generate parameterized constructors in the same way, except choosing

Constructor in the popup.

Now that we have a container for our data, we can create the custom adapter that will show our data.

Create a new class in the same package and call it IconAdapter. Inside of it, we’ll create a public static

inner class ViewHolder whose superclass is RecyclerView.ViewHolder. We’ll get an error, but we can fix

it by clicking our cursor somewhere in the error and press Alt+Enter to generate a constructor matching

super. Since we’re using a more complicated layout, we’ll need to extract and keep references to

views by adding them as member variables and calling findViewById(int) on the view passed into the

constructor.

1

2

3

4

5

6

7

8

9

public static class ViewHolder extends RecyclerView.ViewHolder {

public ImageView imageView;

public TextView textView;

public ViewHolder(View itemView) {

super(itemView);

this.imageView = (ImageView) itemView.findViewById(R.id.imageView);

this.textView = (TextView) itemView.findViewById(R.id.textView);

}

}

The ViewHolder pattern is a way to make lists very efficient by recycling the list items that go off the

screen. When we have a list, we create enough memory and resources for list items on the screen plus a

Page 57: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 57

few more for smooth scrolling. When list items, go off the top of the screen, the idea is to recycle those

views by replacing their contents with that of a new data item and putting them at the bottom. This

allows us to use the least amount of memory while still giving the user a smooth experience. Now that

we’ve instantiated our ViewHolder, we’ll need to make our IconAdapter actually extend

RecyclerView.Adapter with the generic being our ViewHolder. We’ll have to implement the abstract

methods soon, but, currently, our entire IconAdapter class should look like the following:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

public class IconAdapter extends RecyclerView.Adapter<IconAdapter.ViewHolder> {

@Override

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

return null;

}

@Override

public void onBindViewHolder(ViewHolder holder, int position) {

}

@Override

public int getItemCount() {

return 0;

}

public static class ViewHolder extends RecyclerView.ViewHolder {

public ImageView imageView;

public TextView textView;

public ViewHolder(View itemView) {

super(itemView);

Page 58: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 58

23

24

25

26

27

28

this.imageView = (ImageView) itemView.findViewById(R.id.imageView);

this.textView = (TextView) itemView.findViewById(R.id.textView);

}

}

}

Now we need to start implementing the adapter and we can take full use of the ViewHolder pattern to

make this task easy. We first need some way to store data, and we’ll use an array of IconData for that

purpose. After creating a member variable and generating a parameterized constructor, we get the

following:

1

2

3

4

5

6

7

public class IconAdapter extends RecyclerView.Adapter<IconAdapter.ViewHolder> {

private IconData[] data;

public IconAdapter(IconData[] data) {

this.data = data;

}

...

Now we can start implementing the primary methods. getItemCount() can just return the length of our

data array:

1

2

3

4

5

6

...

@Override

public int getItemCount() {

return data.length;

}

...

Page 59: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 59

onCreateViewHolder(ViewGroup, int) will need to “inflate” our custom list item view from our xml

layout. However, the LayoutInflater needs a Context object and we can’t provide one from just our

adapter, but we can get one from the ViewGroup object. Then we can inflate the view and get a View

object. As the name suggests, we’ll also need to create a new ViewHolder object that will be associated

with that row and we can return that object:

1

2

3

4

5

6

7

8

9

...

@Override

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());

View listItem= layoutInflater.inflate(R.layout.list_item, parent, false);

ViewHolder viewHolder = new ViewHolder(listItem);

return viewHolder;

}

...

onBindViewHolder(ViewHolder, int) is where we actually populate the views in the list item row with

data. Because of the ViewHolder pattern, this is as simple as getting our ImageView and TextView from

our ViewHolder and setting their image or text. Within the parentheses of setText(String) and

setImageResource(int) , we grab the single IconData object at that particular position and extract its

description or image ID:

1

2

3

4

5

6

7

...

@Override

public void onBindViewHolder(ViewHolder holder, int position) {

holder.textView.setText(data[position].getDescription());

holder.imageView.setImageResource(data[position].getImgId());

}

...

Now our adapter is complete and we can begin using it! Let’s go to MainActivity.java and look in the

onCreate(Bundle) method. Inside, we should just have a class to the super class and a method call to

setContentView(int) that will associate this Activity with the given layout. We need to put any data that

Page 60: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 60

accesses views after the call to setContentView(int) since, before then, there is no inflated view! Let’s

add some code after that call so our method looks like the following:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

IconData[] data = new IconData[] {

new IconData("Delete", android.R.drawable.ic_delete),

new IconData("Alert", android.R.drawable.ic_dialog_alert)

};

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);

IconAdapter adapter = new IconAdapter(data);

recyclerView.setHasFixedSize(true);

recyclerView.setLayoutManager(new LinearLayoutManager(this));

recyclerView.setAdapter(adapter);

}

First, we create an array of static IconData that will be displayed in the RecyclerView. You might notice

on the left margin Android Studio will show a small thumbnail icon of each of the icons that we use for

each IconData object. Then, we grab a reference to the RecyclerView and create a new IconAdapter

using that array of IconData. Now we can set properties on the RecyclerView. The first is there for

performance: if the RecyclerView isn’t going to change in size, then Android can make it even smoother!

The next is the layout of the RecyclerView. It can present a list (LinearLayoutManager), a grid

(GridLayoutManager), or a staggered grid (StaggeredGridLayoutManager). We’ll be presenting a list so

we’ll use a LinearLayoutManager. Finally, we set the adapter of our RecyclerView to be our IconAdapter.

Running our application, we should see the following.

Page 61: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 61

Feel free to use any text description or icons (many are in android.R.drawable class and start with

“ic_”!). Add as many or as few items you want! This will give you a chance to see what you can do with a

RecyclerView.

Conclusion

In this post, we learned about the more power and flexible RecyclerView. However, with this power, we

had to do more work ourselves to get the desired result. For instance, we had to create a custom list

item layout and corresponding ViewHolder. Then we had to create an adapter that used that

ViewHolder. then we can finally use that adapter in our RecyclerView. When debating on

using RecyclerView or a plain ListView, generally choose the RecyclerView since it’s intended to replace

ListView. On the other hand, if you’re presenting a small, simple list, a ListView might fit your needs to

get that data presented quickly.

Page 62: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 62

Page 63: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 63

Introduction to SQLite Databases on Android Devices Hello World! In this post, we’re going to cover the basics of SQLite and databases. SQLite is the main

database backend that Android uses to manage complicated data. It provides more structure

and functionality than storing data in a file or anywhere else. Database backends are widely used to

store data locally on the device and sync with a web server, for example. But before we can do this, we

need to learn more about databases and SQLite, which defines it’s own “programming language” and

system. We’ll learn about what databases are and how to do basic CRUD (Create, Read, Update, and

Delete) operations with them in SQLite.

The database itself can be downloaded here.

Prerequisites It is highly recommended that this tutorial be followed on a UNIX-based operating system like Linux or

Mac OS X. You can download Ubuntu Linux here and a Virtual Machine here to run it on to prevent you

from going through the ordeal of dual-booting. While it’s certainly possible to do this whole tutorial on

Windows, the commands I’ll be using are UNIX bash commands so having access to a shell is ideal.

We’ll obviously need SQLite! You can download it here and find all kinds of great documentation on the

website. We just need the shell executable and not the analyzer. Unzipping the file will give the actual

executable. We’ll want to put it in a folder so we have access to it or we can copy it to a more useful

directory by running the following terminal command: sudo cp sqlite3 /usr/local/bin and we should be

able to access the executable from anywhere. We can test this by running sqlite3 --version and we

should get the current version of SQLite.

Page 64: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 64

What is a Database?

A database is an organized collection of information or data. More specifically, SQLite is a relational

database, meaning that each datum conforms to a highly-specific format or schema. We can visualize

databases as being giant tables, with potentially many rows and columns. However, databases are much

more powerful than just spreadsheets because we can do complicated queries to retrieve exactly what

data we want, subject to any number of constraints. More concretely, databases are just files that

hold this organized data.

Databases primarily consist of many tables; each table is defined by its columns. Each column needs a

name and a data type, much like in Java. Each table can then have many hundreds of rows, which each

row is a tuple whose elements correspond to the columns. Suppose I had a table whose columns were

simply an artist name and an album name, both as text data. Then an example of a row would be (“Led

Zeppelin”, “Led Zeppelin IV”). Note that the order that data appears in the tuple must correspond to the

order that columns were defined.

Let’s see what this looks like in action. Open up a terminal and navigate to any directory you want to

create the database file in. Then type sqlite3 my-db.sqlite and we should see the SQLite prompt like in

the following figure.

Page 65: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 65

Now that we have a blank database, we can create a table with a very specific schema. But before we do

that, we need more information on what the data types for SQLite columns. They’re enumerated in the

table below.

Page 66: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 66

In this post, we’ll only be using INTEGER, REAL and TEXT since they’re the most common, but NULL and

BLOB exist as well. These data types store exactly what you think they store based on their names:

INTEGER, REAL, TEXT. We’ll need to use them when declaring our table and columns. Let’s declare a

table called student with an ID, Name, Age, and GPA. This will illustrate using working with all of the

common data types. Type the following into SQLite:

1

2

3

4

5

6

CREATE TABLE student(

_id INTEGER,

name TEXT NOT NULL,

age INTEGER,

gpa REAL

);

The will create the table named students with the given schema. At any time, we can view all of

our tables by typing .tables and we can view the full schema for all tables by typing .schema . You’ll

notice that the name column has some additional properties. By putting NOT NULL after a column type,

we’re telling SQLite that any row inserted into this table must have a value for the name column. There

are more helpful properties that we’re going to get to later. You’ll also notice that we have this _id

column. It’s common practice to have some identification for each row so we can uniquely identify that

particular row for being deleted or updated, for example. Currently, we have to manage this uniqueness

ourselves, but when we talk about additional properties at the end of this post, we can actually have

SQLite manage this for us.

Page 67: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 67

Create Now that we have a table, let’s actually add some rows to it! To insert rows, we have to begin

a transaction since we’re modifying the database. We can query all we want, but if we’re adding new

rows, updating existing rows, or deleting rows, we need to use a transaction to do so. All transactions

begin with BEGIN; and end with COMMIT; and we’ll be wrapping all of our potential database changes

in these markers like so. Execute the following SQLite commands.

1

2

3

BEGIN;

INSERT INTO student(_id, name, age, gpa) VALUES(1, 'John Doe', 18, 3.81);

COMMIT;

Let’s talk about the insert statement. First we have to say what table we’re inserting rows into! Then

comes a comma-delimited list of columns in parentheses that we want to insert into and then the values

that we want to insert into those columns. After this, we should have our row inserted into the

database! We’ll learn how to read it later, but let’s add a few more rows and go over different styles of

insert statements.

The purpose of the above syntax is to specify that we’re going to be inserting exactly these values into

these columns of the table. If we’re going to provide values for each column, we can omit the comma-

separated list of columns. Execute the following statement:

1

2

3

BEGIN;

INSERT INTO student VALUES(2, 'Jane Doe', 20, 3.57);

COMMIT;

We can see that the columns are omitted and SQLite associates the first value with the first column and

so on. This is why the ordering of the columns in the table is important! It allows us to do this kind of

shorthand. In addition to this method of inserting, we can insert only values into particular rows.

Suppose we wanted to omit one’s age for privacy reasons. As long as that column isn’t marked with the

NOT NULL attribute, we can do something like the following. Execute the following statement:

1

2

3

BEGIN;

INSERT INTO student(_id, name, gpa) VALUES(3, 'John Smith', 3.38);

COMMIT;

Page 68: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 68

We can see that we omitted the age column so this row will not have an age if we were to query for it.

Note that the age isn’t simply zero; the age doesn’t exist! Now we have 3 rows in our database! Let’s

learn how to access these columns next.

Read Now that we have some data, let’s see how we can query for it. Let’s first retrieve all of rows in our only

table. Note that we’re not actually modifying the database, so we won’t need to use a transaction.

Instead, we can use a select statement. Execute the following statement: SELECT * FROM student; We

should see 3 rows where the columns are delimited by a pipe character |.

The star means to get all of the columns. We can choose to only retrieve specific columns by

replacing the asterisk in the select statement with comma-delimited columns names like SELECT name

FROM student; and we can only get all of the names. Now suppose we want to retrieve rows that fit a

criterion. We can add a where clause and search for more specific data like the following query that

Page 69: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 69

only retrieves student names who have a GPA of 3.5 or higher: SELECT name FROM student WHERE gpa

>= 3.5;

This only scratches the surface of the kinds of powerful queries we can do with databases!

Update Suppose we want to make a change to an existing row. We can do that by using the update statement.

For example, suppose John Smith did very well in his classes so we need to update his GPA. We can do

that using the following.

1

2

3

BEGIN;

UPDATE student SET gpa=3.52 WHERE _id=3;

COMMIT;

Note that this does change the database so we needed to use a transaction. You can see we use the

unique id of John to change his GPA. We could also have used the condition where name was John

Smith, or, better yet, we could use wildcard characters, but we won’t get into those in this post. After

the SET keyword, we could provide any number of columns to change, delimited by commas.

Any columns not in the list won’t be changed.

Delete Suppose we want to delete a row from our database. This is going to look similar to update, except we

won’t need any values. Suppose John Smith transferred to another school and we need to remove him

from our database.

1

2

3

BEGIN;

DELETE FROM student WHERE _id=3;

COMMIT;

The delete statement is fairly straightforward and will remove any row from our database that satisfies

the where clause.

Additional Properties I mentioned earlier that it’s common to have an ID column where each row can be identified uniquely.

We’ve been managing it ourselves, but we can have SQLite do this for us. This happens at database

creation though, so we’ll also learn how to safely transfer data between tables so we don’t lose all of

our users’ data! First, we’ll rename the old table and create the new one. You’ll notice that we now use

the additional attributes PRIMARY KEY and AUTOINCREMENT. The former means that this column holds

unique values for each row and the latter means to automatically increment this column if it isn’t given a

Page 70: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 70

specific value in the insert statement. Then we copy over all of our data and delete the old table. All of

this looks like the following:

1

2

3

4

5

6

BEGIN;

ALTER TABLE student RENAME TO tmp_student;

CREATE TABLE student (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER, gpa REAL);

INSERT INTO student SELECT * FROM tmp_student;

DROP TABLE tmp_student;

COMMIT;

Now we can use insert statements like INSERT INTO student(name, age, gpa) VALUES('Michael Smith',

20, 3.77) and there will be a new row with an ID that’s one greater than the previous row, even if that

row is deleted! We’re guaranteed unique values for rows and PRIMARY KEY helps to enforce that as

well.

This technique can be used whenever we want to change our table schema drastically. We can use

ALTER TABLE to rename our old table, create a new one with a new schema and copy over all of our old

data and remove the old table. This method is safe, secure, and prevents your users from losing all of

their data!

Conclusion In this post, we learned about relational databases (RDBs) and SQLite. We covered the data types of the

language and how to create tables. We then learned the basic create, read, update, and delete

(CRUD) operations that we can perform. Then we finished with some basic techniques and additional

modifiers. SQLite is the backend that Android’s ContentProviders use to store data and they can be

synced with data from web servers or other providers.

Page 71: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 71

How to Create Toolbars and Menus in Android Hello World! In this post, we’re going to talk about Toolbars from a design perspective and then we’ll

actually build an app that uses Toolbars. We’re all familiar with the top bar of an app that houses the

logo or name of the app as well as a navigation drawer perhaps. One of the most prominent items on

that top bar are the actions and the action overflow menu! We’re going to cover how we can create this

Toolbar and put actions on it!

Download the source code for this post here. You’ll need some of the resources in the project later on!

Before we get into the source code for building menus, I want to take a short bit of time to think about

our toolbar actions and do some design instead of jumping straight into developing. We’ll be focusing on

the actions that can go on the Toolbar.

When considering whether or not an action should go on the Toolbar, follow the FIT principle. If an

action is Frequent, Important, or Typical, it should go on the Toolbar. By Frequent, ask yourself, will

people use this action almost every time they come to this screen? For example, in a social media app,

the action to publish a new post would definitely be Frequent. By Important, ask yourself, does this

action align with the main purpose of my app? For example, in an email app, composing a new email is

absolutely important and the entire point of the app! By Typical, ask yourself, given the context of this

screen, would it be strange if this action were missing or hidden somewhere? For example, in a photo

editing app, users would be surprised if the ability to edit photos were hidden away in the action

overflow.

If you’ve answered yes to any of these questions, put that action in the Toolbar! Keep the number

of actions on the Toolbar to a minimum so that your app looks very clean and fresh. Nothing puts off of

your app than a million items on a small Toolbar!

Now that we’ve thought carefully about the design of our toolbar, let’s actually begin developing one!

Let’s create a project in Android Studio and call it ToolbarDemo. We’ll just need a blank Activity called

MainActivity. We’re going to create a quick ListView for the sake of having some content. If you’d like to

know more about ListViews in-depth, check out the blog post on simple ListViews. Anyways, let’s open

up res/values/strings.xml and add the following code block to serve as our main content for the

ListView:

1

2

3

4

5

<string-array name="countries_array">

<item>Afghanistan</item>

<item>Albania</item>

<item>Algeria</item>

<item>American Samoa</item>

Page 72: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 72

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

<item>Andorra</item>

<item>Angola</item>

<item>Anguilla</item>

<item>Antarctica</item>

<item>Antigua and Barbuda</item>

<item>Argentina</item>

<item>Armenia</item>

<item>Aruba</item>

<item>Australia</item>

<item>Austria</item>

<item>Azerbaijan</item>

<item>Bahrain</item>

<item>Bangladesh</item>

<item>Barbados</item>

<item>Belarus</item>

<item>Belgium</item>

<item>Belize</item>

<item>Benin</item>

<item>Bermuda</item>

<item>Bhutan</item>

<item>Bolivia</item>

<item>Bosnia and Herzegovina</item>

<item>Botswana</item>

<item>Bouvet Island</item>

<item>Brazil</item>

<item>British Indian Ocean Territory</item>

<item>British Virgin Islands</item>

Page 73: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 73

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

<item>Brunei</item>

<item>Bulgaria</item>

<item>Burkina Faso</item>

<item>Burundi</item>

<item>Cambodia</item>

<item>Cameroon</item>

<item>Canada</item>

<item>Cape Verde</item>

<item>Cayman Islands</item>

<item>Central African Republic</item>

<item>Chad</item>

<item>Chile</item>

<item>China</item>

<item>Christmas Island</item>

<item>Cocos (Keeling) Islands</item>

<item>Colombia</item>

<item>Comoros</item>

<item>Congo</item>

<item>Cook Islands</item>

<item>Costa Rica</item>

<item>Cote d\'Ivoire</item>

<item>Croatia</item>

<item>Cuba</item>

<item>Cyprus</item>

<item>Czech Republic</item>

<item>Democratic Republic of the Congo</item>

<item>Denmark</item>

Page 74: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 74

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

<item>Djibouti</item>

<item>Dominica</item>

<item>Dominican Republic</item>

<item>East Timor</item>

<item>Ecuador</item>

<item>Egypt</item>

<item>El Salvador</item>

<item>Equatorial Guinea</item>

<item>Eritrea</item>

<item>Estonia</item>

<item>Ethiopia</item>

<item>Faeroe Islands</item>

<item>Falkland Islands</item>

<item>Fiji</item>

<item>Finland</item>

<item>Former Yugoslav Republic of Macedonia</item>

<item>France</item>

<item>French Guiana</item>

<item>French Polynesia</item>

<item>French Southern Territories</item>

<item>Gabon</item>

<item>Georgia</item>

<item>Germany</item>

<item>Ghana</item>

<item>Gibraltar</item>

<item>Greece</item>

<item>Greenland</item>

Page 75: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 75

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

<item>Grenada</item>

<item>Guadeloupe</item>

<item>Guam</item>

<item>Guatemala</item>

<item>Guinea</item>

<item>Guinea-Bissau</item>

<item>Guyana</item>

<item>Haiti</item>

<item>Heard Island and McDonald Islands</item>

<item>Honduras</item>

<item>Hong Kong</item>

<item>Hungary</item>

<item>Iceland</item>

<item>India</item>

<item>Indonesia</item>

<item>Iran</item>

<item>Iraq</item>

<item>Ireland</item>

<item>Israel</item>

<item>Italy</item>

<item>Jamaica</item>

<item>Japan</item>

<item>Jordan</item>

<item>Kazakhstan</item>

<item>Kenya</item>

<item>Kiribati</item>

<item>Kuwait</item>

Page 76: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 76

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

<item>Kyrgyzstan</item>

<item>Laos</item>

<item>Latvia</item>

<item>Lebanon</item>

<item>Lesotho</item>

<item>Liberia</item>

<item>Libya</item>

<item>Liechtenstein</item>

<item>Lithuania</item>

<item>Luxembourg</item>

<item>Macau</item>

<item>Madagascar</item>

<item>Malawi</item>

<item>Malaysia</item>

<item>Maldives</item>

<item>Mali</item>

<item>Malta</item>

<item>Marshall Islands</item>

<item>Martinique</item>

<item>Mauritania</item>

<item>Mauritius</item>

<item>Mayotte</item>

<item>Mexico</item>

<item>Micronesia</item>

<item>Moldova</item>

<item>Monaco</item>

<item>Mongolia</item>

Page 77: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 77

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

<item>Montenegro</item>

<item>Montserrat</item>

<item>Morocco</item>

<item>Mozambique</item>

<item>Myanmar</item>

<item>Namibia</item>

<item>Nauru</item>

<item>Nepal</item>

<item>Netherlands</item>

<item>Netherlands Antilles</item>

<item>New Caledonia</item>

<item>New Zealand</item>

<item>Nicaragua</item>

<item>Niger</item>

<item>Nigeria</item>

<item>Niue</item>

<item>Norfolk Island</item>

<item>North Korea</item>

<item>Northern Marianas</item>

<item>Norway</item>

<item>Oman</item>

<item>Pakistan</item>

<item>Palau</item>

<item>Panama</item>

<item>Papua New Guinea</item>

<item>Paraguay</item>

<item>Peru</item>

Page 78: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 78

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

<item>Philippines</item>

<item>Pitcairn Islands</item>

<item>Poland</item>

<item>Portugal</item>

<item>Puerto Rico</item>

<item>Qatar</item>

<item>Reunion</item>

<item>Romania</item>

<item>Russia</item>

<item>Rwanda</item>

<item>Sqo Tome and Principe</item>

<item>Saint Helena</item>

<item>Saint Kitts and Nevis</item>

<item>Saint Lucia</item>

<item>Saint Pierre and Miquelon</item>

<item>Saint Vincent and the Grenadines</item>

<item>Samoa</item>

<item>San Marino</item>

<item>Saudi Arabia</item>

<item>Senegal</item>

<item>Serbia</item>

<item>Seychelles</item>

<item>Sierra Leone</item>

<item>Singapore</item>

<item>Slovakia</item>

<item>Slovenia</item>

<item>Solomon Islands</item>

Page 79: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 79

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

<item>Somalia</item>

<item>South Africa</item>

<item>South Georgia and the South Sandwich Islands</item>

<item>South Korea</item>

<item>South Sudan</item>

<item>Spain</item>

<item>Sri Lanka</item>

<item>Sudan</item>

<item>Suriname</item>

<item>Svalbard and Jan Mayen</item>

<item>Swaziland</item>

<item>Sweden</item>

<item>Switzerland</item>

<item>Syria</item>

<item>Taiwan</item>

<item>Tajikistan</item>

<item>Tanzania</item>

<item>Thailand</item>

<item>The Bahamas</item>

<item>The Gambia</item>

<item>Togo</item>

<item>Tokelau</item>

<item>Tonga</item>

<item>Trinidad and Tobago</item>

<item>Tunisia</item>

<item>Turkey</item>

<item>Turkmenistan</item>

Page 80: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 80

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

<item>Turks and Caicos Islands</item>

<item>Tuvalu</item>

<item>Virgin Islands</item>

<item>Uganda</item>

<item>Ukraine</item>

<item>United Arab Emirates</item>

<item>United Kingdom</item>

<item>United States</item>

<item>United States Minor Outlying Islands</item>

<item>Uruguay</item>

<item>Uzbekistan</item>

<item>Vanuatu</item>

<item>Vatican City</item>

<item>Venezuela</item>

<item>Vietnam</item>

<item>Wallis and Futuna</item>

<item>Western Sahara</item>

<item>Yemen</item>

<item>Yugoslavia</item>

<item>Zambia</item>

<item>Zimbabwe</item>

</string-array>

Before we go editing the view, we need to configure some things regarding styles first. Open up

res/values/styles.xml. In this file, we can configure any special properties that we want our app to have.

In our case, we need to remove the system-provided action bar so we can use the more flexible Toolbar

widget. In order to do this, we need to add a few properties to this file. The end result should look like

the following.

Page 81: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 81

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<resources>

<!-- Base application theme. -->

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

<!-- Customize your theme here. -->

<item name="colorPrimary">@color/colorPrimary</item>

<item name="colorPrimaryDark">@color/colorPrimaryDark</item>

<item name="colorAccent">@color/colorAccent</item>

<item name="windowActionBar">false</item>

<item name="windowNoTitle">true</item>

</style>

</resources>

Now that we’ve added that, let’s go into our main layout in res/layout/activity_main.xml. We need to

position our Toolbar before our ListView, and, in accordance to Material Design, it should be above our

ListView as well. The best layout to accomplish our task is the LinearLayout. We can declare one as the

top-level element and set its orientation to be vertical so we can put our Toolbar first, then our ListView

after it. Replace the contents of the layout file with the following:

1

2

3

4

5

6

7

8

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

tools:context=".MainActivity"

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent">

Page 82: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 82

9

10

11

12

13

14

15

16

17

18

19

20

21

<android.support.v7.widget.Toolbar

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:minHeight="?attr/actionBarSize"

android:elevation="4dp"

android:background="@color/colorPrimary"/>

<ListView

android:layout_width="match_parent"

android:layout_height="match_parent"

android:id="@+id/listView" />

</LinearLayout>

You can see that we have a minHeight and a layout_height. By including both properties, we can let

our Toolbar grow in size, like on tablet layouts, but not be less than the Material Design guideline for

size. This helps us achieve the best of both worlds. The question mark syntax queries the system’s value

of actionBarSize and sets our Toolbar’s minHeight to be in accordance with what the system uses. This

enforces conformity among apps, which is always good for your user!

We can use the elevation property on the Toolbar so that it appears to be “above” the ListView. All of

the shadows will be drawn for us! Toolbars also need to have a color: the primary color of our

application. Each application, according to Material Design, has a primary color for the most common

elements, a dark primary color for the status bar, and an accent color for EditText underlines and other

smaller elements. The Toolbar is definitely a primary element so we should have it’s background be our

primary color. We can change these colors by editing the res/values/colors.xml file. Now that this is

configured, we should see a view similar to below if we click on the design tab.

Page 83: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 83

Now we can start populating our ListView, and, to make it interesting, let’s add listener so that our app

displays a Toast message when the user clicks on an ListView item! Add the following code

to the MainActivity class.

1

2

3

4

5

6

7

8

9

private ListView listView;

private ArrayAdapter<CharSequence> adapter;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Page 84: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 84

10

11

12

13

14

15

16

17

18

19

listView = (ListView) findViewById(R.id.listView);

adapter = ArrayAdapter.createFromResource(this, R.array.countries_array, android.R.layout.simple_list_item_1);

listView.setAdapter(adapter);

listView.setOnItemClickListener(this);

}

@Override

public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {

Toast.makeText(this, adapter.getItem(position), Toast.LENGTH_SHORT).show();

}

Now let’s run our app we should see a very simple app with a populated ListView. But now let’s get

more into actually using the Toolbar. Let’s add a refresh menu item to the Toolbar and have it also

display a Toast message.

One of the best ways to do this is to create an XML file that describes our menu. Right-click on the res

folder and select New → Android resource directory. In the dialog that appears, select menu under

Resource type and click OK. A new folder should be in the res directory called menu. Right-click on that

and go to New → Menu resource file. We’ll call it toolbar.xml. Before we can declare this item, we need

an app icon for it! Download the source code (link is at the beginning of this post!) and navigate to

ToolbarDemo/app/src/main/res/drawable and there should be an icon called

ic_refresh_white_48dp.png. Copy this into your own drawable folder in your project (exact same path).

You should see it in Android Studio because the drawable folder will be populated now. As a side note,

Google has a ton of free material design icons that you are free to download and use! This is where I

originally got the refresh icon. You can download this library of icons here! Now that we have an icon,

let’s go back to our toolbar.xml menu and replace the contents with the following.

1

2

3

4

5

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto">

<item android:id="@+id/action_refresh" android:title="Refresh" android:icon="@drawable/ic_refresh_white_48dp" app:showAsAction="ifRoom" />

</menu>

Page 85: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 85

You’ll notice that we needed to declare another namespace app so that AppCompat can make our app

backwards compatible, particularly for the showAsAction attribute. This attribute tells Android in what

circumstances to put this action at different places on the Toolbar: always visible, only visible if there’s

room, or put it in the action overflow menu (three vertical dots on the far right of the Toolbar) Now

we’ve declare a menu item with an ID of action_refresh. It’s common to prefix IDs for menu actions with

action_. We’ve also given it a text title and set it’s icon to be the image we just put in our drawable

folder.

This is all it takes to define a menu! Now we can tell our Toolbar to inflate this menu. We’re also going

to wire it to an action as well: display the Toast message! It would also be nice if we could add a custom

title and color to our Toolbar as well. Let’s go back to the MainActivity class and set some properties on

our Toolbar programmatically. Inside of the onCreate(Bundle) method, let’s add the following lines of

code after we configure the ListView.

1

2

3

4

5

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

toolbar.setTitleTextColor(Color.WHITE);

toolbar.setTitle("ListViewDemo");

toolbar.inflateMenu(R.menu.toolbar);

toolbar.setOnMenuItemClickListener(this);

In this code snippet, we grab a reference to the Toolbar and set the title and its color. We also inflate

that menu we were just editing and set the listener. Android Studio will want us to handle the listener so

Alt+Enter at the error and allow MainActivity to implement the handler interface. Inside, we need to

make sure that we only display the Toast if we clicked on the item whose ID matches the ID of the

refresh action. To make this future-proof (in case we decide to add more actions later), we can use a

switch-case statement. Add the following to the onMenuItemClick(MenuItem) method.

1

2

3

4

5

6

@Override

public boolean onMenuItemClick(MenuItem item) {

switch (item.getItemId()) {

case R.id.action_refresh:

Toast.makeText(this, "Refreshing...", Toast.LENGTH_SHORT).show();

return true;

Page 86: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 86

7

8

9

10

default:

return false;

}

}

Now we can run our app and see the results below!

Conclusion In this post, we learned how to use Toolbars and Menus. We covered some of the design considerations

for adding actions to the Toolbar. Actions must be either Frequent, Important, or Typical. We created

our own Toolbar and populated it with an action. We even set up an event listener for that action as

well. As a reminder, Google has a ton of free material design icons for all platforms that you can use in

your apps!

Page 87: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 87

How to Use Contextual Toolbar and ActionBar in Android Hello World! In this post, we’re going to be covering contextual toolbars/action bars. They are a

structure that will allow us to change the menu items on the toolbar based on the user’s context.

Suppose we were looking at our email in the Inbox or Gmail app and wanted to delete an email. We

could tap on the email in the list and then click the delete icon in the Toolbar, or we could long-press on

the email in the list and the menu items in our Toolbar change! The context is the list of selected emails.

What can we do with a list of emails? We can delete them, mark them to be unread, archive them, etc.

This the contextual toolbar at work! We’re going to be adding on from our previous app on Toolbars and

Menus.

Note: Before reading too much into this post, you should look at the other post on Toolbars and Menus.

We’re going to be building off of the same app! The source code for this post can be downloaded here.

You’ll need an icon in it so make sure you download it!

Side Note: To save text, I’m going to be abbreviating the contextual Toolbar as CAB, which actually

stands for Contextual Action Bar. However, we’ll be using Toolbars instead of the system action bar

because it gives us the flexibility we need to implement Material Design.

Let’s open up the previous app and make sure it works. We should see a list with all of the countries and

a refresh icon on the Toolbar. We’ll need to add another icon to our drawable folder so follow the same

process as before: copy over everything in CABDemo/app/src/main/res/drawable/ folder and copy it to

your project’s drawable folder. We’ll get a new icon that we can use in the toolbar’s context menu.

Speaking of context menu, let’s create another menu XML file to serve as the menu that will be inflated

when the CAB activates. Let’s right-click on the menu folder and create a new menu resource XML file

called toolbar_cab.xml. Put the following in the file:

1

2

3

4

5

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto">

<item android:id="@+id/action_delete" android:title="Delete" android:icon="@drawable/ic_delete_white_48dp" app:showAsAction="ifRoom" />

</menu>

This is similar to the previous menu with the exception of the icon and the ID. Now we can use this when

we start the Toolbar’s contextual action mode. However, before we can get to this, we need to set

another property in the styles.xml file to prevent the CAB from being stacked on top of the existing one

like in the following image!

Page 88: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 88

We want the CAB to be an overlay on top of our existing Toolbar. Let’s open up the styles.xml file and

append the following line after the windowNoTitle attribute: <item

name="windowActionModeOverlay">true</item> . This will give us the desired result of having the

action mode overlayed on top of the existing Toolbar.

Now that we’ve handled everything there is to do regarding resources, let’s get to the code. We’re going

to have to rethink our approach when it comes to our list because of one critical fact: ArrayAdapter’s

internal representation of a list is immutable! We’re not allowed to delete items from the ArrayAdapter

so we need to think of another way to do this. Luckily, we can use Java’s aliasing to our benefit. Instead

of using the utility method on ArrayAdapter, we’re going to grab an ArrayList and pass that reference

to ArrayAdapter. It’s important that we use an ArrayList because they are completely mutable. Keep in

mind that not all implementing classes of the List interface are mutable! In specific, we’ll use an

ArrayList. This way, we can make changes to the underlying list that the adapter displays. Then we can

call a method on the adapter called notifyDataSetChanged() that will refresh our main ListView. This

works because when we set the adapter, the ListView registers itself as a listener to the adapter for

some methods. Therefore, when the adapter calls that method, the ListView knows to refresh itself

because it’s underlying adapter changed. We can also use this to implement refresh functionality by

“resetting” our adapter by “resetting” our list by clearing it and adding back a permanent copy of all of

the countries.

Let’s begin implementing this fix by adding member variables for the list of current countries and a list of

countries that are queued up for deletion:

1

2

3

4

private ListView listView;

private ArrayAdapter<String> adapter;

private ArrayList<String> toDelete;

private ArrayList<String> countries;

Page 89: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 89

The final two variables we’ll need to keep track of countries to be deleted in the action mode and a

running list of countries that may not or may not have all of the countries. Now that we’ve done this,

let’s make corresponding changes in our onCreate(Bundle) to initialize these ArrayLists and use a

constructor for our adapter instead of the utility method.

1

2

3

4

toDelete = new ArrayList<>();

countries = new ArrayList<>(Arrays.asList(getResources().getStringArray(R.array.countries_array)));

adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_activated_1, countries);

listView.setAdapter(adapter);

That constructor parameter is simply fetching the array from our app’s resources and converting it into a

List, then an ArrayList, more specifically. Now that we have this new approach, let’s change more code

in our onMenuItemClick(MenuItem) method so that the refresh functionality actually works!

1

2

3

4

5

6

7

8

9

10

11

12

13

@Override

public boolean onMenuItemClick(MenuItem item) {

switch (item.getItemId()) {

case R.id.action_refresh:

Toast.makeText(this, "Refreshing...", Toast.LENGTH_SHORT).show();

countries.clear();

countries.addAll(Arrays.asList(getResources().getStringArray(R.array.countries_array)));

adapter.notifyDataSetChanged();

return true;

default:

return false;

}

}

Page 90: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 90

What we’re doing in this code snippet is clearing out the current list of countries so it becomes an empty

list. Then we’re adding back all of the countries. Finally, we’re telling our adapter that our data set has

changed and it will tell our ListView to refresh.

Now that we’ve added that core functionality, let’s actually get to the part where we’re going to start

our action mode. We can do this in two different ways: register a listener with our ListView to listen for

long presses and call Activity’s startActionMode(…) and pass in MainActivity as a listener, or we can take

advantage of ListView and use it’s setMultiChoiceModeListener(…) to start the action mode

automatically for us. To do this, we first need to tell our ListView to allow the user to select multiple

items and enter the action mode at the same time. Then we can set this activity to be the listener

and implement those methods. In our onCreate(Bundle) , let’s type in the following code.

1

2

listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);

listView.setMultiChoiceModeListener(this);

The last line will make our activity implement the MultiChoiceModeListener interface so we’ll have to do

that. The first method we need to implement is the one that actually inflates the menu!

1

2

3

4

5

6

@Override

public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {

MenuInflater menuInflater = getMenuInflater();

menuInflater.inflate(R.menu.toolbar_cab, menu);

return true;

}

We can grab a MenuInflater object from our Activity class and very simply inflate the XML file of the

menu into the menu object. Note that we have to return true so the action mode knows we’re

doing work in this method. In onPrepareActionMode(...) , it’s OK for us to return false since we’re not

doing any work in that method. Next, we need to implement the method that will handle list items

being checked and unchecked.

1 @Override

Page 91: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 91

2

3

4

5

6

7

8

public void onItemCheckedStateChanged(ActionMode actionMode, int position, long id, boolean checked) {

if (checked) {

toDelete.add(adapter.getItem(position));

} else {

toDelete.remove(adapter.getItem(position));

}

}

The implementation is simple: if this item is checked, then add it to the list to be deleted! We also need

the other condition of the list item being unchecking. However, we don’t need any more

contingencies since our design guarantees us that if a ListView item is passed in with the checked flag as

false, it must be true that it is in our list since it had to have been checked at some point. Next, we can

move on to the method that actually deletes the items. We also have a method that is called when the

action mode is finished.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@Override

public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {

switch (menuItem.getItemId()) {

case R.id.action_delete:

for (String item : toDelete) {

countries.remove(item);

}

actionMode.finish();

return true;

default:

return false;

}

}

Page 92: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 92

15

16

17

18

@Override

public void onDestroyActionMode(ActionMode actionMode) {

toDelete.clear();

}

Our implementation looks strikingly similar to when we implemented the Toolbar’s menu items and it’s

intended to be that way. If the delete action was tapped, then we need to iterate through all of the

items in the queue of items to delete and remove them from our list of current countries. Then we

actually need to end the action mode! Regarding the method that’s called when the action mode is

finished, we need to clear our queue of items to delete every time the user exits the action mode.

Page 93: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 93

Now we’re finished with our implementation and we can run our app! When we long-press on a

ListView item, we should see the CAB overlay on top of our Toolbar and we should be able to delete

items now! If we’ve removed countries, we can always add them back again by pressing the refresh

button and our ListView should reset!

Conclusion In this post, we learned how to use the contextual Toolbar/action bar to change the menu items based

on the context of the user. We did this by declaring another menu item and inflating that when

the action mode begins. We also learned more about ArrayLists and dealing with immutable and

Page 94: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 94

mutable lists as well. Overall, we created an app changes the menus when the user long-presses on a

country, allow them to delete it. Changing our view to suit the user’s context is always beneficial to your

user!

Page 95: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 95

How to get the User Location in Android Tutorial Hello world! In this post, we’re going to learn how we can use Google Play Services to access the user’s

location. Along with that, we’re also going to learn how to use Android Marshmallow’s new runtime

permissions to ask the user for location permission at runtime instead of when they download your app.

We’ll be building off of an existing application from a previous post here. In that post, we learned how

to access the Internet and pull weather data from OpenWeatherMap given a specific latitude and

longitude. We’re going to extend that app, and, instead of providing a latitude and longitude, the system

will grab the user’s last known location and we’ll use that as the location to send to OpenWeatherMap!

Download the source for this project here.

Let’s get started! From the previous mentioned post, run NetworkDemo to double-check that it still

works. We’re going to be adding location functionality in this app to grab the user’s location and send it

to OpenWeatherMap instead. However, before we do that, we can’t just grab the user’s location

without their permission!

The permission model took a new turn in Android 6.0 Marshmallow to an approach similar to iOS: ask

for permission only when needed! In the old Android permission model, developers would post all of

the permissions that their app used in the AndroidManifest. When they published their app, users could

see all of the permissions that a particular app required on the Play Store. The downside was that before

users could install the app, they had to agree to grant the app all of the permissions it requested.

Concern arose when simple “Flashlight” apps requested Internet, camera, or audio permissions. Users

didn’t like this as they had to debate whether or not to install a particular application based on that one

suspicious condition. Browsing through the Play Store, users had to decide whether it was worth the risk

of downloading a simple app that, for some reason, needed access to your camera.

The old permission model also promoted bad practices for developers as well. If your app tried to access

some data without the appropriate permission, Android would just crash your app. This can get

annoying if you keep forgetting to add permissions. To remedy this headache, instead of

carefully thinking what about permissions their app really needs, developers would just add all of the

permissions or much more than necessary so that they could develop more seamlessly. When they

would go to publish, their app would have many unnecessary permissions that users wouldn’t be

comfortable with so developers lose user installs and wonder why!

Starting in Android 6.0 Marshmallow, we now have runtime permissions that developers must declare

in both the manifest (partly for backwards compatibility) and request them at runtime. This forces

developers to only include the permissions they need and gives the users more freedom and security in

limiting what your app can do. For example, take the Google Keep app. We can add audio or images to a

note, but those permissions aren’t enabled at first. The first time a user clicks on the audio button, the

app asks the user whether or not they have permission to access the device’s microphone. Should the

user say yes, then the appropriate action occurs. However, if the user declines, we can just disable the

functionality that requires that permission. For example, if I didn’t want Keep to access my microphone,

Page 96: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 96

I wouldn’t be able to take audio notes until I tap the audio icon again and accept the permission. Also,

we can decide when to ask again, as long as we don’t pester the user about accepting a permission.

We’ll generally want to ask the user for permission when we need it with one exception: if the

permission is central to our app, then we can request it right at the start. If the user declines, we should

show some rationale as to why this permission is central to our app. Hopefully, this won’t be the case

since our app’s purpose will be clear enough that users will understand why we need a particular

permission.

In our case, location is obviously central to our application so we can just request our permission in

onCreate(...) . Add the following code to the method.

1

2

3

4

5

if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)

!= PackageManager.PERMISSION_GRANTED) {

ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.ACCESS_COARSE_LOCATION },

PERMISSION_ACCESS_COARSE_LOCATION);

}

What we’re doing is first checking to see if the coarse permission location isn’t already granted. If it isn’t

then we need to request it. We also need to give it a constant as an identifier in the callback method.

We need a callback method as a check the result of the request. This is called

onRequestPermissionResult(...) and we need to override it as the following.

1

2

3

4

5

6

7

8

9

@Override

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

switch (requestCode) {

case PERMISSION_ACCESS_COARSE_LOCATION:

if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

// All good!

} else {

Toast.makeText(this, "Need your location!", Toast.LENGTH_SHORT).show();

}

Page 97: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 97

10

11

12

13

break;

}

}

We perform a switch-case on the request code and check if the resulting array is greater than zero. If so,

we check if the first (and only) permission was granted. If so, we’re good to go! If not, then we tell the

user. As I mentioned before, there are more robust ways of doing this, but this method will suffice for

now.

Now that we have permission to grab the user’s location, let’s actually do that and send it to

OpenWeatherMap. We’ll have to refactor our existing code, but we first need to learn how to get

location. The location APIs are now integrated with Google Play Services and made backwards-

compatible all the way back to Android 2.2 Froyo devices. We also have a new FusedLocationProvider

that will automatically select the best method of ascertaining the user’s location: either WiFi or GPS. It’s

also very easy to use, but we’ll need to make sure we have the Google Play Services support library and

add it to our Gradle build file. Open up the SDK manager and go to the SDK Tools tab. Download the

latest version of Google Play services. Afterwards, expand the Gradle Scripts item in Android

Studio’s Project Explorer on the left. Double-click the build.gradle file for the app module, NOT FOR THE

PROJECT! In the dependencies code block, add the following line: compile

'com.google.android.gms:play-services:8.3.0' . Replace the version number with the most recent one.

This will give us access to Google Play services and the FusedLocationProvider API.

Now let’s go back to our MainActivity.java file. Let’s declare a field for the Google Play Services API client

and instantiate it on onCreate(...) like the following.

1

2

3

4

5

6

7

8

...

private GoogleApiClient googleApiClient;

...

@Override

protected void onCreate(Bundle savedInstanceState) {

...

Page 98: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 98

9

10

11

googleApiClient = new GoogleApiClient.Builder(this, this, this).addApi(LocationServices.API).build();

}

We create a new client through the means of a builder inner class. The first parameter is the Context

and the next two parameters are callbacks for when the connection succeeded, was suspended, or

failed. Then we add the location services API and finally call build() . However, now that we have the

client, we need to connect it when we need to use location and disconnect it when we’re not using

location to conserve system resources. Ideal places to do this are the onStart() and

onStop() methods. The former is called before the Activity is visible on screen and the latter is called

after the Activity leaves the screen. These won’t be called when a dialog or other view partially blocks

the current activity, else we’d be connecting and disconnecting very frequently and wasting even more

resources! Override those lifecycle methods and add the following code inside them to connect and

disconnect the API client.

1

2

3

4

5

6

7

8

9

10

11

12

13

@Override

protected void onStart() {

super.onStart();

if (googleApiClient != null) {

googleApiClient.connect();

}

}

@Override

protected void onStop() {

googleApiClient.disconnect();

super.onStop();

}

Now that we have the connection set up, we can look at the most important method for Google Play

services: onConnected(...) . This method is called when we’ve successfully connected to Google Play

Page 99: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 99

services. Beyond this point, we can use any of the APIs we declared when we were building the

object. We should first check if the user gave the permission to use location services in the same fashion

as the onRequestPermissionsResult(...) method. Then we can get the user’s last known location and run

the code to fetch the weather. We can implement the method like the following.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@Override

public void onConnected(Bundle bundle) {

if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)

== PackageManager.PERMISSION_GRANTED) {

Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);

double lat = lastLocation.getLatitude(), lon = lastLocation.getLongitude();

String units = "imperial";

String url = String.format("http://api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&units=%s&appid=%s",

lat, lon, units, APP_ID);

new GetWeatherTask(textView).execute(url);

}

}

Notice that we can retrieve the user’s last location very simply using the FusedLocationAPI. We then

extract the latitude and longitude from the Location object and execute the task. Note: we know need a

field that store the main textView of the screen so that we can grab a reference to the textView in

onCreate(...) for efficiency reasons. We can do this using standard procedure: textView = (TextView)

findViewById(R.id.textView); .

There’s just one last thing we have to do before we can run this application. We need to make sure our

emulator supports Google Play services. We can do this by opening up the SDK manager once more and

downloading a system image that says “Google APIs” in the title. Create a new AVD from that system

image and we should be good to go! After we’ve done all of this, we should have a complete

application and it will ask for your location and then display the current weather at that latitude and

longitude! Here are some screenshots below.

Page 100: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 100

Page 101: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 101

Conclusion In this post, we learned about Android Marshmallow’s new runtime permissions model that asks the

user for permission only when needed, not all up front. We also covered how to connect to Google Play

Services. Many of Android’s newer APIs, like location services, will require the Google Play Services

configuration. Finally, we used the FusedLocationProvider API to gain access the the user’s last known

location and sent that through to OpenWeatherMap to give the user the current weather at their

current location.

Page 102: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 102

Beginners Guide to Material Design In this post, we’re going to learn all about Google’s design philosophy dubbed Material Design. We’re

going to cover some of the fundamental concepts behind Material Design and will later learn how to

realized our design. We’ll be discussing just some of the basics behind the essence of Material Design,

like elevation, colors, and layouts. Note that we’ll only be covering a very small amount of what Material

Design actually is so if you want to learn more, check the link at the bottom of the post for more

information on Google’s Material Design.

In most development settings, we have both developers and designers. The designer’s purpose is to

think about how the user can get the best experience on a product or service. They do market research

on other products, mockups, and even focus groups. One of the most important thing designers

are responsible for are the wireframe mockups and workflow diagrams. They define our application’s

entire purpose and give the developers a bird’s eye view on all of the screens and elements they’ll have

to deal with. When thinking about an app idea, they come up with flows for different scenarios or use-

cases. For example, think about a note-taking app and let’s explore one such use-case. Suppose we have

our character, let’s call him Jim, talking with his boss at work. His boss mentions that Jim needs to file

reports to him by 3:00PM on Friday and that they must be filed in alphabetical order as well. Jim opens

up our note-taking app on his phone and puts all of that information in there, including the due date and

the notes. This may seem like a silly example, but it’s a perfectly valid use-case. From this, we know that

our note-taking app should have a way to quickly enter in notes so the user doesn’t spend too much

time trying to figure out how to work with the app. In other words, we also want to make our app as

intuitive as possible. Furthermore, we want our user to feel comfortable in our app, regardless of the

platform he or she is using it on, i.e. phone, tablet, desktop.

Although there are variations in intuitiveness, Google’s Material Design aims to provide a combined user

experience across all sorts of devices. If you see a particular icon on a phone app, you can be pretty

certain that it’ll mean the same thing on the desktop app and the web app. By unifying the experience

across all devices, this allows users to be more familiar with an app and spend less time trying to figure it

out. Material Design provides a clean interface that users can intuitively interact with and expect that

same level of interaction on all of their different devices. As developers, we also need to have an

appreciation for this design as well as the knowledge on how to implement or realize it. Let’s get right to

some of the key topics in Material Design!

Page 103: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 103

(Source: Google’s Material Design website)

One of the most important facets of Material Design is the fact that we have three axes we can work

with instead of two! We have our fundamental plane that is the phone’s screen, but Material Design

adds the z-axis to be increasing as the element moves “above” the screen. When we have material that

is “above”, we can denote this by having a shadow that gives the impression that a particular element is

at a different elevation than those around it. Take the floating action button (or FAB for short) for

example. Note that it has a noticeable drop shadow around it and it gives the impression that it is

“above” the rest of the screen.

Page 104: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 104

We define different elevations for different UI elements based on importance. For example, the FAB’s

resting elevation is 6dp. In addition to a resting elevation, we have a raised elevation that is activated

when a UI element is pressed. This signifies to the user that there’s interaction happening. The raised

elevation of the FAB is 12dp. It gives the impression that the FAB is “rising” to meet the user. As

mentioned before however, the system can do most of this for us, particularly rendering the drop

shadows. These numbers come in handy because in our views, we have that elevation attribute that we

will assign appropriate elevations too. Not everything in material design has an elevation!

The next aspect of Material Design is the bright and bold color scheme. Google has provided us with a

giant list of different colors and shades that we can use right here. There are several colors that we need

to pick, particularly a primary and accent color. The primary color is intended to be the 500 value of a

particular color. The status bar has to be a darker shade of the particular color, the 700 value of our

primary color. In addition, we can define an accent color. Notice that the colors have a bottom section

that starts with A###. For the accent color, we’ll use the A200 value of a complimentary color with a

good contrast from our primary color. The accent color will be used for things like EditText

underlines and other subtile places to add the bold color signature that is Material Design. This is why it

needs to have a good contrast, so that we can overlay it on top of the primary color and users will be

able to see the difference instead of the text being difficult to read.

It’s helpful to place these hexadecimal values in a file called colors.xml. The default colors.xml file when

we create a project looks like the following.

Page 105: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 105

1

2

3

4

5

6

<?xml version="1.0" encoding="utf-8"?>

<resources>

<color name="colorPrimary">#3F51B5</color>

<color name="colorPrimaryDark">#303F9F</color>

<color name="colorAccent">#FF4081</color>

</resources>

Notice that we have a primary color (the 500 value), a dark primary color (the 700 value), and an accent

color (the A200 value of a different, complimentary color). The hex values can either be in uppercase or

lowercase. If we wanted to change our colors, we can just copy-and-paste values from the above

webpage. Overall, colors help to better define our brand and promote our product. Take Evernote for

example. When we see the icon and the green background, our mind immediately associates this with

being Evernote. As another example, take Apple. We immediately recognize the brand by the white icon

that looks like an apple with a bite taken out and a leaf. Hopefully these examples illustrate the power of

branding our product/service.

We’re going to shift our design perspective a bit towards development and talk about keylines. We can

think of all Android layouts to conform to a baseline grid of density-independent pixels which scale

based on the actual density of the device our app runs on (hence the density-independent part). Keylines

are critical margins that we have to consider when we’re building a layout. For example, take the below

app.

Page 106: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 106

Notice that our app has margins to the left and the right, as well as between the circular ImageView and

the TextView to its right. The magic number of the first keyline is 16dp. This means that all UI elements,

except the status bar and toolbar of course, start at 16dps from the left and right side of the screen. This

prevents text from being placed at the edge of the screen, which makes it difficult to read. We followed

this keyline in the above app. The magic number of the second keyline is 72dp. This is where, in a list or

navigation drawer, we can start the text if there’s an icon or checkbox to the left of it. This gives us

enough space between the icon/checkbox that the user can accurately touch the icon/checkbox and we

can provide a touch event. For example, in the Messager app, when we touch on an icon, we bring up

that contact’s info; however, if we tap on the list item, we bring up the text messages between us and

that contact. This also prevents us from cramming the text right up against the icon/checkbox.

Page 107: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 107

There are also other considerations when regarding lists and spacing, in general. For example, the main

toolbar usually has a height of 56dp (as opposed to 48dp back in Android 4.0). In some of the other

posts, you’ll notice that we set the minimum height of the toolbar to be the system’s height of the

toolbar. This is the reason why: if the height changes in the next Android release, we can be future-

proof. Also, the toolbar can change depending on the screen size or orientation. We also do the same

for ListView rows/items. Depending on their content, we can query the system for the best height using

the listPreferredItemHeight or listPreferredItemHeightLarge attributes. In our case, ListView items have

a height of 72dps. This makes them easy to tap on and the user doesn’t have to pinpoint his or her

finger to touch the right ListView item.

We’ve only covered just a little bit of Material Design. In fact, Google has a great website that covers

many more aspects about Material Design that you can look at here. If you need some inspiration, just

look at some of the apps on the Google Play Store already! Most of the major applications, by the time

of this writing, have already redesigned their apps to support Material Design. Take a look at them for

some great examples of Material Design in action.

We only scratched the surface of Material Design in this post. We hit some key points about Google’s

new Material Design approach. We talked about the purpose of Material Design and why it

was instated. We also discussed topics that we need to be mindful of, like elevation, color, and layout.

We finally learned about some great resources that we can refer to for guidance.

Page 108: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 108

How to Use Loaders in Android In this post, we’re going to learn about loaders as well as content providers. Loaders allow us

to load vast amounts of data asynchronously so we don’t bog down the main UI thread. We can get this

data from querying databases using content providers instead of having it stored in a resources file like

we’ve done in other posts. We’ll be building a small application that will just list the names of all of the

contacts on our phone.

If you’re not familiar with SQLite, I highly suggest that you look over this post on SQLite since content

providers deal with accessing data from the system’s SQLite databases.

The source code for this post can be downloaded here.

We’ve looked before at how to load data into a ListView using adapters, but what if we have a very large

database or data set? Most of the data sets that we’ve been using have been pretty small so it doesn’t

hurt that much to load them immediately in onCreate(...) . However, when we have databases or data

sets of thousands or hundreds of thousands of entries, instead of stalling the app, it might be better to

load them on a background thread. We’ve already looked at how we can create and manage

background threads, but since loading data from a database in a background thread is such a common

task, Android has a wonderful CursorLoader class that prevents us from having to write the boilerplate

code ourselves.

But where do we get the data for the loaders to load? Let me talk about cursors and content providers.

Let’s look at an example of one: the Contacts app. On Android phones, there’s a way to manage all of

our contacts. But where is that data stored? It’s stored in a database! In fact, the system can even let us

access into that database through a content provider. Content providers allow applications to share data

between each other. This is how Twitter or LinkedIn know about your contacts: they have access to

them if you give the permission for them to read your contacts.

The Android system has hundreds of content providers for many different pieces of information like

contacts, media, and photos. To differentiate all of these different content providers, each group of

related information has a content URI that we provide to tell the content provider that we’re

querying one database and not the other. Think of URIs as being URLs on the internet. Inputting

androidkennel.org will get you to this site, but inputting google.com will get you to another site. These

URIs are also unique so no two content providers should have the same URI. We simply provide the URI

and the query we want to run, although most of the querying part is actually abstracted away for good

reasons.

When we query a content provider, we get back a Cursor object. This allows us to step through the rows

of the result query using a similar approach as if we had an iterator: while the Cursor has a next row,

grab the current one and then move on to the next row. We can access the data stored in the

current row of the Cursor through the index of the column, but we won’t have to do this since Android

provides us with a SimpleCursorAdapter that will display cursor results for us, allowing us to skip the

step of making our own custom adapter.

Page 109: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 109

To summarize our approach to display contacts in a ListView, we’ll first need to ask for permission to

read contacts. Then we’ll initialize the loader with the appropriate query (that is, retrieve all of the

contacts’ names). Then, when the query is finished, we switch our adapter’s Cursor with the one we get

back from the loader.

Let’s get started and create the LoaderDemo project! We’ll need Android 6.0 Marshmallow with an

empty activity. First things first, we need a ListView! Replace the layout/activity_main.xml with the

following.

1

2

3

4

5

6

7

<?xml version="1.0" encoding="utf-8"?>

<ListView xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/listView"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.deshpande.loaderdemo.MainActivity" />

Now that we have a ListView, we need to deal with the runtime permissions for reading contacts. Add

the following line in the AndroidManifest.xml file before the application tag.

1 <uses-permission-sdk-23 android:name="android.permission.READ_CONTACTS" />

Now that we’ve done this, we can request the READ_CONTACTS permission right when we start the app.

Open up MainActivity and add the following to the onCreate(...) method. We’ll also need to create a

constant at the top of our class for PERMISSION_CONTACTS.

1

2

3

4

5

if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {

ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.READ_CONTACTS }, PERMISSION_CONTACTS);

} else {

getLoaderManager().initLoader(LOADER_CONTACTS, null, this);

}

Page 110: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 110

Now after we’ve been granted permission, we can initialize the loader. We’ll need another constant for

LOADER_CONTACTS since we could have initialized multiple loaders if we wanted to.

1

2

3

4

5

6

7

8

9

10

@Override

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

switch (requestCode) {

case PERMISSION_CONTACTS:

if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

getLoaderManager().initLoader(LOADER_CONTACTS, null, this);

}

break;

}

}

The first parameter is the ID of the loader, the next is an optional Bundle we could pass, and the final

argument is the callback listener. This will make us implement the callbacks, but change the declaration

so that instead of the parameter type being Object, it’s Cursor. We’ll have to change this in the methods

as well.

1 public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> { ... }

Before we do that, we’ll need to create a SimpleCursorAdapter and set our ListView’s adapter to be that

SimpleCursorAdapter. We’ll need to create a private field in our class for the adapter and then initialize

it in onCreate(...) since we’ll need the adapter later. The first parameter is the context, the second is the

layout, and the third is the Cursor. We’re passing in a simple ListView item layout that’s really just a

TextView whose ID is text1.

We’re initially passing null since we’ll give it a Cursor after the loader is finished. The next two fields are

the mapping between database column and the contents of a view ID. In our case, we want to map the

name to the text1 TextView. To reiterate, text1 is the ID of the single TextView in the simple list item

layout. Android is smart enough to know that the ID we’re passing is that of a TextView so we set it’s

text to be whatever is in the row’s DISPLAY_NAME column. The final parameter is just some arbitrary

flags that we won’t set since we don’t have any flags to set.

Page 111: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 111

1

2

3

4

5

6

String[] from = { ContactsContract.Contacts.DISPLAY_NAME };

int[] to = { android.R.id.text1 };

adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, null, from, to, 0);

ListView listView = (ListView) findViewById(R.id.listView);

listView.setAdapter(adapter);

Now that we’ve configured our adapter, we can actually look at how we can implement the loader. First

we need to create the loader. We’ll be creating a new CursorLoader that will handling loading up the

data we need. The first parameter is the context, the next is the URI that I mentioned before. The third

parameter is called the projection and it’s the columns that we want to return. We declared this as a

constant at the top of the class. We need to make sure to always have the unique _ID value in the

projection. Then we need the DISPLAY_NAME. The next two parameters are the selection clause and the

selection arguments. We’re passing in null so we get all of the contacts (null translates to * in SQLite)

and we don’t have any selection parameters, of course. The final parameter is the sorting order and

we don’t care, but we could have our ListView sorted if we needed to.

1

2

3

4

5

6

7

8

9

10

11

12

private static final String[] PROJECTION = { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME };

...

@Override

public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {

if (id == LOADER_CONTACTS) {

return new CursorLoader(this, ContactsContract.Contacts.CONTENT_URI, PROJECTION, null, null, null);

} else {

return null;

}

}

Page 112: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 112

Now the loader will go and execute the query on the background thread and call

onLoadFinished(...) when it’s done with the query. Note that we get the original loader and an object of

the parameterized type, a Cursor in our case. This part of the code is simple, we just swap the null

Cursor with the one that the loader returned.

1

2

3

4

5

@Override

public void onLoadFinished(Loader<Cursor> loader, Cursor c) {

adapter.swapCursor(c);

adapter.notifyDataSetChanged();

}

You might have noticed that we have a method called swapCursor(...) and one called changeCursor(...) .

These two are very different by one key fact: changeCursor(...) will close the old Cursor. After we’re

done getting data from a Cursor, it’s important that we call close() on it to free up resources. We

haven’t had to do it since SimpleCursorAdapter and the CursorLoader manage it for us. This is also the

reason why it’s very important that we use swapCursor(...) instead of changeCursor(...) . CursorLoader is

managing the Cursor so it will close it after the call to onLoadFinished(...) . If we close it and it’s already

closed, this will crash our app! This is why we must use swapCursor(...) instead of changeCursor(...) .

onLoaderReset(...) is just a mandatory method we have to implement so we’ll swap the cursor of our

adapter to be null since this means that our created loader is being reset, so we don’t want to be

accessing data at this time.

1

2

3

4

@Override

public void onLoaderReset(Loader<Cursor> loader) {

adapter.swapCursor(null);

}

That’s all we need to do with the loaders! Now we can run the app in our emulator or on our phone and

get a list of all of our contacts! In the emulator, you can sign into your Google account to grab those

contacts. Here’s an example of the app running on my phone (obviously my contacts are censored).

Page 113: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 113

Conclusion In this post, we learned how to use content providers to access our phone’s contacts and load them into

a ListView asynchronously using loaders. The great benefit of using loaders is that they’re asynchronous

so we don’t hang the UI thread while it waits for us to grab potentially thousands of entries. We also

learned more about Cursors and how they’re related to content providers as well. Use loaders whenever

Page 114: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 114

you predict that you’re going to be fetching a potentially vast amount of data (maybe even showing a

spinning progress dialog while the user waits).

How to Accessing the Camera and Take Pictures on Android In this post, we’re going to learn how we can access the camera and use it to take a picture. Grabbing

data from the camera can be a bit tricky, especially when dealing with the Android filesystem so we’ll be

covering how to create an image file for the photo and extracting that image back into the

ImageView. In this post, we’re going to create an app that will take a photo and display that photo in

an ImageView.

Download the full source code here.

Let’s get started right away and create a new Android project called CameraDemo with Android 6.0.

We’ll just need to create a blank activity and leave the defaults as is. The first thing we’ll need to do is

to define the appropriate permissions in our AndroidManifest.xml. So open that up and add the

following lines before the application tag.

1

2

<uses-permission-sdk-23 android:name="android.permission.CAMERA" />

<uses-permission-sdk-23 android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

We’ll obviously need the camera permission, but we’ll also need the permission to write this image to

the device’s public storage, so even if our application is uninstalled, the photos that users took with it

will still remain on the device. Next we’ll need to define our layout so open activity_main.xml and

substitute the following text (replacing tools:context with your respective MainActivity).

1

2

3

4

5

6

7

8

9

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

Page 115: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 115

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

tools:context="com.deshpande.camerademo.MainActivity">

<ImageView

android:id="@+id/imageview"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerHorizontal="true"

android:layout_above="@+id/button_image"/>

<Button

android:id="@+id/button_image"

android:layout_width="wrap_content"

android:layout_height="48dp"

android:layout_alignParentBottom="true"

android:layout_centerHorizontal="true"

android:onClick="takePicture"

android:text="Take a picture!"/>

</RelativeLayout>

We’re defining the ImageView that will store our resulting image. We also want to center that and make

sure it’s above the Button. Speaking of the Button, we’re giving it a height of 48dp so that it conforms

with Material Design (for more information on Material Design, read this post). We want to anchor this

view to the bottom of the screen and center it as well. Notice that we give it a method name for the

onClick event that we’ll later define. Finally, we give it some text.

Now that we’ve completed our view, we’ll need to handle the permissions. But what if the user doesn’t

want to give us permission to access the camera or external storage? Instead of closing the app, we can

actually disable the Button that allows the user to take a picture. Then after the user has given us

permission to access those systems, we can re-enable the Button. In order to do this however, we need

Page 116: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 116

to declare the Button as a field and set it in onCreate(...) before we check out permissions. If we don’t

have the appropriate permissions, we disable the button until we do. We also need the ImageView to

populate so we can do that as well in a similar fashion to the following.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

private Button takePictureButton;

private ImageView imageView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

takePictureButton = (Button) findViewById(R.id.button_image);

imageView = (ImageView) findViewById(R.id.imageview);

if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {

takePictureButton.setEnabled(false);

ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);

}

}

We can save some checking by only determining whether or not we have the camera permission since

the only reason we need the external storage permission is to save images from the camera. So we can

add both permissions to the String array. To save some space, we’re also simply using 0 as the request

code since we’re only calling requestPermissions(...) once in our app. If the user accepts our terms, then

we simply re-enable the button like the following.

1

2

@Override

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

Page 117: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 117

3

4

5

6

7

8

9

if (requestCode == 0) {

if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED

&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {

takePictureButton.setEnabled(true);

}

}

}

Next, we’re going to implement the onClick attribute of the button. We’ll be using the system’s Intent

for taking pictures so we don’t have to implement our own functionality of taking pictures. Since we also

need a result, we call startActivityForResult(...) and not just startActivity(...) . We also need a file that

we’re saving the image to. This will have to be defined as a member variable at the top of our class for

reasons we’ll see in just a second. For now, we’re assuming that there’s a method called

getOutputMediaFile() that does this for us. We’ll implement it later in this post. We also need to make

this file Uri a field in our class instead of a local variable in the method since Intents fully support having

Uris as extras and for another reason we’ll see in the implementation of that method. Now we can just

call startActivityForResult(...) . As with requesting permissions, we’re just going to use some integer

constant like 100.

1

2

3

4

5

6

7

public void takePicture(View view) {

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

file = Uri.fromFile(getOutputMediaFile());

intent.putExtra(MediaStore.EXTRA_OUTPUT, file);

startActivityForResult(intent, 100);

}

Now that we’ve sent this Intent to the system, we have to handle the result in onActivityResult(...) like

the following.

Page 118: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 118

1

2

3

4

5

6

7

8

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (requestCode == 100) {

if (resultCode == RESULT_OK) {

imageView.setImageURI(file);

}

}

}

But wait, there’s no result? This is why we needed to declare that file Uri to be a member. For camera

events, data is written to the file and not returned in the data Intent. So the workflow here is to pass in

a reference to a file that the camera will populate with image data. In onActivityResult(...) , we’re really

just setting the ImageView’s image data to be that URI since it’s been set by the system’s camera activity

if the result code was RESULT_OK.

The only thing left to do is to implement the getOutputMediaFile() method to create a

file reference that the image data will be saved to. We first need to get access to the public directory

where images may be saved on the device. As mentioned before we don’t want to use just

our application’s inner directory because our user will loose all of the photos that were taken with our

app when it is uninstalled. To do this, we need to get a file path to that external pictures directory and

then add a subdirectory to the path for our app’s pictures! Now we need to create that subdirectory. So

we first check if the path exists, and, if it doesn’t, then we call mkdirs() to create the file path. If that

failed, we simply return null since we weren’t able to create a path for the file.

1

2

3

4

5

6

7

8

9

private static File getOutputMediaFile(){

File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(

Environment.DIRECTORY_PICTURES), "CameraDemo");

if (!mediaStorageDir.exists()){

if (!mediaStorageDir.mkdirs()){

return null;

}

}

Page 119: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 119

10

11

12

13

14

String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

return new File(mediaStorageDir.getPath() + File.separator +

"IMG_"+ timeStamp + ".jpg");

}

Now that we have the directory, we need to create the file. We’re going to have the file names

contain timestamps so that each is unique and no two files would have a chance at being overwritten.

Calling new Date() will return the timestamp exactly when that call is executed. Then we create the

filepath to be the subdirectory in the public pictures directory, plus a file separator, and plus an IMG_

prefix, then the name of the file and the file extension. (Please note that this code is adapted

from Android’s API. Original source here) Now we’re done!

Before we can run our app, we need to make sure we have a camera-enabled emulator by opening up

our AVD manager and clicking the pencil icon next to our emulator to manage it. In the dialog that

comes up, click on the button that says “Show Advanced Settings” and find the Camera section. In

here, we have the option to emulate the camera or actually use our computer’s webcam. Currently, the

default is that our device won’t have a camera, but we need it for our app. Click the dropdown for both

Front and Back cameras and change them to webcam if you have one. If not, change them to emulated.

We need them to be not “None” since our app requires a camera and the system will tell us that a

camera doesn’t exist.

Now that we’re finished with our app, we can run it! Our app will have a mostly-blank screen with a

button (initially disabled) at the bottom. After we accept all of the permissions, the button will be

enabled and we can click on it. This will bring us to the system’s Activity for handling image capture and

we can take a picture now. After we do that and accept the photo, Android will bring us back to the

Activity that called the system’s camera Activity and we will be able to see the image in the main view of

our app!

Page 120: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 120

Conclusion In this post, we learned how we can access the Camera using Intents so we don’t have to create our own

Activity to take pictures. We learned how we can get a result back from that camera Activity and how

we can use the Android filesystem’s public directories to save data. We learned how to create an image

file that the system will save the data to before control jumps back to our app. Ultimately, we created an

app that can take a picture using the system’s Activity for picture-taking and read the result back.

Page 121: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 121

How to Use Android Sensors in Games In this post, we’re going to learn how to access just one of the multitude of sensors present on an

Android device by building a very small game that uses the accelerometer on the device. This game will

simply show a red ball on the screen whose motion is tied to the device’s accelerometer. For example,

tilting the device will cause the ball to accelerate in the direction of the tilt.

Download the full source code here.

Let’s get started! Create an Android Studio project called SensorsDemo and we’ll leave the defaults as is

(but create an Empty Activity). We can go ahead and delete the activity_main.xml file in the layout

folder since we’ll be using a custom view that will fill our entire screen and setContentView(...) has an

overload where we can pass in a View object. Also, copy-and-paste the ball from the provided source

code’s res/drawable directory to our res/drawable directory. If there isn’t a directory, create one. We’re

going to create a custom view that will handle updating our ball.

However, we still have much to do before we can get to the custom View. As a placeholder, let’s just

create our BallView private inner class inside MainActivity towards the end of the file like the following.

1

2

3

4

5

private class BallView extends View {

public BallView(Context context) {

super(context);

}

}

We’ll populate it with the logic to move the ball, but we first need to declare some top-level members

representing our ball’s position, acceleration, and velocity in the x and y directions. We’ll also

need members to represent the maximum x and y so we define boundaries restricting the ball’s motion

so it doesn’t roll off the screen! Of course, we’ll need a member to be the ball itself as a Bitmap object.

Finally, we need a SensorManager object so that we can register and unregister the listener for the

accelerometer sensor.

1

2

3

4

private float xPos, xAccel, xVel = 0.0f;

private float yPos, yAccel, yVel = 0.0f;

private float xMax, yMax;

private Bitmap ball;

Page 122: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 122

5 private SensorManager sensorManager;

Now that we’ve done this, let’s complete our onCreate(...) method. Since we’re using the

accelerometer, it’s a good idea to keep our app in portrait mode so that the system doesn’t think we

want to change orientations if we tilt a bit too much in one direction. We can do this to a call in

setRequestedOrientation(...) method. Then we can create our custom BallView and set the view

of our Activity to be the new BallView object. Then we need to grab the our device’s size so that the ball

doesn’t roll off of the screen. Finally, we need to instantiate our SensorManager object by grabbing a

reference to the system’s sensor manager.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

BallView ballView = new BallView(this);

setContentView(ballView);

Point size = new Point();

Display display = getWindowManager().getDefaultDisplay();

display.getSize(size);

xMax = (float) size.x - 100;

yMax = (float) size.y - 100;

sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

}

In onStart() and onStop() , we need to register and unregister our SensorManager, respectively. This

is a great place to do this because these Activity lifecycle methods are called before the screen is visible

to the user and after the screen has disappeared off the screen, respectively. We need to specify

that we need the accelerometer sensor and we’ll need to specify a refresh rate, SENSOR_DELAY_GAME,

in our case. Note that we perform our method calls after the call to the superclass in onStart() , but, in

Page 123: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 123

onStop() , we perform method calls before the call to the superclass. This is because we’d like to

unregister our listener before the system does it’s tasks to free up resources, for example.

1

2

3

4

5

6

7

8

9

10

11

@Override

protected void onStart() {

super.onStart();

sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);

}

@Override

protected void onStop() {

sensorManager.unregisterListener(this);

super.onStop();

}

This will force us to implement the SensorEventListener2 interface, which will make us implement

onSensorChanged(...) , onFlushCompleted(...) , and onAccuracyChanged(...) . We won’t have to do

anything in the latter two methods, but the former is the most important since this is where we

actually retrieve data from the accelerometer. To gain a better understanding of why we have

positive/negative values in our code, look at the following diagram of the orientation of the sensors with

respect to the device.

Page 124: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 124

(Source)

Also, according to the documentation, sensorEvent.values[i] stores data on our accelerometer, where i

is a value from 0 to 2 representing the acceleration in the x, y, and z directions. From the diagram, note

that we have to negate our y value, else the ball will just move in one dimension! After we get their

values, we need to update our ball’s location. This is a common practice in game development to update

the location of all of the entities of the game per frame. In our case, our only entity is the ball, and, since

that’s tied to the accelerometer, our “frame” depends on the refresh rate of the sensors, which is still

very fast.

1

2

3

4

5

6

7

8

@Override

public void onSensorChanged(SensorEvent sensorEvent) {

if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

xAccel = sensorEvent.values[0];

yAccel = -sensorEvent.values[1];

updateBall();

}

}

Page 125: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 125

Now in our updateBall() method, we need to change our velocities and calculate how far our ball has

moved in that time. Then we need to combine our ball’s current location with the displacement and we

now have the ball’s new position! Notice that because of the coordinate axes on the device, we have to

actually subtract the delta position from the current position! Feel free to play around with these

calculation to make your ball game more or less difficult! We also need to handle the cases where

it goes off the screen. We can set the position to be the min or the max depending on how it goes off

the screen.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

private void updateBall() {

float frameTime = 0.666f;

xVel += (xAccel * frameTime);

yVel += (yAccel * frameTime);

float xS = (xVel / 2) * frameTime;

float yS = (yVel / 2) * frameTime;

xPos -= xS;

yPos -= yS;

if (xPos > xMax) {

xPos = xMax;

} else if (xPos < 0) {

xPos = 0;

}

if (yPos > yMax) {

yPos = yMax;

} else if (yPos < 0) {

Page 126: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 126

21

22

23

yPos = 0;

}

}

Now we need to code our custom view to actually display the ball on the screen. Since our entire

Activity is comprised of the BallView, we can just position the ball on the view and we’re sure that the

ball will be on the screen. Note that we are forced to implement the constructor that calls the

superclass’s constructor. In our constructor, we need to grab our Bitmap and resize it so it’s the

appropriate size for our screen.

When we’re creating a custom view, we have to override a method called onDraw() since that’s called

to draw the view once. However, we don’t just want to draw our ball once, we want to keep refreshing

it. We can call an instance method inside View called invalidate() . This will tell the view to call

onDraw(...) again sometime in the future.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

private class BallView extends View {

public BallView(Context context) {

super(context);

Bitmap ballSrc = BitmapFactory.decodeResource(getResources(), R.drawable.ball);

final int dstWidth = 100;

final int dstHeight = 100;

ball = Bitmap.createScaledBitmap(ballSrc, dstWidth, dstHeight, true);

}

@Override

protected void onDraw(Canvas canvas) {

canvas.drawBitmap(ball, xPos, yPos, null);

invalidate();

}

Page 127: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 127

16 }

This should be all we need to get our app running and using the accelerometer! Here’s what our app

looks like running on a physical device.

As we move the device, the ball accelerates in the appropriate direction! For those of you that might not

have an Android device, we can still use the accelerometer. However, instead of having a physical

device, we need to manually connect with the emulator’s console through a client called telnet. If you’re

on a Mac or Linux computer, you already have this installed. However, if you’re on Windows, you’ll need

to enable it by following this procedure. To simulate the accelerometer, we’ll need to start up our

emulator and open up a terminal window. Note the 4-digit number at the top of the emulator’s window.

That’s called the port number and we need it to log into the emulator. In the console, type telnet

localhost #### with #### as your emulator’s port number. Now we should see something like Android

Console: type 'help' for a list of commands in the console. Now we can type sensor status to show the

status of all of the emulator sensors. We know everything is good if we can see acceleration: enabled. in

the list of sensors. Now if we wanted to change the acceleration, we can run the following command to

set the acceleration: sensor set acceleration 0:0:0 or sensor set acceleration 50:50:50 . We can use this

to change the acceleration of the emulator and play our game!

Page 128: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 128

Conclusion In this post, we learned how to access the accelerometer on our device/emulator to build a game using

it as well. We built a game that has a ball on the screen whose motion is tied to the accelerometer.

When we move the accelerometer, we also move the ball. Even though we only covered the

accelerometer, this same approach can be done with different types of sensors as well. Make sure to

check out the documentation on how to use the other kinds of sensors!

Page 129: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 129

How to Use the Android Notification System In this post we’re going to learn how to use the Android notification system. Android notifications have

evolved from the standard one-liner with an app icon to having actions, showing images, and expanding

to show more information. Notifications are a critical part of the user experience. Instead of the user

having to check your app for updates, your app will save the user the time and effort by notifying the

user about important things. We’re going to learn how to use the notification system as well as

the variety of styles that notifications come in.

You can download the source code for this post here.

Let’s get started! Create a new Android Studio project called NotificationDemo with Android 6.0. We

just need an empty Activity with the default naming conventions. In addition to this primary Activity, we

also need to create a second Activity so that the user will be directed to that when they tap on the

notification. Android Studio has a shortcut that will allow us to create an Activity and corresponding XML

layout file. Right-click on the primary package and select New->Android Activity-> Empty Activity. Then

enter ResultActivity for the name of our new Activity. Android Studio will now create the corresponding

Java and XML file.

Regarding the view of this Activity, we want to keep this simple by just having a large TextView centered

on the screen so that we know our notification directed us to the appropriate Activity. Change the XML

of ResultActivity to be the following:

1

2

3

4

5

6

7

8

9

10

11

12

13

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context="com.deshpande.notificationdemo.ResultActivity">

<TextView

android:layout_width="wrap_content"

Page 130: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 130

14

15

16

17

18

19

20

android:layout_height="wrap_content"

android:textAppearance="?android:attr/textAppearanceLarge"

android:text="Notification Worked"

android:id="@+id/textView"

android:layout_centerVertical="true"

android:layout_centerHorizontal="true" />

</RelativeLayout>

Now that we’ve done that, we need to consider the view that will actually launch the notification that

will get us to this Activity. In our case, since we just need to generate a notification, let’s have a simple

button that will launch a notification when it is clicked. The XML layout file of MainActivity should now

look like the following:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context="com.deshpande.notificationdemo.MainActivity">

<Button

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Click Me!"

Page 131: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 131

16

17

18

19

20

android:id="@+id/button"

android:layout_centerVertical="true"

android:layout_centerHorizontal="true"

android:onClick="createNotification" />

</RelativeLayout>

We’ve centered the Button on the screen and already assigned it a method to be called when the button

is clicked. All of our notification content is going to go into that single method. Let’s open up

MainActivity and add the method below onCreate(...) as public void createNotification(View view). The

reason we need that one View parameter is because that’s a part of the method signature required for

our Button’s onClick attribute.

Now we can get started building the notification. First of all, the process of creating a notification

follows the Builder design pattern. With this pattern, the only way to create a Notification object is to

use the public inner class Notification.Builder. Then we can customize our notification, call build(), and

our Notification object is created and ready to hand off to the system to post. Each setter method

of the Builder also returns a Builder with that property set. This means that we can chain together the

setters like the following:

1

2

3

4

NotificationCompat.Builder builder = new NotificationCompat.Builder(this)

.setSmallIcon(android.R.drawable.ic_dialog_alert)

.setContentTitle("Notification!")

.setContentText("This is my first notification!");

Make sure to import the v4 NotificationCompat class, not the v7! The only argument the Builder

requires is the Context. Note that on the left gutter of Android Studio’s main text pane, we can see a

tiny thumbnail of the drawable icon. This gives us an idea of what the icon is going to look like.

After we’ve created this preliminary Builder object, we can then consider changing the style. You

might have noticed that when you have multiple unread emails, the notification looks like a miniature

ListView. This is the NotificationCompat.InboxStyle. If you get a notification with a single email, the

notification becomes expandable and we can actually read the first few lines of the email. This is the

NotificationCompat.BigTextStyle. Finally, when you take a screenshot, there’s always a follow-up

notification that can be expanded into a picture of the screenshot. This is the

NotificationCompat.BigPictureStyle. In fact, we can create our own custom styles by extending the

NotificationCompat.Style abstract class.

Page 132: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 132

For our purposes, we’re going to look at the BigTextStyle. Using styles is very straightforward. We just

create a BigTextStyle object and call bigText(...) on it to set the expanded content of the notification. In

our case, we’re going to use a Lorem Ipsum generator so that we can generate some phony text to see

how the notification is going to work. Finally, we need to set our builder object’s style to be the one we

just created. All of this looks like the following in code:

1

2

3

4

5

6

7

NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();

bigText.bigText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +

"Etiam hendrerit risus ut congue feugiat. Donec rutrum tristique purus, at tempus ipsum pharetra eget. " +

"Ut tristique aliquet elementum. Sed hendrerit quis sapien a mattis. " +

"Pellentesque interdum neque a felis mattis finibus. ");

builder.setStyle(bigText);

Now that we’ve done this, we need to handle what happens when the user clicks on the notification. We

can use the Intent system to launch an Activity. However, we need to wrap that Intent inside another

kind of special Intent called a PendingIntent. By wrapping our Intent around a PendingIntent and

passing that to the system, it becomes the systems responsibility to call the Intent when the notification

is called. A PendingIntent is just what the name implies: it’s an Intent that has yet to be used. After we

create this PendingIntent, we then tell our builder to use it. This is represented in code by the following:

1

2

3

Intent resultIntent = new Intent(this, ResultActivity.class);

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

builder.setContentIntent(pendingIntent);

Notice that we don’t really care about the request code since this is the only PendingIntent our app

launches. In addition, the last parameter of the getActivity(...) method is any flags we want to give to

this PendingIntent. In our case, we’re telling the system not to push out a new notification if any

information changes, but to update this current one. This prevents the user from receiving a hundred

notifications from our app!

Finally, we can build this Notification. We also want to set an additional flag so that the notification

is dismissed when the user taps on it. We can do this by building our notification and setting the flags

on the built notification as follows:

Page 133: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 133

1

2

Notification notification = builder.build();

notification.flags = Notification.FLAG_AUTO_CANCEL;

Now that we’ve finally built our notification, we can send it off to the system! We need to get a

backwards-compatible reference to the system’s notification manager and simply call notify(...) with

our notification object.

1

2

NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);

notificationManager.notify(0, notification);

Notice how we simply set the ID of the notification to be some arbitrary integer. However, if we wanted

to cancel our notification programmatically for some reason, then we would need to keep track of the

ID.

And that’s all it takes to create a highly-customizable notification! We can see the various stages of the

notification in the screenshots below!

Page 134: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 134

Page 135: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 135

In this post, we learned how to create and customize a notification that can be sent

programmatically. We learned about how the notification system uses the Builder pattern to create

Notification objects. We also covered the three styles of notifications: InboxStyle, BigTextStyle, and

BigPictureStyle. In addition to that, we learned what PendingIntents are and their uses. Finally, we saw

how to formally post the notification to the Android systems. Notifications are a key part of an

app’s interact with the user. A word of warning: only make notifications if it makes sense for your app to

do so. Nothing is more annoying than receiving random notifications from a calculator app! Be smart

about your notifications!

Page 136: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 136

How to Pass Data between Activities using Intents Hello World! In this post, we’re going to learn how we can pass data back and forth between two

different activities. We’ll also learn how to reuse layouts and use our app’s manifest with Intents. The

Intent object is the fundamental class that we use to pass data around in Android. It acts as a container

of information to the system that we can manipulate. We’re going to see how we can transfer to

an Activity and get a result back from that Activity as well.

Note: To make this easier on us, we’re going to use source code from a previous post on Toolbars so if

you have any questions as to the specifics of ListViews or Toolbars, please read those respective articles!

We’re going to be building an app that displays a list of countries, and, when the user taps on an entry, it

brings them to another view that simply displays the name of the country. The interesting part is that

the second Activity will receive the country to display from the first Activity.

Let’s create a new Android Studio project and call it IntentDemo. We’re going to start by adding the

following to the res/values/strings.xml file to act as our database backend.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<string-array name="countries_array">

<item>Afghanistan</item>

<item>Albania</item>

<item>Algeria</item>

<item>American Samoa</item>

<item>Andorra</item>

<item>Angola</item>

<item>Anguilla</item>

<item>Antarctica</item>

<item>Antigua and Barbuda</item>

<item>Argentina</item>

<item>Armenia</item>

<item>Aruba</item>

<item>Australia</item>

<item>Austria</item>

<item>Azerbaijan</item>

Page 137: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 137

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

<item>Bahrain</item>

<item>Bangladesh</item>

<item>Barbados</item>

<item>Belarus</item>

<item>Belgium</item>

<item>Belize</item>

<item>Benin</item>

<item>Bermuda</item>

<item>Bhutan</item>

<item>Bolivia</item>

<item>Bosnia and Herzegovina</item>

<item>Botswana</item>

<item>Bouvet Island</item>

<item>Brazil</item>

<item>British Indian Ocean Territory</item>

<item>British Virgin Islands</item>

<item>Brunei</item>

<item>Bulgaria</item>

<item>Burkina Faso</item>

<item>Burundi</item>

<item>Cambodia</item>

<item>Cameroon</item>

<item>Canada</item>

<item>Cape Verde</item>

<item>Cayman Islands</item>

<item>Central African Republic</item>

<item>Chad</item>

Page 138: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 138

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

<item>Chile</item>

<item>China</item>

<item>Christmas Island</item>

<item>Cocos (Keeling) Islands</item>

<item>Colombia</item>

<item>Comoros</item>

<item>Congo</item>

<item>Cook Islands</item>

<item>Costa Rica</item>

<item>Cote d\'Ivoire</item>

<item>Croatia</item>

<item>Cuba</item>

<item>Cyprus</item>

<item>Czech Republic</item>

<item>Democratic Republic of the Congo</item>

<item>Denmark</item>

<item>Djibouti</item>

<item>Dominica</item>

<item>Dominican Republic</item>

<item>East Timor</item>

<item>Ecuador</item>

<item>Egypt</item>

<item>El Salvador</item>

<item>Equatorial Guinea</item>

<item>Eritrea</item>

<item>Estonia</item>

<item>Ethiopia</item>

Page 139: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 139

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

<item>Faeroe Islands</item>

<item>Falkland Islands</item>

<item>Fiji</item>

<item>Finland</item>

<item>Former Yugoslav Republic of Macedonia</item>

<item>France</item>

<item>French Guiana</item>

<item>French Polynesia</item>

<item>French Southern Territories</item>

<item>Gabon</item>

<item>Georgia</item>

<item>Germany</item>

<item>Ghana</item>

<item>Gibraltar</item>

<item>Greece</item>

<item>Greenland</item>

<item>Grenada</item>

<item>Guadeloupe</item>

<item>Guam</item>

<item>Guatemala</item>

<item>Guinea</item>

<item>Guinea-Bissau</item>

<item>Guyana</item>

<item>Haiti</item>

<item>Heard Island and McDonald Islands</item>

<item>Honduras</item>

<item>Hong Kong</item>

Page 140: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 140

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

<item>Hungary</item>

<item>Iceland</item>

<item>India</item>

<item>Indonesia</item>

<item>Iran</item>

<item>Iraq</item>

<item>Ireland</item>

<item>Israel</item>

<item>Italy</item>

<item>Jamaica</item>

<item>Japan</item>

<item>Jordan</item>

<item>Kazakhstan</item>

<item>Kenya</item>

<item>Kiribati</item>

<item>Kuwait</item>

<item>Kyrgyzstan</item>

<item>Laos</item>

<item>Latvia</item>

<item>Lebanon</item>

<item>Lesotho</item>

<item>Liberia</item>

<item>Libya</item>

<item>Liechtenstein</item>

<item>Lithuania</item>

<item>Luxembourg</item>

<item>Macau</item>

Page 141: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 141

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

<item>Madagascar</item>

<item>Malawi</item>

<item>Malaysia</item>

<item>Maldives</item>

<item>Mali</item>

<item>Malta</item>

<item>Marshall Islands</item>

<item>Martinique</item>

<item>Mauritania</item>

<item>Mauritius</item>

<item>Mayotte</item>

<item>Mexico</item>

<item>Micronesia</item>

<item>Moldova</item>

<item>Monaco</item>

<item>Mongolia</item>

<item>Montenegro</item>

<item>Montserrat</item>

<item>Morocco</item>

<item>Mozambique</item>

<item>Myanmar</item>

<item>Namibia</item>

<item>Nauru</item>

<item>Nepal</item>

<item>Netherlands</item>

<item>Netherlands Antilles</item>

<item>New Caledonia</item>

Page 142: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 142

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

<item>New Zealand</item>

<item>Nicaragua</item>

<item>Niger</item>

<item>Nigeria</item>

<item>Niue</item>

<item>Norfolk Island</item>

<item>North Korea</item>

<item>Northern Marianas</item>

<item>Norway</item>

<item>Oman</item>

<item>Pakistan</item>

<item>Palau</item>

<item>Panama</item>

<item>Papua New Guinea</item>

<item>Paraguay</item>

<item>Peru</item>

<item>Philippines</item>

<item>Pitcairn Islands</item>

<item>Poland</item>

<item>Portugal</item>

<item>Puerto Rico</item>

<item>Qatar</item>

<item>Reunion</item>

<item>Romania</item>

<item>Russia</item>

<item>Rwanda</item>

<item>Sqo Tome and Principe</item>

Page 143: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 143

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

<item>Saint Helena</item>

<item>Saint Kitts and Nevis</item>

<item>Saint Lucia</item>

<item>Saint Pierre and Miquelon</item>

<item>Saint Vincent and the Grenadines</item>

<item>Samoa</item>

<item>San Marino</item>

<item>Saudi Arabia</item>

<item>Senegal</item>

<item>Serbia</item>

<item>Seychelles</item>

<item>Sierra Leone</item>

<item>Singapore</item>

<item>Slovakia</item>

<item>Slovenia</item>

<item>Solomon Islands</item>

<item>Somalia</item>

<item>South Africa</item>

<item>South Georgia and the South Sandwich Islands</item>

<item>South Korea</item>

<item>South Sudan</item>

<item>Spain</item>

<item>Sri Lanka</item>

<item>Sudan</item>

<item>Suriname</item>

<item>Svalbard and Jan Mayen</item>

<item>Swaziland</item>

Page 144: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 144

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

<item>Sweden</item>

<item>Switzerland</item>

<item>Syria</item>

<item>Taiwan</item>

<item>Tajikistan</item>

<item>Tanzania</item>

<item>Thailand</item>

<item>The Bahamas</item>

<item>The Gambia</item>

<item>Togo</item>

<item>Tokelau</item>

<item>Tonga</item>

<item>Trinidad and Tobago</item>

<item>Tunisia</item>

<item>Turkey</item>

<item>Turkmenistan</item>

<item>Turks and Caicos Islands</item>

<item>Tuvalu</item>

<item>Virgin Islands</item>

<item>Uganda</item>

<item>Ukraine</item>

<item>United Arab Emirates</item>

<item>United Kingdom</item>

<item>United States</item>

<item>United States Minor Outlying Islands</item>

<item>Uruguay</item>

<item>Uzbekistan</item>

Page 145: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 145

233

234

235

236

237

238

239

240

241

242

243

<item>Vanuatu</item>

<item>Vatican City</item>

<item>Venezuela</item>

<item>Vietnam</item>

<item>Wallis and Futuna</item>

<item>Western Sahara</item>

<item>Yemen</item>

<item>Yugoslavia</item>

<item>Zambia</item>

<item>Zimbabwe</item>

</string-array>

Now, before we make changes to our view, since we’re going to need a Toolbar in both Activity’s views.

Instead of copying and pasting code from one file to another, we can declare a layout file that can be

inserted in both views. This way, we only need to edit one layout file, not every single one! Let’s right-

click on the res/layout folder and create a new layout file whose name toolbar and whose root element

is android.support.v7.widget.Toolbar . Now we add properties to this toolbar like so.

1

2

3

4

5

6

7

8

<?xml version="1.0" encoding="utf-8"?>

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:minHeight="?attr/actionBarSize"

android:elevation="4dp"

android:background="@color/colorPrimary" />

Since we’ve created this layout file, we can insert it into any number of other layout files as well. For

example, let’s go into the activity_main.xml file and insert the following.

Page 146: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 146

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

tools:context=".MainActivity"

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent">

<include layout="@layout/toolbar" />

<ListView

android:layout_width="match_parent"

android:layout_height="match_parent"

android:id="@+id/listView" />

</LinearLayout>

In the above code snippet, we can insert the contents of the toolbar layout into this layout by using the

include tag and layout attribute. Let’s first have our list configured before we move on to create another

Activity. Open up the MainActivity class and add the following code snippet to set up our list.

1

2

3

4

5

6

7

private ListView listView;

private ArrayAdapter<CharSequence> adapter;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Page 147: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 147

8

9

10

11

12

13

14

15

16

17

18

19

listView = (ListView) findViewById(R.id.listView);

adapter = ArrayAdapter.createFromResource(this, R.array.countries_array, android.R.layout.simple_list_item_1);

listView.setAdapter(adapter);

listView.setOnItemClickListener(this);

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

setSupportActionBar(toolbar);

toolbar.setTitleTextColor(Color.WHITE);

toolbar.setTitle(R.string.app_name);

}

You’ll notice that we can access the Toolbar even when it’s actually in another file thanks to the include

tag. The call to setSupportActionBar(Toolbar) simply sets this Toolbar to act as the system Toolbar; we’ll

see more of this when we get to the other Activity. In the final line, we’re using the overload of the

setTitle(int) that accepts a string resource ID. We’ll be forced to implement the interface that will add

the onItemClick(...) method, but we can leave that empty for now. Run the code now and verify that

you get a list of countries as a start.

Page 148: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 148

Now we’re ready to create a new Activity. There are several steps involved in this process: creating the

Java class, creating the XML layout, and registering the Activity with the app manifest. Luckily, Android

Studio can do all of this for us with a single wizard! Right-click on the package name of our MainActivity

and go to New → Activity → Empty Activity. We’ll call ours DetailActivity and Android Studio will create

the corresponding layout file and register it with the app manifest. Let’s first look at the layout and

replace it with the following.

1

2

3

4

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"

android:layout_height="match_parent"

Page 149: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 149

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

android:orientation="vertical"

tools:context="com.deshpande.intentdemo.DetailActivity">

<include layout="@layout/toolbar" />

<RelativeLayout

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

android:paddingBottom="@dimen/activity_vertical_margin"

android:layout_width="match_parent"

android:layout_height="match_parent">

<TextView

android:id="@+id/textview_detail"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="22sp"

android:layout_centerInParent="true"/>

</RelativeLayout>

</LinearLayout>

We’re just simply declaring a TextView that will display our country. We need a top-level LinearLayout

so that the Toolbar appears first. Then we use the include tag to insert the Toolbar into this layout. We

need a RelativeLayout after the Toolbar so that the TextView is centered on the screen. Now we can go

back to our MainActivity and start the other Activity when a list item was clicked. Let’s add the following

code to the onItemClick(...) method. We also need some constants to keep track of uniqueness so we’ll

add those as fields at the top of the Activity.

Page 150: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 150

1

2

public static final String EXTRA_COUNTRY = "EXTRA_COUNTRY";

private static final int REQUEST_RESPONSE = 1;

1

2

3

4

5

6

@Override

public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {

Intent intent = new Intent(this, DetailActivity.class);

intent.putExtra(EXTRA_COUNTRY, adapter.getItem(position));

startActivityForResult(intent, REQUEST_RESPONSE);

}

In this code snippet, we’re creating a new Intent object, giving it some data, and starting up the other

Activity. The first parameter to the constructor is the Context and the second is the class we want to

start. Each class in Java has a class property that uses Java’s Reflection API (where a program can know

about itself so to speak). This particular parameterized constructor uses Java Reflection to launch the

appropriate Activity. In the next line, we call a method to store the country into the Intent with a unique

String ID. We’ll retrieve this value later in the other Activity. Then, we call the method to start the other

Activity through the Intent. Since we want a response back, we’re also passing in a unique request code

that we’ll be checking later. Now let’s open up the DetailActivity and add the following code in the

onCreate(Bundle) method.

1

2

3

4

5

6

7

8

9

10

String country = getIntent().getStringExtra(MainActivity.EXTRA_COUNTRY);

TextView textView = (TextView) findViewById(R.id.textview_detail);

textView.setText(country);

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

setSupportActionBar(toolbar);

toolbar.setTitleTextColor(Color.WHITE);

toolbar.setTitle("Country");

toolbar.setNavigationOnClickListener(this);

Page 151: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 151

11 getSupportActionBar().setDisplayHomeAsUpEnabled(true);

In the very first line, we grab the String hidden away in the Intent. We need the unique ID to grab

it however. Then we set the TextView’s text to be that country. We grab the Toolbar and set the

system’s ActionBar to be this Toolbar. The reason for this is so we can provide backwards-navigation for

the user to get back the the previous Activity. You might have noticed in other apps that it looks like a

left-facing arrow to the left of the Toolbar’s title. Instead of having to import and manage that image,

we can have the system display that for us by getting the ActionBar, in other words our Toolbar, and tell

the system to display that backwards-navigation icon. We just have to make sure we implement the

callback. We set this callback when we call setNavigationOnClickListener(...) . This will force us to

implement an interface and a callback method.

Before we do this, we need to tell Android that the parent activity of DetailActivity is MainActivity. We

can only do this in our app’s manifest file. In our Project view, let’s open up the

app/manifests/AndroidManifest.xml file and find and replace the tag relating to DetailActivity with the

following.

1

2

3

<activity android:name=".DetailActivity" >

<meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity" />

</activity>

The above code snippet tells Android that the parent activity of DetailActivity is MainActivity. Now that

we’ve done this, we can go back to our DetailActivity and configure the navigation. To do this however,

we’ll need an extra constant to do the same task as EXTRA_COUNTRY did in MainActivity.

1 public static final String EXTRA_RESPONSE = "EXTRA_RESPONSE";

1

2

3

4

5

@Override

public void onClick(View view) {

Intent intent = new Intent();

intent.putExtra(EXTRA_RESPONSE, "All is well!");

setResult(RESULT_OK, intent);

Page 152: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 152

6

7

finish();

}

We’re creating a new Intent object and putting in a small verification message. This method

setResult(...) will be helpful when we go back to MainActivity to read the response. RESULT_OK is a

constant of Activity so we don’t need to declare it. Then we pass the Intent that we created with the

data as well. The final call will finish this current Activity and transfer control back to the Activity which

started DetailActivity, which is MainActivity. Let’s take a look at what this Activity is going to look like.

Now let’s go back to MainActivity and display the response. Let’s override onActivityResult(...) method.

Page 153: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 153

1

2

3

4

5

6

7

8

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (resultCode == RESULT_OK) {

if (requestCode == REQUEST_RESPONSE) {

Toast.makeText(this, data.getStringExtra(DetailActivity.EXTRA_RESPONSE), Toast.LENGTH_SHORT).show();

}

}

}

In this code, we first check if the resultCode turned out to be RESULT_OK, which it did. Then we make

sure that the requestCode corresponds to the code we sent initially. Finally, we create a Toast message

and extract the string from the Intent using the key. This is all there is to do! Let’s run our app!

Page 154: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 154

You can see that when we tap on a list item, we transition to DetailActivity that has the name of the

country in the center of the screen. When we press on the backwards-navigation arrow, we have a Toast

message that says “All is well!”

Conclusion In this post, we covered how we can use Intents to start other Activities and pass data to them. We

also learned how to pass data back to the initial Activity as well. As a bonus, we also went over how to

reuse layouts through the include tag and a bit about the mysterious AndroidManifest.xml file. Intents

are very important since we can use so that we don’t have to create an Activity for everything!

For example, if we want an image, we ask the system, via an Intent, to take the user to the Camera app.

Then we can get the image back in onActivityResult(...) ! It’s really that simple! To summarize,

Intents are powerful objects that will make our Android coding go a lot smoother!

Page 155: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 155

Page 156: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 156

Android Networking Tutorial with AsyncTask Hello World! In this post, we’re going to lean how to access and use the Internet. This might seem like a

simple task, but we’re going to learn all of what that entails. Specifically, we’ll look at how we can run

networking operations on a different thread as well as how to use Android’s networking client to grab

data. We’ll finally learn how to parse the result to find our specific value in a sea of other information. In

our example, we’re going to pull weather data from a free weather API called OpenWeatherMap

and display the current weather for a given location.

Grab the full source code here.

Before we can create the project, we first need to go to OpenWeatherMap and get an API key. For most

online API services, developers need to create an account and request an API key. We send this

uniquely-generated key whenever we need to use the API to get data from the online API. The identifies

the API call with our signature. Anyway, at the website, sign up for a new account. After that, we

should see a “My Home” page and the “Setup” tab active. Scroll down and there should be a field called

“API key”. We need to write this down or copy it into a text file. We’ll need this unique String

after we create the project. Don’t share this API key with anyone! OpenWeatherMap’s API service

can cost money, but we’ll just be using their free tier of service. Sharing API keys could cause your usage

to spill over into the paid tier!

After we’ve retrieved our OpenWeatherMap API key, let’s create the project! We’ll call it

NetworkingDemo, give it an API level of Marshmallow, and create a blank Activity. Before we do start

creating our app, we need to open up the app/manifests/AndroidManifest.xml file. Above the

application tag, we need to add the following permission for internet access: <uses-permission-sdk-23

android:name="android.permission.INTERNET" />. After we’ve done this, we’re going to set up our view

so that it simply displays the current weather. Let’s go into our activity_main.xml layout file. Replace the

TextView with the following TextView.

1

2

3

4

5

<TextView

android:id="@+id/textView"

android:text="Getting Weather..." android:layout_width="wrap_content"

android:layout_height="wrap_content" android:layout_centerInParent="true"

android:textSize="28sp"/>

This new TextView has an ID since we’ll need to populate it eventually. The default text is “Getting

Weather…” in case the network is slow. For more complex cases, we would want to show a progress

spinner to tell the user that we’re waiting on the network. Our case is trivial enough that changing the

Page 157: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 157

TextView will suffice. We also center this child on the screen and change the text size so that it’s easier

to see.

Now we’re ready to add the Java code and handle all of the networking and JSON parsing. Let’s open up

our MainActivity and add a private constant to the top for the API key that looks something like

this: private static final String APP_ID = "INSERT YOUR API KEY HERE!";. You’ll need to replace the value

with your the API key from OpenWeatherMap.

Before we get into the actual networking, let’s first look at threads and threading. A thread is simply a

sequence of execution handled independently of the main sequence. For example, Android has a main

thread that we’ve been working with. Most of our code runs on main thread. In fact, we can only access

UI elements on the main thread, hence it’s also called the UI thread sometimes. But we have a problem

if we want to do networking. If we try to run networking calls on the main/UI thread, our entire app

will freeze until we’re done with the networking request. Imagine you’re waiting for your news feed to

load on a news app on your phone. If we didn’t have threading, your phone would freeze until the

stories are ready to go! To prevent this, we can create another thread, grab the data from the network

from that thread, and give it to our UI thread to update the UI elements. In some cases, we might want

to update a download progress bar, for example. We can use a method to send progress updates to the

main thread for it to update the download progress bar. After the networking is done, we can publish

the result on the main/UI thread for further processing or for display. In fact, Android is now more

proactive and forces you to take this approach so an error will be shown if you try to access the network

on the UI thread!

Instead of creating and managing these threads manually, Android provides us with an AsyncTask

parameterized class to help us do exactly this! Above is a graphic of the different method calls and the

Page 158: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 158

order in which they are called and the thread they run on. First, onPreExecute() is called and then

doInBackground(...) is called on the background thread immediately after. We can push progress

updates to onProgressUpdate(...) by called publishProgress(...) in doInBackground(...) . Finally, after

doInBackground(...) is finished, we run onPostExecute(...) .

Let’s create an inner subclass of AsyncTask to handle all of our networking after

the onCreate(...) method. Notice that we’re accepting a String as an input, leaving the progress

parameter unused (put in Void), and returning a String. Since AsyncTask is abstract class, we’ll need to

implement doInBackground(...) at least. But we also need to override onPostExecute(...) . We’re going

to be using aliasing to our benefit to populate the TextView. We’re going to pass in a reference to the

TextView we want to populate in the constructor. Since we’re getting a temperature, we can simply set

the TextView’s text to say that temperature in onPostExecute(...) with what we’ll soon get in

doInBackground(...) .

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

private class GetWeatherTask extends AsyncTask<String, Void, String> {

private TextView textView;

public GetWeatherTask(TextView textView) {

this.textView = textView;

}

@Override

protected String doInBackground(String... strings) {

return null;

}

@Override

protected void onPostExecute(String temp) {

textView.setText("Current Weather: " + temp);

}

}

Page 159: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 159

Now that we’ve done this, we can look at what we need to do in the background thread. Let me

outline the approach we’re going to take in this background thread. Note that we get a varargs list, but

we only need the first argument from that. However, we’ll need to grab just the first from that list. We

need to create a valid URL from it and open up a connection. Then we’ll get some JSON back and we

need to convert that input stream into a String and convert that into a JSON object. Then we can extract

our value from the JSON. Finally, we need to close the connection. In code, this looks like the following.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

@Override

protected String doInBackground(String... strings) {

String weather = "UNDEFINED";

try {

URL url = new URL(strings[0]);

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

InputStream stream = new BufferedInputStream(urlConnection.getInputStream());

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream));

StringBuilder builder = new StringBuilder();

String inputString;

while ((inputString = bufferedReader.readLine()) != null) {

builder.append(inputString);

}

JSONObject topLevel = new JSONObject(builder.toString());

JSONObject main = topLevel.getJSONObject("main");

weather = String.valueOf(main.getDouble("temp"));

urlConnection.disconnect();

} catch (IOException | JSONException e) {

e.printStackTrace();

Page 160: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 160

24

25

26

}

return weather;

}

The reason we use a String is so that in case we don’t get a response back, we can account for that. We

need to surround most of this in a try-catch since many of these instance methods throw exceptions. In

the next two lines, we create a new url and connect using Android’s awesome HttpURLConnection class.

The next three lines essentially convert the input stream to a buffered format so we can read it a line at

a time. If we wanted to be more robust, we could check the status code of the URL connection to make

sure it’s an HTTP OK before grabbing an input stream. Then we have a StringBuilder that we append

each line of the response to the StringBuilder. Converting to a JSONObject is a piece of cake since one of

the parameterized constructors for JSONObject takes a String and parses it for us.

JSON stands for Javascript Object Notation and it’s a way to format and organize information in key-

value pairs. We can essentially have JSON Objects with key-value pairs. We can also have JSON Arrays of

objects, each with key-value pairs as well. Look at this link for more information about JSON and

examples of it compared to XML. Looking at the OpenWeatherMap API, we know that we’ll get a top-

level JSONObject. The temperature we’re looking for is another JSON object whose name is “main”.

Then we can extract the temperature inside that object called “temp” and get the value of it. Finally, we

close the connection.

Now that we have our AsyncTask subclass created, it’s very simple to execute it in our

onCreate(...) method.

1

2

3

4

5

6

7

8

9

10

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

double lat = 40.712774, lon = -74.006091;

String units = "imperial";

String url = String.format("http://api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&units=%s&appid=%s",

lat, lon, units, APP_ID);

Page 161: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 161

11

12

13

TextView textView = (TextView) findViewById(R.id.textView);

new GetWeatherTask(textView).execute(url);

}

Feel free to replace the lat and lon with your location! The one provided is that of New York City, New

York, USA. The units can either be “imperial” or “metric” depending on your taste of units. If you want

to see the raw JSON, copy the url link and put it in your browser and substitute the lat, lon, API key, and

units. Your browser should show raw JSON text. You can format it by pasting into a JSON formatter here.

In this code, we grab a reference to the TextView to change and pass it to the AsyncTask to

populate after the network call. In the final line, we create a new task and call execute with the single

URL. We don’t need to store it in a variable since we won’t be do anything with it beside calling

execute(...) on it. We can see the current weather at our provided location below!

Page 162: Android App Development for Human Beings · Android App Development for Human Beings Mohit Deshpande . Zenva Academy ... Android 6.0 Platform Intel x86 Atom_64 System Image ... configure

Zenva Academy – Online courses on game, web and mobile app development

©2017 Zenva Pty Ltd all rights reserved

Page 162

Conclusion In this post, we learned how to access the Internet using AsyncTask and HttpURLConnection. We also

learned that all network calls need to happen on a separate thread and AsyncTask is the best way to

create a background thread. We learned the different methods in AsyncTask and how threading works

to our benefit. Finally, in AsyncTask, we covered how to connect to the OpenWeatherMap API by using

HttpURLConnection as well as how to parse the resulting JSON.