quick look at ActiveAndroid #androiddev

Just checking out ActiveAndroid, and while it seems to do a lot to make Android DB access easier, a few criticisms appear right up front:

  • Doesn’t having to extend the proprietary base class as your Application class seem a little… invasive? It’s like saying, this isn’t my application, this is an ActiveAndroid application!
  • I’m sure it wasn’t intended this way, but looking at the licensing terms:

The SOFTWARE PRODUCT is licensed as follows:
(a) Installation and Use.
Michael Pardo grants you the right to install and use copies of the SOFTWARE PRODUCT on your computer running a validly licensed copy of the operating system for which the SOFTWARE PRODUCT was designed [e.g., Windows 95, Windows NT, Windows 98, Windows 2000, Windows 2003, Windows XP, Windows ME, Windows Vista].

Let’s ignore for the moment the question of what OS this intended for… but isn’t this JAR going to be built into our app? Doesn’t this technically mean we can’t distribute the app?

  • This is based on reflection, right? So isn’t that gonna be kind of slow on Android?
Advertisements

Intercepting SimpleCursorAdapter data #androiddev

Normally when you create a SimpleCursorAdapter for a ListView, you specify a one-to-one mapping of the columns from the DB and the views where you want them to end up, and the adapter basically just does a toString() on your data and sticks it in the view.

You can, of course, modify this behavior by overriding setViewText, which lets you reformat the text or modify the view as you wish; but it doesn’t give you the DB cursor, just a String, so you can’t pull the data yourself or refer to other columns. But not to despair (or turn to the NotSoSimpleCursorAdapter)! You can modify anything you want by providing a ViewBinder to the adapter.

The main reason I’m talking about this is because I think the documentation on this is just a little vague:

An easy adapter to map columns from a cursor to TextViews or ImageViews defined in an XML file. You can specify which columns you want, which views you want to display the columns, and the XML file that defines the appearance of these views. Binding occurs in two phases. First, if a SimpleCursorAdapter.ViewBinder is available, setViewValue(android.view.View, android.database.Cursor, int) is invoked. If the returned value is true, binding has occured. If the returned value is false and the view to bind is a TextView, setViewText(TextView, String) is invoked. If the returned value is false and the view to bind is an ImageView, setViewImage(ImageView, String) is invoked. If no appropriate binding can be found, an IllegalStateException is thrown.

OK, great. This also promises that you can put any kind of data in any kind of view (not just a TextView). But I didn’t know what it meant by “if a SimpleCursorAdapter.ViewBinder is available.” Turns out it’s pretty simple:

  1. Implement the SimpleCursorAdapter.ViewBinder interface (it has only one method, setViewValue, which gives you the Cursor and the view to work with – and just return false to let the adapter’s default behavior handle the binding). I did this for LogCursorAdapter in an inner class.
  2. Instantiate your implementation and use setViewBinder on your SimpleCursorAdapter instance to set it up as the binder. This makes it “available” for the process described above.

This is arguably better than overriding setViewText because you wouldn’t even have to subclass the adapter to do it – or even create a class (it could be an anonymous implementation). And of course you can access all of the cursor columns in any way you please. Nice.

As far as my earlier data retrieval woes, this gave me the ability to pull data out the way I wanted. Sqlite seems to be storing plenty of precision in the NUMERIC column type; it was just a matter of it being retrieved as a String that caused truncation of precision. In this case the solution was just to pull it out as a Long or Double as appropriate and format it myself (I also learned about DecimalFormat which was very helpful).

LogMyLife alpha release – try it out!

It’s time for LogMyLife to see the light of day outside my house – I’m calling it alpha-ready today. Go check it out. I’ve had it with fiddling around and no one seeing the results :-) It’s actually pretty functional, but it’s not as pretty as it could be and I know there are a few corner cases where things are a little wonky. And there’s so much functionality left to add… but it’s been a great project for me to familiarize myself with a lot of Android UI. And that will continue.

Some interesting stuff I just learned recently:

What’s in a name?

The application name and the name you see on its home screen/launcher icon need not match (though it’s probably wisest if they do). The application has a label in the manifest, and so does each activity (potentially).

If you look up the application in the settings page, it will show the application name (probably also in any market interactions). The launcher icon will show the label on the launcher activity. Presumably this is because you could conceivably have multiple launching activities for the same app (different entry points).

In my case, I wanted to show a different label (“LogMyLife – Main”) to the user once they launch the app than the application name (“LogMyLife”), so they’re oriented once they return; so I just created a shell activity (“Launcher”) with the correct app label which simply replaces itself with the real front Activity, just so I could get the labelling right. There’s probably a better way, like changing the label once the activity launches. In fact, I just tried that out (setTitle at the beginning of onCreate) and it works fine. Heh – live and learn.

Also interestingly, when I noticed this and changed the label, Android didn’t handle the change very well, at least in the 1.5 emulator where I test this (likely fixed since). The icon with the old label remained, but it wouldn’t actually load the app (error), and there was no new icon/label. I had to un-install and re-install the app to get it to launch properly.

Displaying DB data

I was going to follow up a bit on my last post, but I think I’ll do it with another post.

Onward

Anyway, the release is out there, so please let me know what you think of it. And feel free to hack it up if you want to see your own improvements! Github can have your own clone set up in seconds.

I may start working on the website for this sooner rather than later. SpringSource released some kind of library to assist with Android so I’m itching to try it out!

Mangling data with sqlite on Android

Oof! I still haven’t recovered from the holidays.

I nearly have LogMyLife in a presentable state, but I just have this one last nit to pick: numbers don’t seem to get recorded the way I expect. I’m using a numerical column (with the intention of using the DB to manipulate numerical values later) but they weren’t storing with the precision I expected.

To explore this, I created a demo project on github. It’s a simple Android app that lets you try out storing values in different ways. It’s interesting for exploring edge cases. I’d like to say more about this but it’s late… maybe later. One answer I was looking for: when you store the value 1.23456789 into a numeric column, if you retrieve it as a String, you get 1.23457; as a Float, 1.2345679; if you retrieve it as a Double you get the full precision. When retrieved as a String it’s getting truncated with only six digits of precision – why?