【问题标题】:Reading values from SQLite Database for Google Map Markers从 SQLite 数据库中为 Google 地图标记读取值
【发布时间】:2014-02-24 22:45:17
【问题描述】:

我正在尝试从预制的 SQLite 数据库中读取位置(纬度、经度)值和标题。我遇到的问题是它似乎在地图上显示了一个标记,但与数据库中的值无关 - 几乎就像它们被错误地读取一样。

我的 MonumentsDatabase.java 类(我在其中处理数据库):

public class MonumentsDatabase extends SQLiteOpenHelper {
public static String DATABASE_NAME = "antiquityDatabase.db";
public final static String DATABASE_PATH = "/data/data/com.example.antiquity/databases/";
private static final int DATABASE_VERSION = 1;
int _id;
double _lat;
double _lng;

String _title;
String _date;
String _description;

String[] _idColumn = {"_id"};
String[] latColumn = {"latitude"};
String[] lngColumn = {"longitude"};
String[] titleColumn = {"title"};
String[] dateColumn = {"date"};
String[] descColumn = {"description"};


private SQLiteDatabase database;
private final Context myContext;

public MonumentsDatabase(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    this.myContext = context;
}

public void createDatabase() throws IOException {
    boolean databaseExist = checkDatabase();

    if(databaseExist) {
        //Do nothing
    } else {
        this.getReadableDatabase();

        try {
            copyDatabase();

        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }
}

private boolean checkDatabase() {
    SQLiteDatabase checkDatabase = null;

    try {
        String myPath = DATABASE_PATH + DATABASE_NAME;
        checkDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    } catch (SQLiteException e) {
        //database doesnt exist yet
    }

    if(checkDatabase != null) {
        checkDatabase.close();
    }

    return checkDatabase != null ? true : false;
}

private void copyDatabase() throws IOException {

    InputStream myInput = myContext.getAssets().open(DATABASE_NAME);

    String outputFilename = DATABASE_PATH + DATABASE_NAME;

    OutputStream myOutput = new FileOutputStream(outputFilename);

    byte[] buffer = new byte[1024];
    int length;
    while((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }

    myOutput.flush();
    myOutput.close();
    myInput.close();
}

public void openDatabase() throws SQLException {

    String myPath = DATABASE_PATH + DATABASE_NAME;
    database = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}

@Override
public synchronized void close() {
    if(database != null) {
        database.close();
    }
    super.close();
}

@Override
public void onCreate(SQLiteDatabase db) {

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}

public int getID() { 
    Cursor idQuery = database.query("monuments", _idColumn, null, null, null, null, null);
    if (idQuery.moveToFirst()) {
        do {
            StringBuilder sb = new StringBuilder();
            int columnsQty = idQuery.getColumnCount();
            for (int idx=0; idx<columnsQty; ++idx) {
                sb.append(idQuery.getString(idx));
                if (idx < columnsQty - 1)
                    sb.append("; ");
            }
            Log.v("getID() - ID", String.format("Row: %d, Values: %s", idQuery.getPosition(), sb.toString()));

        }
        while (idQuery.moveToNext());
    }
    return _id;
}

public void setID(int id) {
    _id = id;
}

public double getLat() {
    Cursor latQuery = database.query("monuments", latColumn,  null, null, null, null, null);

    latQuery.moveToFirst();
    if (latQuery.moveToFirst()) {
        do {
            StringBuilder sb = new StringBuilder();
            int columnsQty = latQuery.getColumnCount();
            for (int idx=0; idx<columnsQty; ++idx) {
                sb.append(latQuery.getString(idx));
                if (idx < columnsQty - 1)
                    sb.append("; ");
            }
            Log.v("getLat() - LATITUDE", String.format("Row: %d, Values: %s", latQuery.getPosition(), sb.toString()));

        }
        while (latQuery.moveToNext());


    }       
    return _lat;
}

public void setLat(double lat) {
    _lat = lat;
}

public double getLng() {
    Cursor lngQuery = database.query("monuments", lngColumn,  null, null, null, null, null);

    if (lngQuery.moveToFirst()) {
        do {
            StringBuilder sb = new StringBuilder();
            int columnsQty = lngQuery.getColumnCount();
            for (int idx=0; idx<columnsQty; ++idx) {
                sb.append(lngQuery.getString(idx));
                if (idx < columnsQty - 1)
                    sb.append("; ");
            }
            Log.v("getLng() - LONGITUDE", String.format("Row: %d, Values: %s", lngQuery.getPosition(), sb.toString()));

        }
        while (lngQuery.moveToNext());
    }
    return _lng;
}

public void setLng(double lng) {
    _lng = lng;
}
// Handle the monuments titles
public String getTitle() {
    Cursor titleQuery = database.query("monuments", titleColumn,  null, null, null, null, null);

    if (titleQuery.moveToFirst()) {
        do {
            StringBuilder sb = new StringBuilder();
            int columnsQty = titleQuery.getColumnCount();
            for (int idx=0; idx<columnsQty; ++idx) {
                sb.append(titleQuery.getString(idx));
                if (idx < columnsQty - 1)
                    sb.append("; ");
            }
            Log.v("getTitle() - TITLE", String.format("Row: %d, Values: %s", titleQuery.getPosition(), sb.toString()));

        }
        while (titleQuery.moveToNext());
    }
    return _title;
}

public void setTitle(String title) {
    _title = title;
}

public String getDate() {
    Cursor dateQuery = database.query("monuments", dateColumn, null, null, null, null, null, null);
    if (dateQuery.moveToFirst()) {
        do {
            StringBuilder sb = new StringBuilder();
            int columnsQty = dateQuery.getColumnCount();
            for (int idx=0; idx<columnsQty; ++idx) {
                sb.append(dateQuery.getString(idx));
                if (idx < columnsQty - 1)
                    sb.append("; ");
            }
            Log.v("getDate() - DATE", String.format("Row: %d, Values: %s", dateQuery.getPosition(), sb.toString()));

        }
        while (dateQuery.moveToNext());
    }
    return _date;
}

public void setDate(String date) {

    _date = date;
}

public String getDescription() {
    Cursor descriptionQuery = database.query("monuments", descColumn, null, null, null, null, null, null);
    if (descriptionQuery.moveToFirst()) {
        do {
            StringBuilder sb = new StringBuilder();
            int columnsQty = descriptionQuery.getColumnCount();
            for (int idx=0; idx<columnsQty; ++idx) {
                sb.append(descriptionQuery.getString(idx));
                if (idx < columnsQty - 1)
                    sb.append("; ");
            }
            Log.v("getDescription() - DESCRIPTION", String.format("Row: %d, Values: %s", descriptionQuery.getPosition(), sb.toString()));

        }
        while (descriptionQuery.moveToNext());

    }
    return _description;
}

public void setDescription(String description) {
    _description = description;
}

public void addMarker(MarkerObject m) {
    m.getTitle();

}

public ArrayList<MonumentsDatabase> arrayDB() {
    ArrayList<MonumentsDatabase> aD = new ArrayList<MonumentsDatabase>();
    //aD.add(getTitle());

    return aD;
}

}

我的 MainActivity.java 类:

public class MainActivity extends FragmentActivity {

private GoogleMap map;
Intent data;    
MonumentsDatabase monDatabase;
ArrayList<MonumentsDatabase> mDatabase;
int _id;
double _lat;
double _lng;
double sLat;
double sLng;
String _title;
String titles;
double lats;
double lngs;
LatLng markerPosition;
int i;
private Marker bigBen;
private Marker mainMarker;
private Marker parliamentSQ;
private Marker parliament;
private Marker random;


static final LatLng PARLIAMENT = new LatLng(51.499776600000000000, -0.125173099999983600);
//static final LatLng MARKERS = new LatLng(getLatitude(), getLongitude());
static final LatLng PARLIAMENTSQ = new LatLng(51.5006, -0.1267);
static final LatLng RANDOM = new LatLng(51.5019, -0.1257);
LocationManager locationManager;
Context context = this;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    map=((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

    map.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
        @Override
        public void onInfoWindowClick(Marker marker) {
           Intent data = new Intent(MainActivity.this, DisplayData.class);
           startActivity(data);

        }
    });

    ArrayList<MonumentsDatabase> mDB = createDatabase();


    for(i = 0; i < mDB.size(); i++) {
        //Get position of what the DB is and get the latitude and longitude
        sLat = mDB.get(i).getLat();
        sLng = mDB.get(i).getLng();
        markerPosition = new LatLng(sLat, sLng);
        map.addMarker(new MarkerOptions()
            .position(markerPosition)
            .title(mDB.get(i).getTitle())
            .snippet("Click for more info.")
            .icon(BitmapDescriptorFactory.fromResource(R.drawable.custom_marker))); 
    }





    locationManager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );

    if ( !locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
        disabledGPS();
    }       

    map.setMyLocationEnabled(true);
}




private void disabledGPS() {
    final AlertDialog.Builder gpsDisabled = new AlertDialog.Builder(this);
    gpsDisabled.setMessage("This app requires GPS to be enabled. Do you wish to continue?")
        .setCancelable(false)
        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
            }
        })
        .setNegativeButton("No", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();
            }
        });
    AlertDialog mainAlert = gpsDisabled.create();
    mainAlert.show();
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

