Back to Silas S. Brown's home page

Android viewer app for static HTML

This is a method for making a standalone Android "app" from a collection of static HTML and Javascript files, such as files from Offline HTML Indexer or Charlearn mobile. Apps made using the files below should run on any version of Android (v1+), and extra Javascript functions are provided to place text on the Android clipboard.

Packaging an offline site as an app makes it easier for beginners to install, but it does mean the app will not automatically copy any "accessibility" options that were set in the main browser. This app (v1.3+) will copy the system text size (so if someone has set a larger font in system settings, they'll get it), but the range of fonts available from the system settings is typically less than that available from the browser settings. (In Android 1.5+ "pinch to zoom" also works in the app, but in Android 4.4+ this does not reflow the text.) For maximum accessibility, always ship an alternative version of your HTML that is not packaged as an app.

If your app uses "local storage", this requires Android 2.1+ (you can use localStorage.setItem etc in scripts; 'cookies' tend not to work).

UTF-8 encoding is assumed.

Instructions for old Android Developer Tools

In June 2015 Google deprecated the Android Developer Tools (ADT), and in June 2017 removed the download, saying "you should immediately switch" to the newer Android Studio. Since Android Studio does not work on all equipment, you might find these instructions for the older ADT useful if you happen to have downloaded it before June 2017. App updates compiled in old ADT might be rejected by Google's "Play Store" after November 2018 due to new targetting requirements, but may still be "side-loadable" on some devices, plus it's possible to increase the old ADT's "target API level" beyond its original range when using the command line.
  1. In ADT, go to File / New / Android application project
  2. Enter the following information:
    Application NameAny short name you wish (will be shown in the phone's app menu)
    Project Nameanything you want (just needs to be unique on your development computer)
    Package Nameorg.ucam.ssb22.html
    Minimum Required SDKAPI 1: Android 1.0
    or API 7 if you use local storage
  3. Leave everything else as default, but make a note of the project directory (probably mentioned on the second setup screen as "location")
  4. Switch out of ADT, and unpack this html2apk.zip into the project directory, saying "yes" to overwrite (it should overwrite 2 files)
  5. If you use local storage, edit src/org/ucam/ssb22/html/MainActivity.java and uncomment the lines as instructed
  6. (Optional) If you don't want your app to be reloaded with every screen or keyboard change, edit the top-level AndroidManifest.xml file and after <activity put android:configChanges="orientation|screenSize|keyboardHidden" (you will likely need to re-start the ADT after saving this edit)
  7. If you are distributing your app to others, or if you intend to load more than one HTML-based app onto your device, please change the package name (in AndroidManifest.xml and MainActivity.java, and by renaming the directories under src) to a (sub)domain you own. This is needed because, if another application already on the device has the same package name, then installing yours will overwrite the one that's already there and vice versa. (But if you change the package name when the app is already deployed, attempts to install the new version will leave the previous version on the device as well.)
  8. Place your HTML (and any related files) into the assets subdirectory, with index.html as the starting page
  9. Back in ADT, go to Run / Run As / Android application. It should let you launch a virtual Android device. It's probably best not to interact with the virtual Android device until the ADT has finished setting it up (check for messages in ADT's Console window). If the install fails, try Run again.
  10. If the install is successful, then you should see your application running when you unlock the Android device in the emulator.
  11. The .apk file will have by this time been placed in the bin subdirectory of the project directory. This file can be copied to a Web server and linked to. (A connection will be required for installing from the Web, but not for usage later.) It might be necessary to go to "Application settings" or "Security" and enable "Unknown sources" before the app will install on a real phone.

Command line

Command-line builds are easier to automate, and also work if you've upgraded to the newer Android Studio---you just need to make sure the directories are set correctly for SDK etc. Here is an example:

export SDK=/usr/local/adt-bundle-mac-x86_64-20140702/sdk # or whatever
export PLATFORM=$SDK/platforms/android-19 # or whatever
export BUILD_TOOLS=$SDK/build-tools/21.0.2 # or whatever
export KEYSTORE_USER=my_user_id # if you want to sign the apk
export KEYSTORE_PASS=my_password # ditto
cd /path/to/your/app/workspace &&
rm -rf bin gen && mkdir bin gen &&
$BUILD_TOOLS/aapt package -v -f -I $PLATFORM/android.jar -M AndroidManifest.xml -A assets -S res -m -J gen -F bin/resources.ap_ &&
javac -classpath $PLATFORM/android.jar -sourcepath "src;gen" -d "bin" src/org/ucam/ssb22/html/*.java gen/org/ucam/ssb22/html/R.java && # change this to your package name
$BUILD_TOOLS/dx --dex --output=bin/classes.dex bin/ &&
cp bin/resources.ap_ bin/AppName.ap_ && # change AppName here and all instances below
cd bin &&
$BUILD_TOOLS/aapt add AppName.ap_ classes.dex &&
cd .. &&
jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore ../keystore -storepass $KEYSTORE_PASS -keypass $KEYSTORE_PASS -signedjar bin/AppName.apk bin/AppName.ap_ $KEYSTORE_USER -tsa http://timestamp.digicert.com && # -tsa option requires an Internet connection
rm -f ../AppName.apk &&
$BUILD_TOOLS/zipalign 4 bin/AppName.apk ../AppName.apk &&
rm bin/*ap_ bin/*apk &&
cd .. || exit 1
adb -d install -r AppName.apk || true # no error if device not connected


All material © Silas S. Brown unless otherwise stated.
Android is a trademark of Google LLC.
Google is probably a trademark of Google LLC.
Javascript is a trademark of Oracle Corporation in the US.
Any other trademarks I mentioned without realising are trademarks of their respective holders.