Wednesday, 18 January 2012

Saving map images in Android

Recently I've been working on a little Android project and wanted to save thumbnail images of a map within the application. This post is just sharing how to do exactly that. Nothing too complicated.

public class MyMapActivity extends MapActivity {
    private MapView mapView;

    ...

    private Bitmap getMapImage() {
        /* Position map for output */
        MapController mc = mapView.getController();
        mc.setCenter(SOME_POINT);
        mc.setZoom(16);

        /* Capture drawing cache as bitmap */
        mapView.setDrawingCacheEnabled(true);
        Bitmap bmp = Bitmap.createBitmap(mapView.getDrawingCache());
        mapView.setDrawingCacheEnabled(false);

        return bmp;
    }

    private void saveMapImage() {
        String filename = "foo.png";
        File f = new File(getExternalFilesDir(null), filename);
        FileOutputStream out = new FileOutputStream(f);
    
        Bitmap bmp = getMapImage();
    
        bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
    
        out.close();
    }
}

In the getMapImage method, we're telling the map controller to move to a particular point (this may not matter to you, you may just want to take the image as it appears) and zooming in to show a sufficient level of detail. Then a Bitmap is created from the map view's drawing cache. The saveMapImage method is just an example of how you may want to save an image to the application's external file directory.

Tuesday, 13 December 2011

Virtual keyboards and "feelable" touchscreens


Senseg made a splash recently when they revealed their touchscreen technology which allows you to actually "feel" objects on-screen. By manipulating small electric charges, users can actually feel texture as they interact with a touchscreen. It'd be too easy to dismiss this as a gimmick, however I think this type of technology has the potential to make a positive impact on mobile devices.

Touchscreens are becoming increasingly ubiquitous in mobile devices, leading to the demise of the hardware keyboard. A glance at the list of all HTC phones in their current line-up shows only two of seventeen phones with a hardware keyboard. Samsung again only offer two phones with a hardware keyboard. While touchscreens offer the ability to eliminate hardware keyboards and other unsightly buttons for the sake of sleek aesthetics, they've so far failed (in my opinion) to provide a suitable replacement for hardware keys.

Yes, touchscreen keyboards are flexible and can offer a variety of layouts, however they still don't give sufficient physical feedback to allow fast touch typing. One reason we're better at typing on physical keyboards is because we "know" where our fingers are. The edges of keys (and the raised bumps often found on some keys) provide reference to other locations on the keyboard. Without looking at the keyboard, an experienced typist can type upwards of 100 words per minute. On a touchscreen, without proper physical feedback, you can expect just a small fraction of those speeds.

One argument against that could be the screen size, however tablets suffer from the same problems. The 26 character keys on my keyboard are of comparable size to the virtual keyboard on my 10-inch tablet. A popular approach to providing feedback for a mobile devices is to vibrate upon key press, however this provides little information other than "you've pressed a key". An alternative approach to making touchscreen keyboards easier to use has been patented by IBM; a virtual keyboard that adjusts itself to how users type on-screen. Auto-correct is another feature which has risen to aid the use of virtual keyboards, yet addresses the symptoms rather than the cause.

Enter touchscreens you can "feel". Actually being able to feel (something which resembles) the edges of keys on a virtual keyboard is likely to make it much easier to type on touchscreen devices. If technology becomes available which allows effective representation of edges (which Senseg claims their technology can), touchscreen devices will be able to offer what is, in my opinion, an improvement to virtual keyboards. I think this could be of particularly great benefit on tabletop computers which, by nature, allow a more natural typing position than handheld devices. Or perhaps this is all just wishful thinking because I go from 110WPM at my desktop to around 5WPM on my phone.

Wednesday, 23 November 2011

Running Visualisations

A heatmap of every run in November so far

Tonight I've been playing around with a python script which generates heatmaps from GPX files. The image above is a composite image of my last 10 runs in November (taken from my phone). It's fairly easy to see where I run most often.

What would be really cool would be if there was some way to visualise speed at a given point. The above image uses colour intensity to encode frequency of location; the more intense the colour, the more often I've run there. I'd find it interesting if it was possible to use colour to encode movement speed at a given point. For example, you could calculate the average speed across each run being visualised, and use different colours to represent above and below average, with varying saturation being used to represent how much above or below the average you were at that point.

Although I've seen a few existing methods of visualising speed (typically line charts), I've yet to see one which shows the relationship between speed and location. Endomondo and similar websites approach the issue by showing a map and separate chart for speed, and moving your mouse over either shows the corresponding location on map or speed on the chart. This exploratory method doesn't really give a good overview of the information.

This has the makings of a potential side project...

Tuesday, 15 November 2011

Android workshop and Surface