public ArrayList<MonumentsDatabase> createDatabase() {
    monDatabase = new MonumentsDatabase(this);
    try {   
        monDatabase.createDatabase();
    } catch (IOException ioe) {
        throw new Error("Unable to create database");
    }
    try {
        monDatabase.openDatabase();
    }catch(SQLException sqle){ 
        throw sqle;
    }

    mDatabase = new ArrayList<MonumentsDatabase>();
    monDatabase.setTitle(titles);
    monDatabase.setLat(lats);
    monDatabase.setLng(lngs);
    titles = monDatabase.getTitle();
    lats = monDatabase.getLat();
    lngs = monDatabase.getLng();
    mDatabase.add(monDatabase);

    return mDatabase;
}

}

我想要在谷歌地图上读取并显示为标记的标题、纬度和经度值,目前 SQLite 数据库中有 20 条记录。

非常感谢任何帮助!

编辑:

Log cat 打印数据如下:

02-24 12:55:11.691: V/getTitle() - TITLE(18411): Row: 0, Values: Big Ben
02-24 12:55:11.692: V/getTitle() - TITLE(18411): Row: 1, Values: Swansea Castle
02-24 12:55:11.693: V/getTitle() - TITLE(18411): Row: 2, Values: Cardiff Castle
02-24 12:55:11.694: V/getTitle() - TITLE(18411): Row: 3, Values: Mumbles Lighthouse
02-24 12:55:11.695: V/getTitle() - TITLE(18411): Row: 4, Values: Sketty Hall
02-24 12:55:11.695: V/getTitle() - TITLE(18411): Row: 5, Values: St Mary's Church, Swansea
02-24 12:55:11.696: V/getTitle() - TITLE(18411): Row: 6, Values: Loughor
02-24 12:55:11.696: V/getTitle() - TITLE(18411): Row: 7, Values: Oystermouth Castle
02-24 12:55:11.696: V/getTitle() - TITLE(18411): Row: 8, Values: Oxwich Castle
02-24 12:55:11.696: V/getTitle() - TITLE(18411): Row: 9, Values: Penlle'r Castell
02-24 12:55:11.696: V/getTitle() - TITLE(18411): Row: 10, Values: Pennard Castle
02-24 12:55:11.698: V/getTitle() - TITLE(18411): Row: 11, Values: The Palace Theatre
02-24 12:55:11.699: V/getTitle() - TITLE(18411): Row: 12, Values: Morris Castle
02-24 12:55:11.699: V/getTitle() - TITLE(18411): Row: 13, Values: Castle Cinema
02-24 12:55:11.699: V/getTitle() - TITLE(18411): Row: 14, Values: Port Eynon
02-24 12:55:11.700: V/getTitle() - TITLE(18411): Row: 15, Values: Penrice Castle
02-24 12:55:11.700: V/getTitle() - TITLE(18411): Row: 16, Values: Weobley Castle
02-24 12:55:11.700: V/getTitle() - TITLE(18411): Row: 17, Values: St Fagans Castle
02-24 12:55:11.700: V/getTitle() - TITLE(18411): Row: 18, Values: Gregynog Hall
02-24 12:55:11.700: V/getTitle() - TITLE(18411): Row: 19, Values: Margam Castle
02-24 12:55:11.702: V/getLat() - LATITUDE(18411): Row: 0, Values: 51.5008
02-24 12:55:11.703: V/getLat() - LATITUDE(18411): Row: 1, Values: 51.6203
02-24 12:55:11.703: V/getLat() - LATITUDE(18411): Row: 2, Values: 51.4824
02-24 12:55:11.703: V/getLat() - LATITUDE(18411): Row: 3, Values: 51.5671
02-24 12:55:11.703: V/getLat() - LATITUDE(18411): Row: 4, Values: 51.6131
02-24 12:55:11.704: V/getLat() - LATITUDE(18411): Row: 5, Values: 51.619
02-24 12:55:11.704: V/getLat() - LATITUDE(18411): Row: 6, Values: 51.6626
02-24 12:55:11.704: V/getLat() - LATITUDE(18411): Row: 7, Values: 51.5765
02-24 12:55:11.704: V/getLat() - LATITUDE(18411): Row: 8, Values: 51.5546
02-24 12:55:11.705: V/getLat() - LATITUDE(18411): Row: 9, Values: 51.7691
02-24 12:55:11.705: V/getLat() - LATITUDE(18411): Row: 10, Values: 51.5766
02-24 12:55:11.705: V/getLat() - LATITUDE(18411): Row: 11, Values: 51.3739
02-24 12:55:11.705: V/getLat() - LATITUDE(18411): Row: 12, Values: 51.391
02-24 12:55:11.705: V/getLat() - LATITUDE(18411): Row: 13, Values: 51.3715
02-24 12:55:11.706: V/getLat() - LATITUDE(18411): Row: 14, Values: 51.5453
02-24 12:55:11.706: V/getLat() - LATITUDE(18411): Row: 15, Values: 51.5752
02-24 12:55:11.706: V/getLat() - LATITUDE(18411): Row: 16, Values: 51.6128
02-24 12:55:11.706: V/getLat() - LATITUDE(18411): Row: 17, Values: 51.4859
02-24 12:55:11.707: V/getLat() - LATITUDE(18411): Row: 18, Values: 52.3403
02-24 12:55:11.707: V/getLat() - LATITUDE(18411): Row: 19, Values: 51.5628
02-24 12:58:56.017: V/getLng() - LONGITUDE(18567): Row: 0, Values: -0.1247
02-24 12:58:56.018: V/getLng() - LONGITUDE(18567): Row: 1, Values: 3.9412
02-24 12:58:56.018: V/getLng() - LONGITUDE(18567): Row: 2, Values: 3.1811
02-24 12:58:56.018: V/getLng() - LONGITUDE(18567): Row: 3, Values: 3.9723
02-24 12:58:56.018: V/getLng() - LONGITUDE(18567): Row: 4, Values: 3.9883
02-24 12:58:56.020: V/getLng() - LONGITUDE(18567): Row: 5, Values: 3.943
02-24 12:58:56.020: V/getLng() - LONGITUDE(18567): Row: 6, Values: 4.06461
02-24 12:58:56.020: V/getLng() - LONGITUDE(18567): Row: 7, Values: 4.00297
02-24 12:58:56.020: V/getLng() - LONGITUDE(18567): Row: 8, Values: 4.16791
02-24 12:58:56.021: V/getLng() - LONGITUDE(18567): Row: 9, Values: 3.9356
02-24 12:58:56.024: V/getLng() - LONGITUDE(18567): Row: 10, Values: 4.1023
02-24 12:58:56.025: V/getLng() - LONGITUDE(18567): Row: 11, Values: 3.5628
02-24 12:58:56.026: V/getLng() - LONGITUDE(18567): Row: 12, Values: 3.562
02-24 12:58:56.027: V/getLng() - LONGITUDE(18567): Row: 13, Values: 3.5629
02-24 12:58:56.027: V/getLng() - LONGITUDE(18567): Row: 14, Values: 4.215
02-24 12:58:56.027: V/getLng() - LONGITUDE(18567): Row: 15, Values: 4.1703
02-24 12:58:56.027: V/getLng() - LONGITUDE(18567): Row: 16, Values: 4.1994
02-24 12:58:56.028: V/getLng() - LONGITUDE(18567): Row: 17, Values: 3.2677
02-24 12:58:56.028: V/getLng() - LONGITUDE(18567): Row: 18, Values: 3.2108
02-24 12:58:56.029: V/getLng() - LONGITUDE(18567): Row: 19, Values: 3.7254

