Android web application in full screen
Web applications in the Android Browser
On iOS you can turn any web page into a installable application by using some HTTP-Headers (see the documentation). This adds a button in the browser which adds the Website as full screen application to the home screen of the iOS-Device.
On Android on the other hand, there is no such feature: Websites and web apps can only bookmarked. These bookmarks still live in the browser window, so the address-bar is shown which uses a lot of space on the screen and is useless in a web application context.
There are some JavaScript Hacks which try to hide the browsers address bar by scrolling the window (for example see the following StackOverflow questions: 1, 2). These solution do not work well if your web application resizes the document itself and are very unstable and only work after the web page has been fully rendered.
The only solution for Android devices is to implement a small application using Java which starts in full screen, creates a own Browser window (a so called WebView) and then loads the web page desired.
Full screen Web apps on Android
There are some pitfalls when implementing a WebView in Android:
- Full screen: Best implemented by a
android:themedirective. Additionally, the scroll bars have been configured to be displayed inside the browser window. - Rotation: Per default, Android apps get restarted when the device
orientation changes. This makes the website rerender which is undesirable.
Adding a
android:configChangesdirective fixes that. - JavaScript: Per default, JavaScript is not enables in WebViews.
- HTML5 Storage: LocalStorage and WebDB are not enabled and can not be enabled on devices with android versions lower than 2.1. To enable the HTML5 features without breaking backwards compatibility, reflection is used.
- Back-Key: The back key on the Android phone should make the webpage go back.
The following code is enough to achieve the features mentioned above. Additionally, the menu key is mapped to a refresh function, if you don’t like this, delete the three lines of code.
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="[package-name here]"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="4" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".WebAppActivity"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:configChanges="orientation|keyboardHidden|keyboard"
>
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
WebAppActivity.java:
package [Your Package];
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
public class WebAppActivity extends Activity {
private WebView wv;
private static final String TAG = "[YOUR Tag]";
//Change to your webapp-url
private static final String url = "http://en.wikipedia.org";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
wv = (WebView) findViewById(R.id.webview);
wv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
WebSettings ws = wv.getSettings();
ws.setJavaScriptEnabled(true);
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.ECLAIR) {
try {
Log.d(TAG, "Enabling HTML5-Features");
Method m1 = WebSettings.class.getMethod("setDomStorageEnabled", new Class[]{Boolean.TYPE});
m1.invoke(ws, Boolean.TRUE);
Method m2 = WebSettings.class.getMethod("setDatabaseEnabled", new Class[]{Boolean.TYPE});
m2.invoke(ws, Boolean.TRUE);
Method m3 = WebSettings.class.getMethod("setDatabasePath", new Class[]{String.class});
m3.invoke(ws, "/data/data/" + getPackageName() + "/databases/");
Log.d(TAG, "Enabled HTML5-Features");
}
catch (NoSuchMethodException e) {
Log.e(TAG, "Reflection fail", e);
}
catch (InvocationTargetException e) {
Log.e(TAG, "Reflection fail", e);
}
catch (IllegalAccessException e) {
Log.e(TAG, "Reflection fail", e);
}
}
wv.loadUrl(url);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && wv.canGoBack()) {
wv.goBack();
return true;
}
else if (keyCode == KeyEvent.KEYCODE_MENU) {
wv.loadUrl(url);
return true;
}
return super.onKeyDown(keyCode, event);
}
main.xml (Layout):
<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbarStyle="insideOverlay"
/>