How to marshal/unmarshal ContentValues to insert generic type into ContentProvider?
Asked Answered
S

1

3

I want to put a generic POJO into ContentValues and unmarshall it within the ContentProvider.

I've been wracking my tiny brain re: Parcelables, ContentValues, and inserting into SQLite Regarding: http://njzk2.wordpress.com/2013/05/31/map-to-contentvalues-abusing-parcelable/

How to write a common code for inserting data in android's Sqlite

I've been trying to insert a android.location.Location into SQLite via ContentProvider:

Location loc = mLocationClient.getLastLocation();
myParcel = android.os.Parcel.obtain();
loc.writeToParcel(myParcel, 0);

ContentValues values = ContentValues.CREATOR.createFromParcel(myParcel );

to populate values w/ parcel.

Question 1) Here is my ContentProvider.insert method:

@Override
public Uri insert( final Uri uri, final ContentValues values ){
SQLiteDatabase db = Mydatabase.getWritableDatabase();

//db.insert() doesn’t unmarshal the values??
db.insert(  myTABLE_NAME, “”, values);

Uri result = null;
db.close();
return result;
}

this fails because the db.insert() doesn’t unmarshal the values (i believe) Error inserting android.database.sqlite.SQLiteException: INSERT INTO myTABLE_NAME() VALUES (NULL)

Question 2) Is there some way I can unmarshal values first and then marshal it back into another ContentValues variable? maybe w/ getKey()???

Send answered 10/10, 2014 at 20:18 Comment(0)
S
3

This works:

HashMap hm = new HashMap();
Location loc = mLocationClient.getLastLocation();
hm.put("LOCATIONS", loc);

android.os.Parcel myParcel = android.os.Parcel.obtain();    
myParcel.writeMap(hm);
myParcel.setDataPosition(0);

ContentValues values = ContentValues.CREATOR.createFromParcel(myParcel);

getContentResolver().insert(MyUri, values);

and then

@Override
public Uri insert( final Uri uri, final ContentValues oldvalues ){
SQLiteDatabase db = GAELdatabase.getWritableDatabase();

Uri result = null;
Location loc = (Location)oldvalues.get("LOCATIONS");

ContentValues values = new ContentValues();

values.put("ALTITUDE", loc.getAltitude());//meters above sea level
values.put("LATITUDE", loc.getLatitude());
values.put("LONGITUDE", loc.getLongitude());

long rowID = db.insert( "MyTABLE_NAME", "", values);
db.close();
return result;
}
Send answered 10/10, 2014 at 23:40 Comment(4)
I am afraid this is not going to work. If you follow the source code from insert, you'll see that the values from the ContentValues are passed to bindOjectToProgram, which is the last step of building the query. In this method, the type of the object is tested. Location is not a known type, which means the data in the table end up being the toString representation.Elenaelenchus
Putting a POJO into a map (and, with recognized types, into a ContentValues) requires more work than that. You can look into Gson, as since it provides a mapping from object to JSON, in fact it does provide a way of mapping from object to sql-compatible map.Elenaelenchus
Otherwise, this is the subject of that other article I wrote : njzk2.wordpress.com/2013/07/09/storage-is-simple-part-1-sql in which I go through the basis of object mapping. The idea is that you need to find out a way to tell sql how to handle each type you need to store.Elenaelenchus
(In your case, however, I would not store the Location object directly, or as a JSON string via Gson or something similar)Elenaelenchus

© 2022 - 2024 — McMap. All rights reserved.