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()???

Community
  • 1
  • 1
JDOaktown
  • 4,262
  • 7
  • 37
  • 52

1 Answers1

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;
}
JDOaktown
  • 4,262
  • 7
  • 37
  • 52
  • 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. – njzk2 Oct 10 '14 at 23:50
  • 1
    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. – njzk2 Oct 10 '14 at 23:53
  • 1
    Otherwise, this is the subject of that other article I wrote : http://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. – njzk2 Oct 10 '14 at 23:55
  • 1
    (In your case, however, I would not store the Location object directly, or as a JSON string via Gson or something similar) – njzk2 Oct 10 '14 at 23:56