将数据保存到SQlite数据库

时间:2015-01-02 07:51:05

标签: android sqlite google-maps

我想知道(因为我是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;
}

}

2 个答案:

答案 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即可。 另一种方法是使用数据库中的图像路径而不是保存图像数据。但是,不应将图像保存在公共目录中,而应将图像保存在应用程序的目录中,以便没有人可以更改或删除该图像。希望这对你有用。