Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert from java.util.HashMap to android.content.ContentValues?

Is there a simple way to convert from a java Map<String,Object> to android.content.ContentValues ?

android.content.ContentValues is used in android database programming to keep the data of a database-row as name-value-pairs.

Background:

I try to port the businesslogic of an existing android app to a j2se-swing-app

My goal is having android specific code and android independant code that goes into a seperate lib that can be used by both android and by swing-gui.

currently i am analysing

  • if i have to implement a complete seperate set of repositoryimplementations with lot of redundant code
  • or if there is common code that can be used in both (j2se-swing- and android-) repository-Implementations.

Repository-Database-Code relies on database-field-name-value pairs which uses android.content.ContentValues.

I thought that my android independat version can use a HashMap<String,Object> insead of ContentValues and create code to convert between both.

The android dependant version would look like this

    // android dependant code in android-app
    class AndroidTimeSliceCategoryRepsitory implements ICategoryRepsitory {

        public long createTimeSliceCategory(final TimeSliceCategory category) {

            // get values from android independant layer
            Map<String, Object> columsToBeInserted = TimeSliceCategorySql.asHashMap(category);

// >>>> this is where i am stuck
            ContentValues androidColumsToBeInserted = DbUtils.asContentValues(columsToBeInserted);

            final long newID = AndroidTimeSliceCategoryRepsitory.DB.getWritableDatabase()
                    .insert(TimeSliceCategorySql.TIME_SLICE_CATEGORY_TABLE, null, androidColumsToBeInserted);
            category.setRowId((int) newID);
            return newID;
        }
    }

This is the android independant part:

    // android independant code in common jar
    class TimeSliceCategorySql {....

        /** converts {@link ....model.TimeSliceCategory}  to {@link java.util.HashMap} */
        public static Map<String, Object> asHashMap(final TimeSliceCategory category) {
            final Map<String, Object> values = new HashMap<String, Object>();
            values.put(TimeSliceCategorySql.COL_CATEGORY_NAME,
                    category.getCategoryName());
            values.put(TimeSliceCategorySql.COL_DESCRIPTION,
                    category.getDescription());

            // ... more values

            return values;
        }
    }

Currently i am stuck here:

    public class AndroidDatabaseUtil {
        /** converts from android independeant {@link java.util.Map} to android dependent {@link android.content.ContentValues} */
        public static ContentValues toContentValues(Map<String, Object> src) {
            ContentValues result = new ContentValues();

            for (String name : src.keySet()) {

// this is not possible because ContentValues does not define put(String name, Object value)
                result.put(name, src.get(name));

// using this would loose ContentValues.getAsLong() throw exception.
// result.put(name, src.get(name).toString());

            }
            src.entrySet()
            return result;
        }
    }
like image 396
k3b Avatar asked Aug 02 '14 11:08

k3b


Video Answer


2 Answers

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

Location loc = mLocationClient.getLastLocation();
HashMap hm = new HashMap();
hm.put("LOCATIONS", loc);
Parcel myParcel = Parcel.obtain();    
myParcel.writeMap(hm);
myParcel.setDataPosition(0);

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

getContentResolver().insert(MyDumbUri, 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;
}
like image 117
JDOaktown Avatar answered Sep 22 '22 22:09

JDOaktown


It looks like the values you put in your Map are Strings.

Therefore you can change the definition of the Map to

final Map<String, String> values = new HashMap<String, String>();

which would allow you to put values in the ContentValues instance :

result.put(name, src.get(name));
like image 40
Eran Avatar answered Sep 23 '22 22:09

Eran