It feels unusually warm for November, which has made the past week quite pleasant for running. I've gotten 4 runs in over the last week, and I'm hoping to keep up at least 3 runs a week until the end of the semester. Dr Cutts talk last Wednesday on computing science education has caused a bit of introspection on how I use my time, and has made me realise that I don't always spend it wisely. I'm a workaholic, I get lots of work done, and I consider myself to be quite well organised. But maybe I could achieve similar things in a lot less time. Lately I've been focusing more on coursework, really trying to get as much done as early as possible. I've never had to pull an all-nighter working towards a deadline before, and I certainly don't plan to start any time soon.

I'm excited for the start of Week 12 because, other than the obvious reasons of having no more deadlines, I'm likely going to be putting on an Android development workshop in the School of Computing Science, along with another classmate. It'll be cool to give something back like that, and hopefully attendance is pretty decent. I'd certainly hope so, given that the Mobile Software Engineering degree has over 5 times as many students this year as last. The more Android projects I work on, the more I notice patterns emerging and the ability to re-use code. Things have gotten to the point now where any project I do in Android has about 50% re-used code. I think myself and James have a decent amount of experience to offer and can help teach other developers how to address problems that we've already encountered.

Week 12 is also the start of a fortnight dedicated to project work. My project at the moment is in quite a good state, I reckon. As far as implementation is concerned, I'm well ahead of schedule and the main technical concerns have been addressed. I don't know if I've mentioned it before, but I'm working with Microsoft Surface this year, and one of the technical challenges I'm approaching is how to display information when the Surface has stuff on top of it. I find this an interesting problem because it's only natural that a tabletop computer has to remain usable at the same time as being used as a table.

So far I've been iteratively developing a prototype which displays a shape in the largest unoccluded space, and have just started to animate this shape as it moves around the tabletop due to objects being placed on or removed from the Surface. There's some really cool stuff going on to make this work, and we (my project supervisor an I) are probably going to submit a work-in-progress paper to CHI2012 about our research so far. It's a new and novel area of research and it'd be the highlight of my academic "career" if that paper gets accepted.

Here's a terrible quality video I took earlier showing a prototype in action.


Wednesday, 26 October 2011

Left-recursion in Parsec

Lately I've been using the Parsec library for Haskell to write a parser and interpreter for a university assignment. Right-recursive grammars are trivial to parse with combinatorial parsers; tail recursion and backtracking make this simple. However, implementing a left-recursive grammar will often result in an infinite loop, as is the case in Parsec when using basic parsers.

Parsec does support left-recursion however. Unsatisfied with the lack of good tutorials when I googled for advice, I decided to write this. Hopefully it helps someone. If I can make this better or easier to understand, please let me know!

Left recursive parsing can be achieved in Parsec using chainl1.

chainl1 :: Stream s m t => ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a

As an example of how to use chainl1, I'll demonstrate its use in parsing basic integer addition and subtraction expressions.

First we'll need an abstract syntax tree to represent an integer expression. This can represent a single integer constant, or an addition / subtraction operation which involves two integer expressions.

data IntExp = Const Int
            | Add IntExp IntExp
            | Sub IntExp IntExp 

If addition and subtraction were to be right-associative, we'd parse the left operand as a constant, and attempt to parse the right operand as another integer expression. Upon failing, we'd backtrack and instead attempt to parse an integer constant. Reversing this approach to make the expressions left-associative would cause infinite recursion; we'd attempt to parse the left operand as an integer expression, which attempts to parse the left operand as an integer expression, which tries to... you get the point.

Instead we use chainl1 with two parsers; one to parse an integer constant, and another which parses a symbol and determines if the expression is an addition or subtraction.

parseIntExp :: Parser IntExp
parseIntExp =
  chainl1 parseConstant parseOperation

parseOperation :: Parser (IntExp -> IntExp -> IntExp)
parseOperation =
  do spaces
     symbol <- char '+' <|> char '-'
     spaces
     case symbol of
       '+' -> return Add
       '-' -> return Sub

parseConstant :: Parser IntExp
parseConstant =
  do xs <- many1 digit
     return $ Const (read xs :: Int)

Here, parseOperation returns either the Add or Sub tag of IntExp. Using GHCi, you can confirm the type of Add as:

Add :: IntExp -> IntExp -> IntExp

So, we have a parser which will parse a constant and a parser which will parse a symbol and determine what type of operation an expression is. In parseIntExp, chainl1 is the glue which brings these together. This is what allows left-associative parsing without infinitely recursing.

A complete code sample is available here. The abstract syntax tree has been created as an instance of the Show typeclass to print in a more readable format, which shows that the grammar is indeed left-associative.

ghci>  run parseIntExp "2 + 3 - 4"
((2+3)-4)