Mobile Assignment

Overview

The purpose of this assignment is to learn how to convert a Web application to a native Android application. The process for iOS is similar but will not be covered.

This assignment builds on the gift assignment.

Related Article

Assignment folder

Create a directory named mobile for the work you do for this assignment. Copy the contents the gift folder into the mobile folder.

Install the Android SDK

Install the Android SDK but do not install Eclipse (unless you want to). To avoid installing Eclipse, do not download the SDK bundle. Instead, download the SDK for an existing IDE.

The standard IDE to use for developing Android applications is Eclipse. However, Eclipse consumes a lot of memory and can run slowly on many computers. But Eclipse is not necessary because you can accomplish the same results using the command line interface to the Android SDK tools.

Do not locate the Android SDK inside your course repository. In other words, do not store the SDK folder anywhere under ~/405.

Modify your environment as follows.

In Windows, you need to go through the Control Panel to set your environment. Alternatively, run a script each time you start a terminal session that makes the above settings.

In OS X, you can accomplish the above by adding the following to ~/.bash_profile. You should restart the terminal program to make sure these settings take effect.

export ANDROID_SDK_HOME=$HOME/android-sdk-macosx
export PATH=$PATH:$ANDROID_SDK_HOME/tools
export PATH=$PATH:$ANDROID_SDK_HOME/platform-tools

The above configuration for OS X assumes that you located the Android SDK in your home directory. If you located it somewhere else, then adjust ANDROID_SDK_HOME accordingly.

If you're working from the lab computers, do the following instead:

export ANDROID_SDK_HOME=$HOME
export PATH=$PATH:/share/android-sdks/tools
export PATH=$PATH:/share/android-sdks/platform-tools

Don't forget to restart your terminal session to make sure the new settings are loaded. You might need to logout and log back in again.

Run the Android SDK Manager as follows.

android sdk

In the SDK manager window, install the Android SDK Tools, Android SDK Platform-tools, Android SDK Build-tools, and the most recent Android target (API 19 at the time of this writing).

Configure Android Device for Testing

If you don't have an Android device, then you will need to use the emulator that comes with the Android SDK. In this case, skip this section.

If you have an Android device that you can use for testing, then configure your phone to test apps you are developing. Depending on the version of Android that you are using, you will do something like the following.

Connect your phone to your computer with a USB cable. The cable will have a mini USB plug on one end for the phone and a regular USB plug on the other end for the computer.

Configure Android Emulator for Testing

If you have a physical Android device that you want to use for testing the application developed in this assignment, then you can skip this section.

Run the Android Virtual Device Manager as follows.

android avd

Create a new virtual device to use for testing. To make sure the emulator runs within the memory available on your computer, define a virtual device that has low resource requirements, such as supporting a small screen, low RAM, etc. Verify that you created a virtual device.

android list avd

Run the emulator with the AVD you created. Suppose that you named the virtual device andy. Use the following to launch the emulator.

emulator -avd andy

Determine Build Target

These instructions assume that you have the most recent version of Android and it is android-19. To check this, run the following command.

android list targets

If you see a version of Android later than android-19, then use that in place of android-19 in these instructions.

Install Apache Ant

Ant is an Apache Foundation project that is widely used for building systems written in Java. The Android SDK uses Ant. For this reason, you need to have ant installed on your system to complete the remainder of this assignment.

Ant depends on the Java development kit (JDK). Before installing ant, run the following command to see if the JDK is installed on your system.

javac -version

If the above command is not found, then you need to install the JDK. For this assignment and the remainder of the course, it is sufficient to install the JDK Standard Edition (JDK SE). I recommend that you install this version of the JDK.

After installing the JDK, use the following command to verify that the Java compiler is runnable from the command line.

javac -version

Go to the Apache Ant website and read a little of the documentation to get more familiar with it. Download and install it.

Ant is a command line tool. After installing Ant, use the following to check that you can run it from the command line.

ant -version

If the command is not found you should try 2 things. First, close your terminal window and open a new terminal window to make sure your environment is current; then try the command again. Second, modify your system path to include a path to the ant executable. If you do this, make sure you close and reopen a terminal window to make sure the environment is current.

If the command is found, but ant complains about not finding something in a JDK, then create an environmental variable named JAVA_HOME that points to the location of the JDK folder in your system. After setting this environmental variable, close and reopen your terminal window to make sure the environment is current.

Learn About Ant

The ant command looks for a file with the name build.xml that contains build targets. If a default target is specified in build.xml, then ant will run it. To run a specific target, specify the name of the target as an argument to the ant command. To see how this works, create file build.xml with the following contents.

<project>
  <target name="clean" description="Delete temp folder.">
    <delete dir="temp" />
  </target>
</project>

This build file contains a single target named clean, which deletes a folder named temp. Use the following command to run the clean target.

ant clean

If you get a command not found message when you try to run ant, it means that the folder containing the Ant executable is not in your system path. To solve this problem, add this folder to your system path.

Clean is a common target that is found in build files; its purpose is to delete generated files, such as java class files.

To see a list of all targets in a build file, run the following.

