George Schneeloch

Blog | Projects | Contact

Migrating to Maps v2 for Android

| categories: uncategorized

In December Google released a new version of their Maps API. It's a complete rewrite but generally an improvement. I've been working on integrating it with BostonBusMap and it looks like I can leave my app mostly unchanged, with a few minor exceptions. My overall impression is, it's less customizable but things generally need less customization so it sort of balances out.

The major change for me is how markers are handled. In the old API you could provide a Drawable for a marker, which might change state depending on if it was selected. Popups didn't exist so I used android-mapviewballoons. The new marker classes take bitmaps (or other resources) which don't change every time draw() is called. The new Maps are drawn in a 3D environment and I guess they couldn't provide this flexibility. Same goes with the new popups, which aren't live Views and don't handle clicks on a part of the whole popup.

These aren't deal breakers though. On the plus side, I got to remove RouteOverlay and BusOverlay, whose functionality is now mostly handled in the Maps library. Maps are now cached better than they were before which should reduce bandwidth needs for people. There is a prohibition on navigation-style apps, which doesn't really affect BostonBusMap.

The migration work is nearly done and it boils down to:

  • switching libraries and API Keys
  • changing BusDrawable, which drew an arrow in the direction of the bus, to be a bunch of static bus icons instead
  • using old popup balloon layout xml in new popup views, and removing the rest of android-mapviewballoons
  • learning about and using fragments. Installing the Support Fragments library, using SupportMapFragment instead of MapActivity
  • Replacing the links in the popup with a popup menu which is triggered on clicking the popup window
  • Replacing references to overlays with MapManager, a class which wraps around GoogleMap and keeps track of Markers and shapes (route lines)
  • Minor changes to listen for taps or to move the camera to a new location
  • Remove references to MyLocationOverlay, deal with GoogleMap directly instead

Projects

| categories: uncategorized

Two projects my former coworkers made that are pretty neat and worth looking at:

  • Code review tool written using Sinatra and haml. It allows you to annotate diffs against git branches which are then shared with other people involved in the code review. You just double click on the area you want to leave a comment, write something in the annotation box, then send the URL for the review to the other people involved for them to look at.
  • Watson, a chatbot for Campfire. It provides an easy interface to run things like deployment scripts, which are also logged and broadcast to everybody because it's done in the chatroom. There is a plugin API which makes it easy to extend for whatever purpose

Concurrency in BostonBusMap

| categories: uncategorized

I've been going through BostonBusMap over the past week replacing certain pieces of code with code that uses Google Guava. It's mostly an incremental improvement, but every little bit helps. In particular I like that many of their data structures forbid null values, and in particular I like the Immutables.

I've been reading through Java Concurrency in Practice to refresh on what that's supposed to look like. BostonBusMap, like most Android apps, uses a UI thread and one or more background threads. It's not complicated but it's been enough to cause problems in the past. Usually I just fix the pieces that cause a problem. When the database was throwing an exception regarding multiple concurrent accesses, I synchronized the methods. When a View was complaining about being accessed from the background thread, I fixed that specific problem. One thing I like about the book is that it sticks to a pattern, emphasizing documentation. I like the @GuardedBy attribute that indicates what needs synchronization, and on what lock.

Concurrency is not documented in the app at all, mostly because I'm the only one working on it and it seemed obvious at the time what threads would use which methods. I went through the code to overhaul it a bit, using ImmutableMaps, Sets, and Lists to guarantee that certain objects could be used by multiple threads on a read-only basis. Synchronization is easy enough when implementing a class but I've often updated certain pieces of code later on without updating synchronization, making it unreliable. I'm currently trying to confine explicit synchronization to database access and small, well defined objects.

I've also been making an effort to reduce the debugging stage of adding new features. It's generally pretty time consuming and less fun than implementation. Part of it is being more aware when I'm adding the feature, and another part is structuring the code to reduce possible errors. Guava discourages null in general. I used to like null because it produces the error immediately, where an empty container would cause similar code to silently continue. I guess it depends on what the rest of the code is supposed to do. Maybe it would be better to assert a non-zero length?


Sorting Music

| categories: uncategorized

The more and more I think about it, alphabetical order doesn't make much sense for digital storage. It's a system meant for human eyes, which divides a collection into 26 buckets (depending on language and other symbols), and then 26 sub-buckets for the second letter, and so on, until you reach a group which is easy to browse one after another. The Wikipedia article on the subject discusses various other issues like the word 'the', spaces, and abbreviations.

Generally when people talk about it regarding computers, they compare each character numerically, which are usually laid out in alphabetical order in Unicode and ASCII. It doesn't have a strong rationalle but it's consistent and generally good enough for displaying the list to people.

I've been thinking about this mostly in regard to music stores, where the CDs and records are sorted by artist title. Many online music services cluster artists by similarity, but there's no obvious way to order multiple dimensions into a single consistent ordering. At the Mahout talk I went to a little while ago Ted Dunning mentioned projecting multiple dimensions to a single dimension using a random projection which worked well enough for clustering purposes. It doesn't need to be a perfectly consistent sort. It would be awesome if certain sections of a music store corresponded to clusters, where people could browse in person and know they are looking at artists that generally match their tastes. Or they could head to the other side of the store and look at something completely different. That would give physical music stores a clear value over online websites where browsing is less natural and most things are represented as lists.


receipt-schema

| categories: uncategorized

I had this idea a while ago for a schema for restaurant (or similar) receipts. There's a lot of hassle in splitting the check, and even existing bill splitting apps require a lot of manual work. I started a repository with a sample Android app, located here. The basic idea is that there would be a QR code on receipts which would contain a URL, something like receipt://data_here, or maybe something http based so people without the app could view it on their phones.

All receipt data would need to be encoded in the URL. I guess I could do something internet based but for now I'm working with the challenge of doing it without that. The QR code should be small in order to be easily read from the bottom of a receipt, which has been a challenge. I had figured that it wouldn't be a problem given how little data is in a receipt, but the limit is actually really small. Maybe there could be a hybrid method, where the really imporant information is in the URL, and less important information is downloaded if available.

The schema basically stores the important pieces of the receipt data, like the title and price of each item, as well as the restaurant name and address. Layout is currently not defined, but I suppose you could encode that in the QR code as well. That's an interesting challenge too, creating a super tiny layout markup language capable of fitting neatly in a URL argument. I'm currently harcoding a printf-style string in the app and displaying all text in one giant textbox.

Of course the real challenge is in getting restaurants or cash register software companies to adopt a schema, some of who still use pen and paper. But the software part is an interesting challenge, so I figured why not.


Next Page ยป