Why does ContentValues have a put method that supports Boolean?
Asked Answered
L

2

27

The ContentValues class contains a method that allows Booleans to be put into the values collection. AFAIK, SQLite does not contain a native Boolean format that Android could push the boolean values into. So, what magic does Android do behind the scenes to store these values?

Also, why is there no complimentary getBoolean method on a Cursor? To me, this appears to be a pretty awkward design oversight since there seems to be no "safe" way of retrieving a boolean value that was put into the DB via ContentValues. What am I missing?

This question may seem a bit frivolous since I suspect that the boolean's are stored as a 1 or 0 integer, but why would Android commit to developers making that assumption? Its not even documented as far as I am aware.

Lindon answered 2/5, 2011 at 19:21 Comment(0)
K
11

The ContentValues class contains a method that allows Booleans to be put into the values collection. AFAIK, SQLite does not contain a native Boolean format that Android could push the boolean values into. So, what magic does Android do behind the scenes to store these values?

From reading this document, it sounds like the boolean to integer conversion is done by SQLite.

Also, why is there no complimentary getBoolean method on a Cursor? To me, this appears to be a pretty awful design oversight since there seems to be no "safe" way of retrieving a boolean value that was put into the DB via ContentValues. What am I missing?

If you're reading from a cursor, then you know what columns should be returned from the query, so you presumably know the data types of the columns that were requested. I agree that having a getBoolean method would be better, but it's not hard to work around.

Kraken answered 2/5, 2011 at 19:57 Comment(3)
Erich, after reading the SQLite documentation it all makes sense. IMHO, its a little poor on Android's part to not assist in documenting this. Without knowing this feature of SQLite, it puts developers in an awkward spot. In any case, now that I know that SQLite automatically does these conversions, I know that I can use Integer columns just like I was doing.Lindon
I know I already accepted your answer, but your Edit may be a bit confusing for some. I didn't mention ContentProviders at all in the question, but I did tag it that way since it may be relevant for some. You can also use the ContentValues class directly with the SQLiteDatabase class (not just ContentProviders). I think my question makes more sense in that context since IMO a Cursor should have a getBoolean method to hide the SQLite implementation detail.Lindon
@Justin: Thanks for the suggestion. When I re-read my answer, I thought I had missed the mark, so I added the edit :)Kraken
L
1

UPDATE

Google has patched the previously mentioned bug, though it's not implemented yet at the time of this post:

https://code.google.com/p/android/issues/detail?id=232274


It's worth noting that the current API is dangerous and could break your app if anything changes under the hood.

Additionally, ContentValues.getBoolean has a major issue that if you create the ContentValues with DatabaseUtils.cursorRowToContentValues it will treat EVERY field as a string:

values.put(columns[i], cursor.getString(i));

When you then retrieve the field via ContentValues.getBoolean you will ALWAYS get false:

if (value instanceof CharSequence) {
    return Boolean.valueOf(value.toString());

Since value is "0" or "1" this conversion fails:

private static boolean toBoolean(String name) {
    return ((name != null) && name.equalsIgnoreCase("true"));

So I highly recommend that you create your own getter and setter so your behavior is well defined.

Lubricator answered 16/1, 2017 at 14:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.