具有相同查询的游标返回不同的结果

时间:2016-01-04 17:18:03

标签: android sqlite google-maps

我使用此方法在SQLite中保存标记:

 public long addMarker(Markers marker) {
    SQLiteDatabase db=null;

        ContentValues values = new ContentValues();
        values.put(COLUMN_ADDRESS, marker.get_address());
        values.put(COLUMN_COUNTRY, marker.get_country());
        values.put(COLUMN_LAT, marker.get_lat());
        values.put(COLUMN_LNG, marker.get_lng());
        values.put(COLUMN_IMAGE, marker.get_image());
        db = getWritableDatabase();
        long result = db.insert(TABLE_LOCATIONS, null, values);
        if (result>0){
            db.close();
        }
        return result;
}

然后onMarkerClick我必须获取我使用LatLng点击的标记的所有信息作为参数。 这是我使用的方法:

public Markers getOneMarker(double lat, double lng) {
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor curs = db.query(true,TABLE_LOCATIONS,new String[]{COLUMN_ID,
            COLUMN_ADDRESS,COLUMN_COUNTRY,
            COLUMN_LAT,COLUMN_LNG,COLUMN_IMAGE},
            COLUMN_LAT+"="+lat+" AND "+COLUMN_LNG+"="+lng,
            null,null,null,null,null);
    Markers marker = null;
    if (curs != null) {
        curs.moveToFirst();
        try{
            marker = new Markers(Integer.valueOf(curs.getString(0)),curs.getString(1), curs.getString(2),Double.valueOf(curs.getString(3)),Double.valueOf(curs.getString(4)),curs.getString(5));
        }catch (CursorIndexOutOfBoundsException e){
            e.printStackTrace();
            marker = new Markers("Address for location unavailable ", "N/A", lat, lng, "image");
        }

    }
    assert curs != null;
    curs.close();
    db.close();
    return marker;
}

90%的时间我得到了我想要的(地址和国家名称),但另外10%我得到了"Address for location unavailable ", "N/A"。我在Toast中设置onClick()来检查地理编码器但是没问题。我收到的是地址,但不是来自数据库。有任何想法吗? 编辑:是否可能是同步问题?如果它是如此打开标记后它保存在数据库中。 在onPostExecute()中的异步任务类中调用保存在DB中 这是我的DatabaseHandler课程:

