Sep 15 2009

Replacing menus with dashboards

Category: Android,Ideas,MobileAleksander Kmetec @ 10:00 am

Is it just me, or do most dialogs on Android seem to be removed really, really far away from the main parts of applications?

Not sure what I’m talking about?

Let’s take a look at the browser, for example. Just entering a new URL requires you to go through 3 different screens:

By the time you can start typing it feels like you’re already in a different application1. Switching to a different window also involves going to a special part of the application designed to handle this single task.

This pattern is not limited just to the browser. Entering an address in the maps application or searching the list of your contacts also involves going through several steps.

Back to the browser…

If you take a look the UI of a regular browser you can immediately see a number of frequently used elements such as the location bar, the back button and tabs for switching between windows. Those UI elements are always visible and usable with a single click. On mobile devices things are a bit different. Because of limited screen sizes most of browser’s UI is either eating away precious screen real estate (like on the iPhone) or is hidden behind a menu button (like on Android).

Except that because of the nature of menus, many of those features are not hidden just behind the menu button, but also behind an item on that menu.

Now, just as I’m typing this, Marissa Mayer is on the stage at TechCrunch50 introducing Google fast flip and talking about how Google is obsessed with speed and shaving milliseconds off of repetitive interactions. So what can can we do to speed up interaction with Google’s mobile browser?

First, we need to understand what’s wrong with menus.

A typical menu is a list of actions available for that application, but most of those actions can’t be performed from the menu itself. Instead, selecting an item takes you somewhere else where that action can finally be performed. In essence, a menu keeps asking the question “What do you want to do?” over and over again and the user then needs to explicitly say that he wants to go to to the place where he can type in an URL or go to the place where he can switch to a different window, etc.

How do we handle this situation where we know that in many applications the user’s answer to the menu’s question is going to be the same most of the time?

Like it is the case usually these days, the solution can already be found on the iPhone. No real surprise there. The iPhone doesn’t have built-in support for application menus which could be copied, but it does have this:

What you’re looking at is a special dashboard for controlling music playback, which can be brought up by pressing the home button twice.

With a bit of bad luck – or bad judgment – this could have easily been implemented as a list of items such as “adjust volume” and “control playback”, with each of them leading to a new screen where that action could be performed. But instead its designers made it possible to perform common actions directly from the pop-up and added a “Music” button that takes you to that other app where the rest of the playback controls are.

So let’s take this dashboard pattern and apply it to Android’s browser menu:

2_alt1_small

While some features (like bookmarks) still remain hidden behind a menu button, the two most commonly used ones are immediately presented in usable form. The “go” button is replaced by an actual location bar and the “Windows” button is replaced by thumbnails of windows. You now no longer need to announce first that you want to go to a different page or switch to a different tab; you can perform that action directly instead.

A quick before/after comparison:

Action Before After
Loading a web page press “menu” → press “go” → focus URL field (3 steps) press “menu” → focus URL field (2 steps)
Switching to a different window press “menu” → press “tabs” → select tab (3 steps) press “menu” → select tab (2 steps)

Removing a single step here and there may not seem like much, but it adds up. Making a typo in the URL or working with several windows suddenly becomes just a little bit less frustrating. A simple improvement that can be achieved simply by ignoring the established meaning of the word “menu”.

  1. Sure, if you have a phone with a physical keyboard you can just start typing and invoke the default action without going through menus, but what if your phone uses an onscreen keyboard or if you want to use some other action?

Tags: , , , , , ,


Feb 22 2009

How is Mosembro different from OilCan?

Category: Android,MosembroAleksander Kmetec @ 4:42 am
Alternate logo.
Image via Wikipedia

If you looked at OilCan – a Greasemonkey-like browser extension for Android – and Mosembro, you’d quickly realize that they have a lot in common. Both are experimental browser extensions which run on Android, both aim to make websites friendlier, both support installable actions written in JavaScript, and both make it possible for those scripts to modify web pages and launch other applications. And since looking at OilCan’s source code has allowed me to avoid reinventing the wheel at several occasions, some pretty obvious similarities can also be spotted at the source code level.

So, with so many things in common, how are they different at all?

The main difference, I believe, is what causes user scripts to be triggered. A typical OilCan script is triggered by a web page’s URL and is executed only once. Its goal is to change the content or functionality of a very specific document. Mosembro scripts, on the other hand, are triggered by embedded microformats and can be executed dozens of times for each page, while not caring about which page they were executed on.

I could say at this point that OilCan’s approach to invoking scripts could be compared to function calls in programming languages and Mosembro’s approach compared to what is done in aspect oriented programming, with functionality implemented by actions attached to bits of semantic content being cross-cutting concerns, but I’m not sure about it, so I won’t. ;-)

Also, because Mosembro is very narrowly focused on adding functionality to web pages based on semantic data embedded in them it can also provide additional infrastructure, like microformat parsers and action menus, which wouldn’t exactly fit in with a more general purpose framework. And finally, there’s the integrated support for site-level search.

So, there you have it. While it’s true that both apps have a lot in common, it’s their unique features that really matter.

Reblog this post [with Zemanta]

Tags: , , ,


Feb 19 2009

Mosembro r5 now available for download

Category: Android,Mobile,Mobile web,Mosembro,UncategorizedAleksander Kmetec @ 8:59 pm

The first major Mosembro release after r2 is now available for download.

