是否有一种简单的方法可以将java Map<String,Object>
转换为android.content.ContentValues
?
android.content.ContentValues
用于android数据库编程,以将数据库行的数据保存为名称 - 值对。
背景:
我尝试将现有Android应用的businesslogic移植到j2se-swing-app
我的目标是拥有特定于Android的代码 和android独立的代码进入一个单独的lib,可以被android和swing-gui使用。
目前我正在分析
Repository-Database-Code依赖于使用android.content.ContentValues
的数据库字段名称 - 值对。
我认为我的android independat版本可以使用HashMap<String,Object>
ContentValues
内容,并创建代码以在两者之间进行转换。
Android依赖版本看起来像这样
// 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;
}
}
这是android独立部分:
// 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;
}
}
目前我被困在这里:
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;
}
}
答案 0 :(得分:6)
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);
然后
@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;
}
答案 1 :(得分:2)
看起来你在Map中放置的值是字符串。
因此,您可以将地图的定义更改为
final Map<String, String> values = new HashMap<String, String>();
允许您将值放在ContentValues
实例中:
result.put(name, src.get(name));
答案 2 :(得分:2)
您可以使用instanceof
声明中的if
关键字对其进行过滤。
示例:
if( src.get(name) instanceof String){
// convert to string
}
您还可以使用对象中的getClass
方法:
Object ob = src.get(name);
if(ob instanceof ob.getClass()){
// convert to type
}