Skip to content

Posts from the ‘Projects’ Category

Feb 3 10

WebApp – An Android experiment

After thinking about a JavaScript API to allow alerts on an Android phone in this post, I came up with a method of adding this using the current Java Android app API. The solution involves starting a Webkit instance in a custom app, and intercepting links with a certain prefix. In this example android://alert/description creates an alert with title “alert” and description “description”.

To demonstrate here are some screenshots of a sample page using a sample application (if you have an Android phone you can use that link to download it and try it yourself):

The application when you load it:

When clicking go an alert is created:

Viewing the created alert:

The example page is very simple javascript:

function go() {
	window.location = 'android://'+document.getElementById('title').value
		+'/'+document.getElementById('text').value;
}

The source for the app follows and is also fairly simple, most of the code is the rather complex way alerts are generated on Android:

package uk.co.connorhd.android.webapp;
 
import java.net.URLDecoder;
 
import uk.co.connorhd.android.webapp.R;
import uk.co.connorhd.android.webapp.WebApp;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
 
public class WebApp extends Activity {
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WebView webview = new WebView(this);
 
    // We're testing, clear the cache.
    webview.clearCache(true);
 
    setContentView(webview);
 
    webview.getSettings().setJavaScriptEnabled(true);
 
    final Activity activity = this;
    webview.setWebViewClient(new WebViewClient() {
      int alert = 1;
 
      public void onReceivedError(WebView view, int errorCode,
          String description, String failingUrl) {
        Toast.makeText(activity, "Oh no! " + description,
            Toast.LENGTH_SHORT).show();
      }
 
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
        // Is it a hack?
        if (url.startsWith("android")) {
          String ns = Context.NOTIFICATION_SERVICE;
          NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
          int icon = R.drawable.icon;
          CharSequence tickerText = "WebApp Alert!";
          long when = System.currentTimeMillis();
 
          Notification notification = new Notification(icon,
              tickerText, when);
          notification.flags = Notification.FLAG_AUTO_CANCEL;
          Context context = getApplicationContext();
 
          String[] split = url.split("/");
 
          CharSequence contentTitle = URLDecoder.decode(split[2]);
          CharSequence contentText = URLDecoder.decode(split[3]);
 
          Intent notificationIntent = new Intent(activity,
              WebApp.class);
          PendingIntent contentIntent = PendingIntent.getActivity(
              activity, 0, notificationIntent, 0);
 
          notification.setLatestEventInfo(context, contentTitle,
              contentText, contentIntent);
 
          mNotificationManager.notify(alert++, notification);
        } else {
          view.loadUrl(url);
        }
        return true;
      }
    });
 
    webview.loadUrl("http://connorhd.co.uk/files/WebApp.htm");
  }
}

This could easily be extended (and I may try to do this myself for Ircster) to provide all the standard browser functionality (for example the back button doesn’t currently work) and a more complete API to interface with Android.

Jan 25 10

node_debug – A debugging console over HTTP

I’d also like to use my blog to write about a few of my personal projects. Many of these aren’t very useful and very few actually reach any usable state, however I feel node_debug is actually something quite useful.

Before reading this post you should probably know what node.js is.

node_debug allows you to evaluate statements and view their result (much like a REPL) from your favourite browser (assuming your favourite browser isn’t IE). It also allows you to browse objects if the result of your statement is an object, for example the global object in node is process so executing process; will return a browsable tree structure of the global scope.

Additionally it exports a log function that allows you to asynchronously output to any active console, for example setTimeout(function () { debug.log("Hello") }, 5000); will output Hello to any open consoles after 5 seconds, allowing useful debug output when using asynchronous functions.

To get started using node_debug you need to have a server running node, and to grab the latest node_debug from github. There is an example.js included to show how you would include it in your own scripts, the idea being you can simply include this in your own project in order to easily debug issues.

Future features I would like to add include:

  • A debug.scope object that allows you to import other objects into the debuggers scope (currently only the global scope is available which can cause confusion due to closures in JavaScript hiding a lot of variables from the debugger).
  • debug.error/warn/info functions in line with the browser console object provided by firebug.
  • Detect disconnection from node and attempt reconnection.
  • Caching of asynchronous messages that can be shown when connecting to the console, in order to log things without having an active browser window all the time.