Posts tagged ‘android’

Caltroid 1.0 in the Android Market

I have been working quite a bit on Caltroid, which is my Caltrain schedules application for Android. I have added new features like automatically scrolling to show the next train, displaying zones of travel and fares, improved the performance by a factor of 10, fixed crasher bug and many other improvements too numerous to mention here. I felt it was now solid enough to call it 1.0, and after all Caltroid is over a year old now.

Caltroid 1.0 screenshot

Caltroid 1.0 screenshot

I kept versions 0.1 through 0.3 Open Source and free to download, but I changed this for 1.0. I decided I wanted to make it easier to find the application as well as experiment with the Android Market, so I registered myself and paid the $25 registration fee. I have priced Caltroid at $1.99, which leaves me about a dollar per sale after Google takes 30% through the Market + 2% + $0.20 through Google Checkout. So if I get at least 25 people willing to buy it, I won’t feel like a fool for registering for the Market.

Update: Seems Google does NOT charge the usual Checkout fees on the Market, so it is just the 30%. Although several of my transactions seems to have $0.10 transaction fee instead, which is not 30% nor 2% + $.020. I have reported this to Google through some Market feedback page (couldn’t find any other contact form), but haven’t heard anything back. Basically it seems like Google is a black hole as far as trying to contact them or trying to get them to respond.

Multicolumn ListView in Android

Ever since I started programming on the Android platform, I have been wondering when the SDK would include a ready-made multicolumn ListView (or listbox as it is often called in other frameworks). One could of course construct such a thing by slapping regular ListViews side by side and then painfully adding code to keep them all in sync when scrolled and so on. It felt such a hack that I used GridView instead. GridView is not really a great list, though, because the cells will all be formatted the same. There are other issues besides that, but for me that was the main one.

I finally saw a blog post which customized ListView to put two TextViews vertically into one line. It was pretty simple going from there to one that would display three TextViews side-by-side. The main layout XML file could define ListView something like this:

<!-- main.xml -->
<ListView android:id="@+id/SCHEDULE" android:layout_width="wrap_content" android:layout_height="wrap_content">
</ListView>

Here is the XML for each row, main point being that we put three TextViews in LinearLayout with horizontal orientation:

<?xml version="1.0" encoding="utf-8"?>
<!-- row.xml -->
<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:paddingTop="4dip"
     android:paddingBottom="6dip"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal">
 
     <TextView android:id="@+id/TRAIN_CELL"
         android:layout_width="50dip"
         android:layout_height="wrap_content"/>
 
     <TextView android:id="@+id/FROM_CELL"
         android:layout_width="70dip"
         android:layout_height="wrap_content" android:layout_weight="1"/>
 
     <TextView android:id="@+id/TO_CELL"
         android:layout_width="60dip"
         android:layout_height="wrap_content"  android:layout_weight="1"/>
</LinearLayout>

Notice how you can format each TextView separately. There is no column separator, but something decent should not be too hard to whip up if desired. My understanding is that the screen width is supposed to be 160 dip, but for some reason I had to use width values that actually add up to more than that, as well as using layout weight to grow some fields proportionally so that when you switch to landscape mode things are still nicely aligned. I would have expected specifying widths in dip would have automatically done that.

Here is how you could populate that ListView with data:

ListView list = (ListView) findViewById(R.id.SCHEDULE);
 
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map = new HashMap<String, String>();
map.put("train", "101");
map.put("from", "6:30 AM");
map.put("to", "7:40 AM");
mylist.add(map);
map = new HashMap<String, String>();
map.put("train", "103(x)");
map.put("from", "6:35 AM");
map.put("to", "7:45 AM");
mylist.add(map);
// ...
mSchedule = new SimpleAdapter(this, mylist, R.layout.row,
            new String[] {"train", "from", "to"}, new int[] {R.id.TRAIN_CELL, R.id.FROM_CELL, R.id.TO_CELL});
list.setAdapter(mSchedule);