public class DatabaseHandler extends SQLiteOpenHelper {
private static DatabaseHandler sInstance;
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "locations.db";
public static final String TABLE_LOCATIONS = "locations";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_ADDRESS = "_address";
public static final String COLUMN_COUNTRY = "_country";
public static final String COLUMN_LAT = "_lat";
public static final String COLUMN_LNG = "_lng";
public static final String COLUMN_IMAGE = "_image";




private DatabaseHandler(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public static synchronized DatabaseHandler getInstance(Context context) {

    if (sInstance == null) {
        sInstance = new DatabaseHandler(context.getApplicationContext());
    }
    return sInstance;
}


@Override
public void onCreate(SQLiteDatabase db) {
    String query = "CREATE TABLE " +
            TABLE_LOCATIONS + "(" +
            COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            COLUMN_ADDRESS + " TEXT, " +
            COLUMN_COUNTRY + " TEXT, " +
            COLUMN_LAT + " REAL, " +
            COLUMN_LNG + " REAL, " +
            COLUMN_IMAGE + " TEXT " +
            ");";

    db.execSQL(query);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_LOCATIONS);
    onCreate(db);
}

public long addMarker(Markers marker) {
        SQLiteDatabase db = null;

        ContentValues values = new ContentValues();
        values.put(COLUMN_ADDRESS, marker.get_address());
        values.put(COLUMN_COUNTRY, marker.get_country());
        values.put(COLUMN_LAT, marker.get_lat());
        values.put(COLUMN_LNG, marker.get_lng());
        values.put(COLUMN_IMAGE, marker.get_image());
        db = getWritableDatabase();
        long result = db.insert(TABLE_LOCATIONS, null, values);
        if (result>0){
            db.close();
        }
        return result;
}

public void deleteMarker(int id) {
    SQLiteDatabase db = getWritableDatabase();

    db.execSQL("DELETE FROM " + TABLE_LOCATIONS + " WHERE " + COLUMN_ID + "=\"" + id + "\";");
}

public Markers getOneMarker(double lat, double lng) {
    SQLiteDatabase db = getReadableDatabase();
    Cursor curs = db.query(true,TABLE_LOCATIONS,new String[]{COLUMN_ID,
            COLUMN_ADDRESS,COLUMN_COUNTRY,
            COLUMN_LAT,COLUMN_LNG,COLUMN_IMAGE},
            COLUMN_LAT+"="+lat+" AND "+COLUMN_LNG+"="+lng,
            null,null,null,null,null);
    Markers marker = null;
    if( curs != null && curs.moveToFirst() && curs.getCount() >= 1 ){
        do{
            try{
                marker = new Markers(Integer.valueOf(curs.getString(0)),curs.getString(1), curs.getString(2),Double.valueOf(curs.getString(3)),Double.valueOf(curs.getString(4)),curs.getString(5));

            }catch(CursorIndexOutOfBoundsException e){
                e.printStackTrace();
                marker = new Markers("Address for location unavailable ", "N/A", lat, lng, "image");
            }


        } while(curs.moveToNext());
    }
    if (curs != null) {
        curs.close();
    }
    db.close();
public void updateMarker(int id,String link){

    SQLiteDatabase db = this.getWritableDatabase();
    String query = "UPDATE "+TABLE_LOCATIONS + " SET "+ COLUMN_IMAGE + "="+link+" WHERE " + COLUMN_ID + "=\"" + id + "\";";
    db.execSQL(query);
}
public int getID(double lat, double lng){
    Markers marker = getOneMarker(lat,lng);
    return marker.get_id();
}

} 这是我称之为Activity的方法:

@Override
public boolean onMarkerClick(Marker marker) {
    try {
        Intent intent = new Intent(getApplicationContext(), MarkerActivity.class);
        DatabaseHandler databaseHandler = DatabaseHandler.getInstance(getApplicationContext());
        Markers tempMarker = databaseHandler.getOneMarker(marker.getPosition().latitude, marker.getPosition().longitude);
        addressLine = tempMarker.get_address();
        country = tempMarker.get_country();
        String lat = String.valueOf(tempMarker.get_lat());
        String lng = String.valueOf(tempMarker.get_lng());
        intent.putExtra("address", addressLine);
        intent.putExtra("country", country);
        intent.putExtra("lat", lat);
        intent.putExtra("lng", lng);
        startActivity(intent);
    } catch (NullPointerException e) {
        e.printStackTrace();

    }
    return true;
}

我用以下方法保存它们:

 @Override
    protected void onPostExecute(Markers markers) {
        DatabaseHandler databaseHandler = DatabaseHandler.getInstance(getApplicationContext());
        id = databaseHandler.addMarker(markers);
        Toast.makeText(getApplicationContext(), String.valueOf(id), Toast.LENGTH_SHORT).show();
        super.onPostExecute(markers);
        markerList.add(latLng);
    }

1 个答案:

答案 0 :(得分:-1)

建议:

从光标获取信息的最佳方法是,

if( curs != null && curs.moveToFirst() && curs.getCount() >= 1 ){
    do {
        ....
    } while( curs.moveToNext() );
}

设计Singletone SQLiteHelper

如果您正在使用多线程处理(例如项目中的AsyncTask),最佳做法是以SQLite方式使用Singletone数据库访问。这意味着您需要设计DatabaseHelper类,如下所示,

public class DatabaseHelper extends SQLiteOpenHelper { 

  private static DatabaseHelper sInstance;

  private static final String DATABASE_NAME = "database_name";
  private static final String DATABASE_TABLE = "table_name";
  private static final int DATABASE_VERSION = 1;
  ...
  public static synchronized DatabaseHelper getInstance(Context context) {

    if (sInstance == null) {
      sInstance = new DatabaseHelper(context.getApplicationContext());
    }
    return sInstance;
  }

  /**
   * Constructor should be private to prevent direct instantiation.
   * make call to static method "getInstance()" instead.
   */
  private DatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
  }
}

访问数据库

现在,当您需要打开数据库帮助程序时,您需要访问类似的项目

DatabaseHelper db = DatabaseHelper.getInstance(context);