Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Hello Web Android

4.82/5 (3 votes)
1 Aug 2014CPOL7 min read 13.2K   345  
A simple but powerful HTML/JavaScript Hello World app template

Introduction

In this article, we will walk through a small Android app that uses a simple HTML page for its interface. You will learn how to connect JavaScript code to the app's Java code and have a foundation for any HTML/JavaScript based Android app. This is great for beginning Android app development with a web development background.

In this example, we will see how we can call Java code from JavaScript in order to save the user's name so we can say hello to them later. 

You should already have an Android development environment set up in order to try this. If you don't, you can enjoy looking through the code :)

It does not matter which IDE you are using. The goal of this article is to be independent of any IDE. I am using Eclipse ADT, and the attached project files have been exported from there.

Writing the Hello Web Android App

Step 1 - Create a New Project

In your IDE, create a new Android Application Project. Name the app Hello Web Android and start with an empty Activity.

Step 2 - Create the index.html Page

Because you may be more familiar with HTML and JavaScript, let's look at the index.html page we will use before moving on to the Java code. This HTML page will be displayed inside a WebView object in our Java code, and we will see how to do that in the next step.

Create a new file called index.html in the assets directory of your project. This directory should be inside the root directory of your project. Here are the contents of the file:

<html>
<head>
<style type="text/css">
body {
    background: #99AA99;
    font-size: 32px;
}
</style>
<script>

function askForName() {
    JavaCode.askForName();
}

function getGreeting() {
    var name = JavaCode.getName();
    if (name) {
        return "Hello " + name;
    } else {
        return "Press the button to tell me your name.";
    }
}

function updateGreeting() {
    document.getElementById("greetingDiv").innerText = getGreeting();
}

window.onload = function() {
    updateGreeting();
}

</script>
</head>

<body>
<div id="greetingDiv"></div>
<br /><br />
<button type="button" id="nameButton" onclick="askForName();">Change name</button>
</body>

</html>

It is a simple web page with a div element we will use to display a greeting message to the user and a button the user can click to set his or her name. In the JavaScript, notice something called JavaCode. This is the name of the JavaScript Interface we will pass to the WebView element in the next step.

Take a look at the simple JavaScript functions.

  • The askForName function will simply call a function in our app's Java code that is also called askForName. It will display a dialog box to the user asking for his name. 
  • The getGreeting function will return the greeting we will display to the user. Note that we will be calling a function from the Java code called getName. This will return the user's name that has been saved in our app. So, if there is no name saved, we will tell the user to click the button to set his name.
  • The updateGreeting function simply sets the text of the greetingDiv element on the page with the greeting message. We will call this right away from the window.onload function.

Step 3 - The Main Activity

The Main Activity is the class that is run when the app launches. In our case, it is setting up and displaying the WebView. In order to create the main activity, we need a layout file (an XML file that defines the elements that are displayed) and the MainActivity.java file that creates the view objects. When creating a new Android project in your IDE, it should create the MainActivity.java file in the src directory of your project and the activity_main.xml file in the res/layout directory. 

Here are the contents of the activity_main.xml file:

<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"
    tools:context="${relativePackage}.${activityClass}" >

    <WebView
        android:id="@+id/webViewMain"
        android:layout_width="fill_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

This is a simple example of an activity layout that uses a RelativeLayout object to hold other objects. In this case, the only thing in the RelativeLayout object is the WebView we will use to display our HTML page. Don't worry if you don't understand everything here, but make sure you see that the WebView object will be inside a RelativeLayout object, and we want it to fill the screen as much as it can. The main area of the Android app will be filled with our WebView object. 

Now, let's see how the MainActivity.java file creates the UI from our activity_main.xml file. Here are the contents of the MainActivity.java file:

package com.hello.hellowebworld;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.webkit.WebChromeClient;
import android.webkit.WebView;

@SuppressLint("SetJavaScriptEnabled")
public class MainActivity extends Activity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        WebView myWebView = (WebView) findViewById(R.id.webViewMain);

        myWebView.setWebChromeClient(new WebChromeClient());
        myWebView.getSettings().setJavaScriptEnabled(true);
        
        JavascriptBridge jsb = new JavascriptBridge(this, getPreferences(Context.MODE_PRIVATE), myWebView);

        myWebView.addJavascriptInterface(jsb, "JavaCode");

        myWebView.loadUrl("file:///android_asset/index.html");
    }
}