ant -projecthelp

Generate an Android Project Folder

In ~/405/mobile, run the following command to create an Android project named cse405. In Windows, replace the Unix line continuation character '\' with the Windows line continuation character '^'.

android create project            \
        --target android-19       \
        --name cse405             \
        --path ./android          \
        --activity MainActivity   \
        --package cse405.gift

The above command creates a folder named android and populates it with files that comprise a hellow world application. Notice that the android folder contains build.xml; this file contains targets that perform various build operations such as compile, install, clean, etc.

Generate a Public-Private Key Pair

To install an Android application, the installation file (apk file) needs to be signed. Our build script will sign the apk file with the keys that we provide to it. For this purpose, we will generate a key pair and self-signed certifcate. Create file ~/405/mobile/android/gen-keystore.sh with the following contents.

keytool -genkey                    \
        -alias dev                 \
        -keyalg RSA                \
        -keysize 2048              \
        -dname CN=localhost        \
        -keypass 123456            \
        -validity 10000            \
        -keystore cse405.keystore  \
        -storepass 123456

If you are on Windows, name the file gen-keystore.bat and substitute the Unix line continuation character '\' with the Windows line continuation character '^'.

In Linux and OS X, make the file executable with the following.

chmod +x gen-keystore.sh

Run the script and observe that a file named cse405.keystore was created. This file contains your key pair and self-signed certificate.

In the keystore, we set the alias of the generated key pair to dev because we will use this key for testing development builds of the application.

Test with the Hello World App

If you have a physical Android device that you prepared in the last section, then make sure it is connected to your computer. If you do not have a physical device for testing, then make sure the Android emulator is running.

Run the debug target of the Android build script to generate an apk file.

cd ~/405/mobile/android
ant debug

Observe that file bin/cse405-debug.apk was created. This is the application installer.

Run the installd target to install the application to your testing device.

ant installd

If you are on Windows and the system can not find the device, then read this comment.

To uninstall the app, run the uninstall target.

ant uninstall

Add Derived Files to .gitignore

Derived files should not be added to your repository. Add the following lines to ~/405/.gitignore to inform git of the files you do not want included in the repository. If this file does not yet exist, then create it.

/mobile/android/gen
/mobile/android/bin
/mobile/android/cse405.keystore
/mobile/android/local.properties

We also include the generated keystore file so that different developers can generate their own keystores. Normally, separate keystores are generated development, staging and production builds of an application.

Also notice that local.properties is not included in the repository. This file contains configuration that is particular to the local computer and therefore should not be shared between development environments. Read the comment inside local.properties.

Modify the Android Manifest File

Android applications use a file named AndroidManifest.xml to declare properties and requirements of the application to the end user's operating system. Because our application needs to connect to a Web application server, we need to request permission to access the Internet. To do this, add the following XML element to the root element of the AndroidManifest.xml.

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

If you don't understand XML and what a root element is, then you should familiarize yourself with the basic ideas of XML.

Notice references to @string/app_name in the manifest file. These are references to a string resource named app_name, which are defined in a file named strings.xml. In res/values/strings.xml, change the name of the application from MainActivity to CSE 405.

After making these changes, make sure you can still compile and install the application.

ant debug
ant installd

Verify that the application name is now CSE 405.

Incorporate the Gift Application Client

In this section, we create an instance of WebView in our Android application and have it load our client HTML file.

Replace the contents of res/layout/main.xml with the following.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<WebView  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
/>
</LinearLayout>

Replace the contents of src/cse405/gift/MainActivity.java with the following.

package cse405.gift;

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebChromeClient;
import android.webkit.ConsoleMessage;
import android.webkit.WebSettings;
import android.view.Window;
import android.util.Log;

public class MainActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        Log.i("cse405", "onCreate entered.");
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);
        WebView webView = (WebView) findViewById(R.id.main);
        webView.setWebChromeClient(new WebChromeClient() {
            public boolean onConsoleMessage(ConsoleMessage cm) {
                Log.d("cse405", cm.message()      + 
                                " -- From line "  +
                                cm.lineNumber()   + 
                                " of "            +
                                cm.sourceId()
                );
                return true;
            }
        });
        webView.getSettings().setJavaScriptEnabled(true);
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webView.loadUrl("http://192.168.1.6:5000/");
    }
}

Change the last line of the code to match the IP address of your computer. To determine your IP under Linux and OS X, use the ifconfig command. To determine your IP under Windows, use the ipconfig command.

With the above coode, there are 2 ways to write to the Android log. First, from inside the Java source code, make calls to the static functions of the Log class. Second, from inside the client Javascript, make calls to console.log. To test this, run the following 2 commands before running the application on your test device. The first command clears the log file. The second command starts a process that displays lines written to the log file, filtered to include only those lines associated with the tag cse405. See Reading and Writing Logs for more information.

adb logcat -c
adb logcat -s cse405

Compile and install revisions to the system.

ant debug
ant installd

Add a call to console.log from within your client Javascript to verify that output gets directed to the Android log. Then start (or restart) your Web application server. When you launch the application on your testing device, look at the logging output.