Homework 7-10 & 12: Quiz Droid

If you've taken Ted's iOS Development (INFO 449) course before, then I'm sure you've come across the famous Quiz App assignment. Now that we're learning about Android development, it's time for you to create the Quiz Droid app.

This series of assignment will require a lot of time to look up materials online and study them. The lectures will only provide the basic starting ground to help you get started on the assignment. We will point you to the right direction but you will be own your own when it comes to implementing things.

So I highly suggest you start each individual assignment in the series as early as possible and make sure each part to the assignment is satisfied and completed. Once you turn in, for instance, Quiz Droid Part 1 (Homework 7), you'll continue building more and more features out of Part 1, and submit the app as Part 2. You'll then repeat the same process for other parts until you submit the last assignment in the series, which is Part 5.

Intents

One of the most useful thing to use for this assignment is an intent. An intent is used to navigate from Activity to another and also pass data along with it.

Find out online for ways to pass an object (like String, ArrayList, and etc.) to another Activity.

Fragments

You must absolutely learn more about fragments before starting to code for this assignment. For some students, fragments are completely easy to understand because they carries the same sort of functionalities as things like components do in React, for instance.

While for several others, fragments are very difficult to work with because it's hard to properly set up FragmentTransaction.

A good place to start is to revisit the lecture on fragments.

Companion Objects

Let's start with the definition of a companion object, which is a singleton instance of an actual object.

In Java, you are allowed to declare static fields and methods. But Kotlin doesn't let you do so. Instead, you'll have to add a Companion object to your class.

Here's an example of companion objects being used:

class ParentClass {

    companion object {
        fun methodA() {
            # insert code here
        }
    }
    
}

Now you can perform execute methods like these:

fun exampleAction() {
    ParentClass.methodA()
    ParentClass.Companion.methodA()
}

Somebody in StackOverFlow also asked what's the equivalent of Java static methods in Kotlin. You should read it too.

Interface

Interfaces in Kotlin are very similar to Java. Here's an example of how one is defined:

interface MyInterface() {
    fun bar()
    fun foo()
}

You can then have a class that implements one or more interfaces by doing something like this:

class Child : MyInterface {
    override fun bar() {
        // Do something here
    }
}

Some parts of Quiz Droid app will utilize an interface that acts as a parent/top-level class for other classes. So it's definitely worthwhile to study about interfaces.

JSON

Working with JSON

We learn a lot about how to read and write JSON during lecture. When it's time to work with JSON for your application, I suggest you start by reading about Kotlin's JSON object.

For those of you that are coming from a web development background and knows a thing or two about the JavaScript's JSON object, then you will be extremely comfortable working with the Kotlin version.

Methods like stringify(...) and toString() are also available.

Using Gson for Fetching and Reading JSON Data

One way to parse / create JSON objects is to use an external library called Gson from Google. It converts a JSON string to an equivalent Java object. That makes it easy to handle them in our code. Methods like toJson() and fromJson() are also simple to understand and use.

To use Gson in your project, you must add the Gson library as a dependency:

dependencies {
  implementation 'com.google.code.gson:gson:2.8.5'
}

Google publishes and maintains a User Guide for the library.

Pushing JSON to Device via ADB

At some point in this series of assignments, your Quiz Droid app will need to be able to read in a file from the device. The problem most students struggle in is getting the file to be inside the device so that the Quiz Droid app can detect it.

Yes, you can obviously transfer files in and out by plugging in the USB cable, navigate through the root of the device, and etc. But the process becomes much simpler when you use Android Debug Bridge (or ADB). If for some reason you cannot get your device to connect to Android Studio, please revisit the section on this guide on how to fix this.

To help you with this, please read an article posted on DroidNews about pushing and pulling files on Android using ADB.

Action Bar

To add a button to an Action Bar in your class, you must override these methods: onCreateOptionMenus(...) and onOptionsItemSelected(..)

There's a training section on the Google Developers Documentation website that teaches you how to add the app bar to your project.

Requesting User Permissions

Your Quiz Droid app will need to read and write to storage and also to connect to the Internet to fetch data. Therefore you must understand how to request appropriate permissions in order for the app to work as intended.

The place to add permissions is in the AndroidManifest.xml file.

As a child of the <manifest> element, you can add permissions such as this:

<uses-permission android:name="android.permission.SEND_SMS"/>

Luckily, you can easily find out everything about requesting permissions by reading this tutorial section on the official documentation of Android.

Handling Permission Problems

Some students may encounter a problem in which the app will not work even if the following have been completed:

  1. The developer has already added the required element in the Manifest

  2. The user has already granted access to permissions that were requested by the developer.

The problem occurs as a result of what's called "dangerous permission." See Protection Levels for more details. But in short, if an app requires a dangerous permission, then there's a chance that the permission that was granted yesterday will not be granted today unless the app asks for the user to re-grant it again.

This is a security feature in Android OS 6.0 and above. You can solve this problem by simply checking for permissions before executing certain actions that require permissions. Suppose the permissions have not been granted, you can request for user permissions.

Working with URL in Kotlin

The basic parameter is URL(url: String, base: String = definedExternally)

Shared Preferences

We discussed about Shared Preferences in a previous section of this guide. You can also find out more about it from previous lecture (see slides).

To recap, Shared Preferences are very useful when it comes to storing simple data.

I borrowed the following example from an answer to a question on StackOverFlow:

Setting values in Preference:

SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
 editor.putString("name", "Elena");
 editor.putInt("idName", 12);
 editor.apply();

Retrieve data from Preference:

String restoredText = prefs.getString("text", null);
if (restoredText != null) {
  String name = prefs.getString("name", "No name defined");//"No name defined" is the default value.
  int idName = prefs.getInt("idName", 0); //0 is the default value.
}

As always, here's the link to the official documentation regarding how to use Shared Preferences.

Last updated