【问题讨论】:

  • 您能否记录下 sLatsLng 的值,并将其作为更新发布到您的帖子中,以便我们查看这些值是否正确正确检索。
  • 当然!它已更新输出:)
  • 我只能看到纬度,您能否将其粘贴到mDB.get(i).getLng() 行之后:Log.i("MainActivity", "Latitude and Longitude " + sLat + " - " + sLng); 并发布新日志。
  • 对不起,我没有意识到它没有附加,现在一切都结束了! :)
  • mDB.get(i).getLng() 之后添加这个Log.i("MainActivity", "Latitude and Longitude: " + sLat + " - " + sLng + " - Title: " + mDB.get(i).getTitle());,这样我们可能会看到正确顺序的值,请发布更新。

标签: java android database sqlite


【解决方案1】:

没有检索纬度和经度,因为方法getLat()getLng() 从光标中检索错误。

由于您只从数据库中选择一列,因此您必须获取列索引 0,而不是像在 getLat()getLng() 方法中所做的那样获取 1 或 2。

在这些方法中,执行以下操作:

// getLat() method
_lat = latQuery.getDouble(0); 

// getLng() method
_lng = lngQuery.getDouble(0);

【讨论】:

    【解决方案2】:

    也许我遗漏了一些东西,但看起来您的 getLat() 方法实际上并没有在任何地方设置 _lat 的值(它返回的值)? getLong() 等也是如此。

    如果这不是问题,您是否尝试过调试和单步调试代码?这应该让您更好地了解 duff 值的来源。

    抱歉,我会将此添加为评论,但没有足够的代表。

    【讨论】:

    • 我现在看看,我已经通过 Log 发送了 DB,它打印出来很好,所以也许这就是原因!
    【解决方案3】:

    将数据元组(lat、lng、description 等)分开的原因是什么?我会把它放在一个有 3 列的表中(为简洁起见,将其余部分删掉):

    Latitude | Longitude | Description
    11.11    | 11.11     | Place A
    22.22    | 22.22     | place B
    

    在这种情况下,你永远不会得到像11,11; 22.22; place B 这样的记录,你的情况显然发生了什么

    【讨论】:

      猜你喜欢
      • 2014-07-25
      • 2013-12-18
      • 1970-01-01
      • 2018-07-02
      • 1970-01-01
      • 1970-01-01
      • 2012-09-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多