If you already have Mosembro installed, uninstall it first by running: adb uninstall com.lexandera.mosembro
The new version can then be installed by executing the following command: adb install mosembro-r2.apk

New features include:

  • It is now possible to install addidional actions which extend Mosembro’s functionality.
  • Addresses can be copied to clipboard.
  • Improved security and various bugfixes.

Screenshots of new features:

Mosmbro r5 screenshots

Mosembro r5: dialogs for installing and managing installed actions

Several simple actions can be installed from the bottom of the demo page which is loaded when Mosembro starts up. Go & try them out.


Feb 01 2009

Intercepting page loads in WebView

Category: Android,WebView examplesAleksander Kmetec @ 6:20 am

It is time for another WebView example. This time on how you can intercept any attempts at loading a web page and redirect the user to a different URL instead.

This can be achieved simply by registering a WebViewClient which overrides the shouldOverrideUrlLoading() method in which you tell the WebView to load a different URL from the one the user had requested.

The example below loads lexandera.com first, but when the user clicks any link on the page, he is redirected to yahoo.com:


WebView browser = (WebView)findViewById(R.id.browser);
browser.setWebViewClient(new WebViewClient() {
    /* On Android 1.1 shouldOverrideUrlLoading() will be called every time the user clicks a link,
     * but on Android 1.5 it will be called for every page load, even if it was caused by calling loadUrl()! */
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url)
    {
        /* intercept all page load attempts and load yahoo.com instead */
        String myAlternativeURL = "http://yahoo.com";
        if (!url.equals(myAlternativeURL)) {
            view.loadUrl(myAlternativeURL);
            return true;
        }
        
        return false;
    }
});

browser.loadUrl("http://lexandera.com/");

Please note that calling loadUrl() does not trigger the shouldOverrideUrlLoading() method, which means that we do not need to worry about endless recursion when calling loadUrl() from within shouldOverrideUrlLoading()!

UPDATE: The above statement is no longer true for Android 1.5! Calling loadUrl() will now also trigger the shouldOverrideUrlLoading() method! This means that you need to make sure that you are not creating an infinite loop when calling loadUrl() from shouldOverrideUrlLoading()!

Reblog this post [with Zemanta]

Tags: , ,


Jan 29 2009

Extracting HTML from a WebView

Category: Android,Semantic Web,Uncategorized,WebView examplesAleksander Kmetec @ 8:30 pm

Here’s another Android WebView tutorial for those of you who are looking for a way to get the source code of a page loaded in a WebView instance.

This example is a bit more complicated than previous ones, so let me explain it step by step:

  • First, a class called MyJavaScriptInterface is defined. It implements a single public method showHTML() which displays a dialog with the HTML it receives as a parameter.
  • Then, an instance of this class is registered as a JavaScript interface called HTMLOUT. The showHTML() method can now be accessed from JavaScript like this: window.HTMLOUT.showHTML(‘…’)
  • In order to call showHTML() when the page finishes loading, a WebViewClient instance which overrides onPageFinished() is added to the WebView. When the page finises loading, this method will inject a piece of JavaScript code into the page, using the method I described in an earlier post.
  • Finally, a web page is loaded.

final Context myApp = this;

/* An instance of this class will be registered as a JavaScript interface */
class MyJavaScriptInterface 
{
    @SuppressWarnings("unused")
    public void showHTML(String html)
    {
        new AlertDialog.Builder(myApp)
            .setTitle("HTML")
            .setMessage(html)
            .setPositiveButton(android.R.string.ok, null)
        .setCancelable(false)
        .create()
        .show();
    }
}

final WebView browser = (WebView)findViewById(R.id.browser);
/* JavaScript must be enabled if you want it to work, obviously */ 
browser.getSettings().setJavaScriptEnabled(true);

/* Register a new JavaScript interface called HTMLOUT */
browser.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");

/* WebViewClient must be set BEFORE calling loadUrl! */
browser.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url)
    {
        /* This call inject JavaScript into the page which just finished loading. */
        browser.loadUrl("javascript:window.HTMLOUT.showHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
    }
});

/* load a web page */
browser.loadUrl("http://lexandera.com/files/jsexamples/gethtml.html");

WARNING
Unfortunately, this approach suffers from a major security hole: if your JavaScript can call showHTML(), then so can JavaScript from every other page that might get loaded into the WebView. Use with care.

Reblog this post [with Zemanta]

Tags: , , ,


Jan 28 2009

Mosembro r2 now available for download

Category: Android,Mobile,Mobile web,MosembroAleksander Kmetec @ 3:45 am

The second release of Mosembro is now available for download.

If you already have Mosembro installed, uninstall it first by running: adb uninstall com.lexandera.mosembro
The new version can then be installed by executing the following command: adb install mosembro-r2.apk

Major changes from r1:

  • Multiple actions can now be attached to a single link.
  • Microformat parsing logic was separated from action logic. Each microformat is parsed only once now and parsed data is then passed to one or more actions registered to handle that microformat.
  • Two new “travel to…” actions were added for addresses. One uses London Journey Planner and the other one uses Bay Area Trip Planner
  • alert(), confirm() and prompt() JavaScript functions now work.

Here is an example screenshot of multiple actions on one link:

Multiple actions for one link

Multiple actions attached to one link

More screenshots and/or a video should be available in a couple of days.


Next Page »