我想知道(因为我是SQlite数据库新手)我需要做些什么才能将数据保存到Sqlite。我遇到的问题是,在我的应用程序中,用户可以通过相机意图拍摄图像并将该图像返回到地图(Google Map API v2)。然后,当用户点击标记时,图像将全屏显示。现在显然我需要将这些标记保存到地图中,这样当用户返回应用程序时,标记(和相关图像)就在那里。现在我已经尝试将图像作为blob保存到数据库,但它似乎不起作用(我不完全确定为什么,我可以提供代码是必要的)。但我想我是否需要保存图像(因为拍摄照片后图像已经保存在sdCard上)或者我只是保存该标记的markerId(HashMap)以指向相关的图像那一点(标记)?
当我点击标记时,我必须检索该标记的图像:
private Map<String, Bitmap> myMarkersHash;
private String markerId;
然后在onCreate
方法:
myMarkersHash = new HashMap<String, Bitmap>();
添加标记时:
private void drawMarker(LatLng point) {
Marker marker = googleMap.addMarker(new MarkerOptions()
.position(thePoint));
markerId = marker.getId();
然后在显示图像时:
ImageView markerIcon = (ImageView) v.findViewById(R.id.marker_icon);
Bitmap bitmap = myMarkersHash.get(marker.getId());
markerIcon.setImageBitmap(bitmap);
非常感谢任何帮助和建议!
谢谢!
修改
contentValues.put(LocationsDB.FIELD_IMAGE, imageData); \\Saving image
\\Convert image to byte
baos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 50, baos);
imageData = baos.toByteArray();
\\Retrieving image
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
int locationCount = 0;
double lat=0;
double lng=0;
float zoom=0;
locationCount = arg1.getCount();
arg1.moveToFirst();
if(arg1.getCount() >= 1){
while(arg1.moveToNext()){
// Get the latitude
lat = arg1.getDouble(arg1.getColumnIndex(LocationsDB.FIELD_LAT));
lng = arg1.getDouble(arg1.getColumnIndex(LocationsDB.FIELD_LNG));
zoom = arg1.getFloat(arg1.getColumnIndex(LocationsDB.FIELD_ZOOM));
arg1.getBlob(arg1.getColumnIndex(LocationsDB.FIELD_IMAGE));
thePoint = new LatLng(lat, lng);
drawMarker(thePoint);
}
if (arg1 != null && !arg1.isClosed()){
arg1.close();
}
if(locationCount>0){
googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(lat,lng)));
googleMap.animateCamera(CameraUpdateFactory.zoomTo(zoom));
arg1.moveToNext();
ImageView image = (ImageView) findViewById(R.id.marker_icon);
imageData = arg1.getBlob(arg1.getColumnIndex("blob"));
image.setImageBitmap(BitmapFactory.decodeByteArray(imageData, 0, imageData.length));
**编辑2 **
12-24 16:19:48.679: E/AndroidRuntime(22984): FATAL EXCEPTION: main
12-24 16:19:48.679: E/AndroidRuntime(22984): Process: com.example.main, PID: 22984
12-24 16:19:48.679: E/AndroidRuntime(22984): android.database.CursorIndexOutOfBoundsException: Index 1 requested, with a size of 1
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:426)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.database.AbstractWindowedCursor.getBlob(AbstractWindowedCursor.java:44)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.database.CursorWrapper.getBlob(CursorWrapper.java:122)
12-24 16:19:48.679: E/AndroidRuntime(22984): at com.example.main.Map.onLoadFinished(KrugerParkMap.java:341)
12-24 16:19:48.679: E/AndroidRuntime(22984): at com.example.main.Map.onLoadFinished(KrugerParkMap.java:1)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:427)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:395)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.support.v4.content.Loader.deliverResult(Loader.java:104)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:73)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:35)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:223)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.support.v4.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:61)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:461)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.support.v4.content.ModernAsyncTask.access$500(ModernAsyncTask.java:47)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:474)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.os.Handler.dispatchMessage(Handler.java:102)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.os.Looper.loop(Looper.java:136)
12-24 16:19:48.679: E/AndroidRuntime(22984): at android.app.ActivityThread.main(ActivityThread.java:5586)
12-24 16:19:48.679: E/AndroidRuntime(22984): at java.lang.reflect.Method.invokeNative(Native Method)
12-24 16:19:48.679: E/AndroidRuntime(22984): at java.lang.reflect.Method.invoke(Method.java:515)
12-24 16:19:48.679: E/AndroidRuntime(22984): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
12-24 16:19:48.679: E/AndroidRuntime(22984): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
12-24 16:19:48.679: E/AndroidRuntime(22984): at dalvik.system.NativeStart.main(Native Method)
然后是LocationsDB类:
private static String DBNAME = "locationmarkersqlite";
private static int VERSION = 1;
public static final String FIELD_ROW_ID = "_id";
public static final String FIELD_LAT = "lat";
public static final String FIELD_LNG = "lng";
public static final String FIELD_ZOOM = "zom";
public static final String FIELD_IMAGE = "blob";
private static final String DATABASE_TABLE = "locations";
private SQLiteDatabase mDB;
public LocationsDB(Context context) {
super(context, DBNAME, null, VERSION);
this.mDB = getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table " + DATABASE_TABLE + " ( " +
FIELD_ROW_ID + " integer primary key autoincrement , " +
FIELD_LNG + " double , " +
FIELD_LAT + " double , " +
FIELD_ZOOM + " text , " +
FIELD_IMAGE + " blob " +
" ) ";
db.execSQL(sql);
}
public long insert(ContentValues contentValues){
long rowID = mDB.insert(DATABASE_TABLE, null, contentValues);
return rowID;
}
public int del(){
int cnt = mDB.delete(DATABASE_TABLE, null , null);
return cnt;
}
public Cursor getAllLocations(){
return mDB.query(DATABASE_TABLE, new String[] { FIELD_ROW_ID, FIELD_LAT , FIELD_LNG, FIELD_ZOOM, FIELD_IMAGE} , null, null, null, null, null, null);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public static Cursor rawQuery(String string, Object object) {
// TODO Auto-generated method stub
return null;
}
}
答案 0 :(得分:0)
这可能是问题吗?您已关闭arg1,但仍在尝试访问它。见http://developer.android.com/reference/android/database/Cursor.html#close()
if (arg1 != null && !arg1.isClosed()){
arg1.close();
}
if(locationCount>0){
googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(lat,lng)));
googleMap.animateCamera(CameraUpdateFactory.zoomTo(zoom));
arg1.moveToNext();
ImageView image = (ImageView) findViewById(R.id.marker_icon);
imageData = arg1.getBlob(arg1.getColumnIndex("blob"));
image.setImageBitmap(BitmapFactory.decodeByteArray(imageData, 0, imageData.length));
答案 1 :(得分:0)
有两种方法可以做到这一点,一种是 - 您可以使用OrmLite库来处理数据库操作。它非常易于使用,您可以将图像数据保存为数据库中的字节数组。只需将列类型指定为Byte_Array即可。 另一种方法是使用数据库中的图像路径而不是保存图像数据。但是,不应将图像保存在公共目录中,而应将图像保存在应用程序的目录中,以便没有人可以更改或删除该图像。希望这对你有用。