The main point here is that the SimpleAdapter requires the data to be in a List, where each entry is a Map. In my case, I simulate the columns by putting in three entries into each of the maps, and the maps each have the same keys. The adapter then maps the key values (like "train") to the corresponding TextView (R.id.TRAIN_CELL).

Putting the above pieces of code into Caltroid produces results that look like this:

Multicolumn ListView in Android

Multicolumn ListView in Android

There is quite a bit of work to create the data structure for the adapter in this way, so for anything involving more than a trivial amount of data this is probably going to be too slow. With more data, a database is almost certainly involved and the SimpleCursorAdapter works almost exactly like SimpleAdapter, except that SimpleCursorAdapter maps column names from the query results to the appropriate views.

Android WebView Limitations

I was trying to figure out how to display HTML help page for my Caltrain schedules application using WebView. I don’t want my application to require internet connection, so the HTML needs to ship with the application. Since help obviously needs to be localized, I tried to put the HTML into a string resource. This turned out to be tricky.

If string resources contain the quote (") or apostrophe (') characters, you need to either be able to wrap the whole string in either quote or apostrophe, or if you use both in the string then you need to espace with backslash (\). You will also need to replace less than (<) with &lt;. But even after this loadData() was giving me a blank page. By reducing my markup I found out I could not use any CSS styles. And even after that I still run into a problem where having hash (#) in the data meant nothing after the hash would show up (including the hash character). Using backslash to escape that or using a numeric entity &#35; instead did not help. At this point I gave up on localizing help, and went looking for ways to just include the HTML help file in the apk and load it using a file URL.

There are seemingly two locations to put “raw” resources in: /assets and /res/raw. It wasn’t clear to me how I could load HTML from /res/raw, so I went with /assets:

        browser.loadUrl("file:///android_asset/help.html");

Hopefully new SDK versions will make internationalizing HTML resources easier.

Caltroid 0.3 – Now with All Trains

It turned out Caltroid 0.2 shipped with an error that showed the times for only the 30 first trains for the day. Fixed that, and since I had already made some internationalization fixes and localized it to Finnish and Spanish (Google Translation only for now, since I don’t speak Spanish), I decided to include those fixes and call it 0.3.

The Android internationalization documentation is pretty good. The only issue I had was that trying to use getText() to get string with rich text styling caused application startup crashes, so I had to go back to using getString().

Caltroid 0.2 – Caltrain Schdules for Android

I am happy to announce Caltroid 0.2, which is a Caltrain schedules application for devices running the Google Android platform, like the T-Mobile G1. The 0.2 release brings the following major improvements:

  • January 1, 2009 timetable
  • Ability to show only trains that stop at selected stations, or all trains
  • Built with Android SDK 1.0 r2 which has been confirmed to work on T-Mobile’s G1

The UI looks a bit different, and there are other minor improvements as well. You can download it from the Caltroid homepage, or from AndAppStore.com. Update: I made entries on SlideMe, Phoload, androidforums.com and getjar.com as well.

Like I wrote yesterday, I had migrated Caltroid code to SDK 1.0 r1. I then went looking for information on how to actually release the application in a way that can be downloaded and installed on devices running Android. Luckily, this turned out to be a simple process. The instructions on how to build a release version and sign it were clear. The only thing I did different from the instructions was to specify -keysize 4096 with keytool, because I think the default 1024 bits is going to be breakable in the near term. I also found AndAppStore.com and created an entry for Caltroid since AndAppStore.com does not charge anything, unlike the Android Market (which charges $25 to register). Oh, and Caltroid 0.2 is free.

Since I don’t have a device running Android myself, I have only tested the application in the emulator. I would be very interested in hearing how it performs on an actual physical device.

Below is the 0.2 screenshot. You might want to compare that to the 0.1 screenshot.

Caltroid 0.2 Screenshot

Caltroid 0.2 Screenshot

Migrated Caltroid to Android SDK 1.0

It has been a year, almost to the day, when I started working on Caltroid. Caltroid is a Caltrain schedule application for Google Android-based devices. I released the 0.1 version of Caltroid 15 days later. I used SDK version m3-rc37a.

In September 2008 Google finally released the 1.0 version of the SDK. In the meanwhile I hadn’t really done any Android development. But I decided I’d update my little application to the 1.0 SDK release so that people could actually start using my application on real devices that were also just coming out.

Unfortunately it seemed the SDK had gone through huge changes. My first strategy was trying to just fix things that did not compile, but that looked hopeless. I ended up either commenting or removing nearly all of my code. I then tried to look at the “what has changed” documents, but that proved nearly useless as well, and was way too difficult. What was worse, almost all of the documentation and code samples were still stuck with some older SDK version. I finally burned out.

But just recently someone commented that they were actually using my application on a real device. I was amazed; I did not know it would work. So given that I seemed to have at least one user, I started thinking about working on the conversion again. And then I noticed that Caltrain had released new schedules on January 1, 2009, so I had to update my other schedule applications. I continued with my conversion, and was happy to note that the situation with documentation and code samples had improved a lot. Web searches also returned some usable samples, so I was able to fix the places where I had gotten stuck previously. Finally I remembered reading about Ctrl+Shift+O to automatically fix imports in Eclipse, and decided to put all the deleted code back and see what would happen. Another amazing thing: just a few minor things left broken that were easy to fix.

After the application finally was running, I noticed it looked pretty ugly compared to what it was with the old SDK. The spinner controls were functionally better, though. The old dark theme was pretty nice looking in my opinion, but the new themes are very plain. With some reading of documentation, and the new improved UI building tool included in the Eclipse plugin, I made the UI look reasonable, although I gave up on customizing buttons which looks like a huge amount of work. It is apparently just not possible to change button colors and retain the 3D look. I also figured I should add some new feature so that I could bump the version number, so I added a checkbox to the UI to toggle showing all trains or only trains that stop at the selected stations.

Some frustrations still remain:

  • documentation still partially out of date
  • documentation could really use code samples
  • still no multicolumn list view
  • parts of the new API seem more difficult to use because things became more generic

I still don’t know anyone who has an Android device, so I have been unable to test my application on real hardware. I am especially concerned about performance, since I am recreating the controls on most changes (I still haven’t figured out how to make UI controls update automatically when data changes). There is quite a bit of room for future improvements.

Next step is figuring out how to release the application so that people can actually install it on their devices. It seems like this will involve digitally signing the package. Having the application on some marketplace would be great, but I am somewhat opposed on principle to the $25 fee since at this point I don’t know if I’ll be charging for any application I might make.

Phone Laptop

The OLO cradle for iPhone that makes an iPhone into a laptop is squarely in the realm of devices I talked about in my mobile predictions article back in March. Of course I was thinking more in terms of using wireless to connect to the keyboard, display and so forth, but the OLO device uses the clever trick of transforming the iPhone touch screen into the “laptop” trackpad.

I expect there will be a lot of similar devices in the market soon, and not just for the iPhone but Google Android devices and others as well. The iPhone is clearly attractive for manufacturers like OLO because iPhones come in very limited variations yet with large number of phones. On the other hand, given the open nature of the Android platform and surprisingly large demand (based on the 1.5 million preorders for the T-Mobile G1), I would expect similar laptop cradles won’t be far behind for Android. Done right, it could be just a matter of fitting the right adapter for your phone into such a “laptop”. One “laptop” to rule them all…

Update: There is a wireless solution as well: the REDFLY for smartphones.

Caltroid Project Page

Since I released the first version of Caltroid (Caltrain schedule application for Caltrain) the de facto homepage for the project has been the release announcement blog post. That is far from ideal, so I finally made a real project page for Caltroid. It has the download links, source links and so forth and will be updated if and when I continue the project. Now that there are rumors about T-Mobile shipping a real Android device in September, I have some motivation to actually do some more work on Caltroid.