TABLE OF CONTENTS (HIDE)

Android: Building Webapps in WebView & Count-down Timer

A Count-Down Timer Example

Reference: "CountDownTimer" @ https://developer.android.com/reference/android/os/CountDownTimer.html.

Start a Android Studio project called "Count Down Timer" with "Empty Views Activity".

Define the Layout in "res\Layout\activity_main.xml"

We use the TextView (from the Hello-world template) to display our timer.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/txtTimer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Program the "MainActivity.java"

Android SDK provides an android.os.CountDownTimer class, which implements a countdown timer.

package com.example.countdowntimer;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private TextView txtTimer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtTimer = (TextView)  findViewById(R.id.txtTimer);
        // Count down from 30 sec. onTick() every second. Values in milliseconds
        new CountDownTimer(30000, 1000) {
            public void onTick(long millisRemaining) {
                txtTimer.setText("Seconds remaining: " + millisRemaining / 1000);
            }
            public void onFinish() {
                txtTimer.setText("Time Up!");
            }
        }.start();
    }
}

Using WebView by Example

References: Building web apps in WebView @ https://developer.android.com/guide/webapps/webview.

The WebView objects allow you to display web content as part of your activity layout, i.e., a simple browser. However, it lack some of the features of full-function browsers.

Example 1: Two Activities

In this example, we shall create two activities (screens) (See "Example: Using an Intent to Start a Second Activity"). The first activity (MainActivity) contains a button to request for a web page. Clicking the button launches the second activity (WebViewActivity) showing the requested web page inside a WebView object.

WebView Example
Step 1: Start a new Project

Start a new Android project with "Empty Views Activity", called "Test WebView".

Step 2a: Define Layout in "res\layout\activity_main.xml"

Replace the existing XML file with the following:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <Button
        android:id="@+id/btnGo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="GO"
        android:onClick="btnGoHandler" />
</LinearLayout>

We use LinearLayout to hold one "GO" button, which triggers "buttonGoHandler" on click.

Step 2b: Program "MainActivity.java"
package com.example.testwebview;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);  // use "res/layout/activity_main.xml"
    }

    /** Callback when the user click the "GO" button */
    public void btnGoHandler(View view) {
        // Create an Intent to start the second activity called "WebViewActivity"
        Intent intent = new Intent(this, WebViewActivity.class);
        // Start the intended activity
        startActivity(intent);
    }
}

The button handler creates an Intent and starts the "WebViewActivity".

Step 3a: Create a Second Activity "WebViewActivity" for an WebView Object

Right-click on "Java" node ⇒ "New" ⇒ "Activity" ⇒ "Empty Views Activity" ⇒ In "Activity Name", enter "WebViewActivity" ⇒ In "Layout Name", enter "activity_web_view" (default) ⇒ In "Package name", enter "com.example.testwebview" (default) ⇒ Finish.

Step 3b: Define Layout in "res\layout\activity_web_view"

This layout (in RelativeLayout) contains one Button (for future use) and one WebView object, as follows:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <Button
        android:id="@+id/btnTodo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="FOR FUTURE USE" />
    <WebView
        android:id="@+id/webView"
        android:layout_below="@id/btnTodo"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</RelativeLayout>
Step 3b: Program "WebViewActivity.java"
package com.example.testwebview;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.WebView;

public class WebViewActivity extends AppCompatActivity {
    private WebView webView;  // for displaying web contents

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view);

        webView = (WebView) findViewById(R.id.webView);
        //webView.getSettings().setJavaScriptEnabled(true);

        // URL hardcoded
        webView.loadUrl("https://www.google.com");  
        //webView.loadUrl("http://10.0.2.2:9999/hello/sayhello");  // Your Tomcat's (localhost:9999) hello app
                  // 10.0.2.2 is the special IP for the host machine of the emulator.
        //webView.loadUrl("http://ip_addr:port/hello/sayhello");   // Your Tomcat's hello app
    }
}

The WebView object invokes loadUrl() to load a hardcoded URL.

Take note that you cannot use localhost (127.0.0.1) to refer to the server on the host machine of the emulator. Localhost refers to the android emulator. You can use a special IP 10.0.0.2 to refer to the host machine of the emulator.

Step 4: Modify "AndroidManifest.xml"

The the lines in red to the generated manifest.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testwebview">

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

    <application
        android:usesCleartextTraffic="true"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".WebViewActivity"></activity>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Notes: android:usesCleartextTraffic="true" is needed to support HTTP; otherwise, only HTTPS is supported.

Step 5: Run the app

Try running the app. Make sure that you emulator/phone has 3G/4G/5G signal for network connection! otherwise???

Step 6: Try

Try modify the "FOR FUTURE USE" button as "BACK" button to return to the first activity.

Example 2: One Activity

In this example, we have one activity that contains a EditText for entering the URL, a Button to trigger the URL and a WebView to display the web page.

Step 1: Start a new Project

Start a new Android project with "Empty Views Activity", called "Test WebView 2".

Step 2a: Define Layout in "res\layout\activity_main.xml"
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <EditText
        android:id="@+id/txtURL"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="https://www.google.com/" />
    <Button
        android:id="@+id/btnGo"
        android:layout_below="@id/txtURL"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="GO"
        android:onClick="btnGoHandler" />
    <WebView
        android:id="@+id/webView"
        android:layout_below="@id/btnGo"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</RelativeLayout>
Step 2b: Program "MainActivity.java"
package com.example.testwebview2;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {
    private WebView webView;  // for displaying web contents
    private EditText txtURL;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        webView = (WebView) findViewById(R.id.webView);
        //webView.getSettings().setJavaScriptEnabled(true);
        txtURL = (EditText) findViewById(R.id.txtURL);
    }

    /** Callback when the user click the "GO" button */
    public void btnGoHandler(View view) {
        // show the web page of the URL of the EditText
        webView.loadUrl(txtURL.getText().toString());
    }
}
Step 3: Modify "AndroidManifest.xml"

The the lines in red to the generated manifest.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testwebview">

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

    <application
        android:usesCleartextTraffic="true"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Notes: android:usesCleartextTraffic="true" is needed to support HTTP; otherwise, only HTTPS is supported.

Step 4: Run the App

Try these URLs (https and http):

  • https://www.google.com
  • http://10.0.2.2:9999/hello/sayhello (Your localhost Tomcat's hello app - 10.0.2.2 is a special IP for the host machine of the emulator)
  • http://ip_addr:port/hello/sayhello

Take note that you cannot use localhost (or 127.0.0.1) to refer to the server on the host machine of the emulator. The localhost refers to the android emulator. You can use a special IP 10.0.0.2 to refer to the host machine of the emulator.