There's not too much here. The onCreate method is called when the activity is created, that is, when the app is launched. There is a call to the setContentView method that references R.layout.activity_main. R is a reference to our resources, so getting the activity_main layout makes sense. This is how our activity_main.xml file is used to build the UI. 

In order to set up the WebView to show our index.html page, we get the WebView object with the findViewById method by passing in the id of the WebView as defined in our activity_main.xml file. Once we have the WebView, we set JavaScript enabled, create and add a JavaScript Interface, and we tell it to load our index.html page. 

The JavascriptBridge class we pass into the WebView as a JavaScript Interface is the only piece of code we have yet to look at. In the code above, you see how we add the JavaCode reference to the WebView. Now, let's look at how our JavascriptBridge class works. 

Step 4 - Creating a JavaScript Interface

In the MainActivity.java class, we passed an instance of the JavascriptBridge class to the WebView to be our JavaScript Interface. This means the JavaScript code in the WebView can call certain methods of the JavascriptBridge object. Let's see how this is set up in the code, and how we can also use the JavascriptBridge object to make calls to the JavaScript code in the WebView object. Here are the contents of the JavascriptBridge.java file:

package com.hello.hellowebworld;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.text.InputType;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.widget.EditText;

public class JavascriptBridge {
    
    private static final String NAME_KEY = "Name";
    
    SharedPreferences sharedPref;
    Context context;
    WebView webView;

    public JavascriptBridge(Context ctx, SharedPreferences preferences, WebView wv) {
        sharedPref = preferences;
        context = ctx;
        webView = wv;
    }
    
    @JavascriptInterface
    public void askForName() {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle("What is your name?");

        // Set up the input
        final EditText input = new EditText(context);
        // Specify the type of input expected
        input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
        builder.setView(input);

        // Set up the buttons
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
            @Override
            public void onClick(DialogInterface dialog, int which) {
                changeName(input.getText().toString());
            }
        });
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });

        builder.show();
    }

    protected void changeName(String name) {
        setName(name);
        webView.loadUrl("javascript:updateGreeting()");
    }

    protected void setName(String name) {
        SharedPreferences.Editor editor = sharedPref.edit();
        editor.putString(NAME_KEY, name);
        editor.commit();
    }
    
    @JavascriptInterface
    public String getName() {
        return sharedPref.getString(NAME_KEY, null);
    }
}

First, let's look at the instance variables in this class. We have a SharedPreferences object - we use this to save key-value pairs of data in the app, such as the user's name. It is passed in through the constructor from the MainActivity class. The Context object is really a reference to our MainActivity class that is passed in through the JavascriptBridge constructor as well, and it is needed to create dialogs that are shown to the user. The WebView object is also passed in through the constructor. It is a reference to the main WebView that is showing our index.html file. 

Now, look at the methods the JavascriptBridge class has:

  • The askForName method has an annotation: @JavascriptInterface. This annotation is means that the method is available to call from the JavaScript code in the WebView. Inside the method, a dialog is created that prompts the user to input their name and hit OK. When OK is clicked, the changeName method is called. If Cancel is clicked, we simply close the dialog without taking any more action.
  • The changeName method calls the setName method, which saves the user's name through our app's SharedPreferences object, and then calls the JavaScript function updateGreeting in the WebView. This will execute the updateGreeting function we looked at earlier in our index.html file.
  • The setName function is an example of how to save a key-value pair to the app's SharedPreferences. In this case, the user's name.
  • The getName method has the @JavascriptInterface annotation, so it is available to be called from our index.html page inside the WebView. All this does is return the user's name value that is saved in the app's SharedPreferences.

Running the App

Now, with the project complete, you can run the app on an emulator or a physical device. How to go about setting up an emulator or device to test may vary based on which IDE you are using. Run the app and try it out! Here's a screenshot walkthrough of how the app looks.

First launch:

Hello Web Android App on first launch

Setting your name:

Setting your name in the app

After I type in my name, Zach, and hit OK, the greeting displayed:

Greeting displayed to the user

Now, the app remembers me! Whenever I open it, my name is saved and it says hello.

Want a small challenge? Take this app and add a button to the index.html page that can be clicked to have the app forget the saved name. Write the additional Java and JavaScript code needed to do this.

Conclusion

For the sake of this example, this app uses a dialog in Java to get the user's name. That could easily be done from the HTML page instead! With this simple template, you have the basis for creating Android apps with interfaces built in HTML and JavaScript. You also know how to connect to the Java code to do things you are unable to from a web page. 

Now, try packaging up your own web app into an Android app today!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)