在 android 中查找属于 sqlite 数据库中同一行的记录

find records belonging to same row in sqlite database in android

在我的应用程序中,我有用于源坐标(用户位置)和目标坐标的文本字段。我想知道我的数据库(公交车站)中是否有任何记录靠近这些坐标。本质上,我想找到最接近用户位置和目的地位置的公交车站,我正在使用以下代码。

来源

public ArrayList<String> countDatabase(Double LAT, Double LNG) {
    String sourcename=null;
    double min_distance=99999999;
    ArrayList<String> sList = new ArrayList<>();
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);
    mCount.moveToFirst();
    while (mCount.moveToNext()) {
        double Latitude = mCount.getDouble(2);
        double Longitude = mCount.getDouble(3);
        double dis=Math.sqrt( (Latitude-LAT)*(Latitude-LAT) + (Longitude-LNG)*(Longitude-LNG) );
        if (dis<min_distance){
            sourcename=mCount.getString(1);
            sList.add(sourcename);
        }
    }
    mCount.close();
   return sList;
}

最后我得到一个数组列表(slist),其中包含使用欧拉距离公式计算的用户位置附近的所有站点的名称。将相同的过程应用于目的地以获取列表(dlist)。 现在我想知道该列表中的任何电台是否位于我数据库中的同一行,因为

for(int i=0;i<ssize;i++){
            String source = ssList.get(i);
            for(int j=0;j<dsize;j++) {
                String destination = ddList.get(j);
                Boolean b = myDb.findBus(source, destination);
                if(b){
                    TextView tvv = (TextView) findViewById(R.id.textView7);
                    tvv.setText(source+" and "+destination);
                }
            }

        }

findBus

 public Boolean findBus(String sourcename, String desname){
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor mCount= db.rawQuery("select count(*) from search_table where name='" + sourcename + "' AND dname='"+desname+"'", null);
    mCount.moveToFirst();
    int count= mCount.getInt(0);
    mCount.close();
    if (count>0) return true;
    else return false;
}

但我似乎无法 运行 这段代码,在

中遇到错误
 Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);

错误说

java.lang.IllegalStateException: Could not execute method for android:onClick

完整代码

数据库助手

public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "Nearby.db";
public static final String TABLE_NAME = "halt_details";
public static final String COL_2 = "snme";
public static final String COL_3 = "slati";
public static final String COL_4 = "slong";
public static final String COL_5 = "dnme";
public static final String COL_6 = "dlati";
public static final String COL_7 = "dlong";
public static final String COL_8 = "buses";

public DatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, 1);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE " + TABLE_NAME + "(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, snme VARCHAR, slati DOUBLE, slong DOUBLE, dnme VARCHAR, dlati DOUBLE, dlong DOUBLE, buses VARCHAR)");
}

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

public void insertData(String sname, Double slat, Double slng, String dname, Double dlat, Double dlng, String bus) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put("snme",sname);
    contentValues.put("slati",slat);
    contentValues.put("slong",slng);
    contentValues.put("dnme",dname);
    contentValues.put("dlati",dlat);
    contentValues.put("dlong",dlng);
    contentValues.put("buses",bus);

    db.insert(TABLE_NAME,null ,contentValues);
}

public void clearDatabase() {
    SQLiteDatabase db = this.getWritableDatabase();
    String clearDBQuery = "DELETE FROM "+TABLE_NAME;
    db.execSQL(clearDBQuery);
}

public ArrayList<String> countDatabase(Double LAT, Double LNG) {
    String sourcename=null;
    double min_distance=99999999;
    ArrayList<String> sList = new ArrayList<>();
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);
    mCount.moveToFirst();
    while (mCount.moveToNext()) {
        double Latitude = mCount.getDouble(2);
        double Longitude = mCount.getDouble(3);
        double dis=Math.sqrt( (Latitude-LAT)*(Latitude-LAT) + (Longitude-LNG)*(Longitude-LNG) );
        if (dis<min_distance){
            sourcename=mCount.getString(1);
            sList.add(sourcename);
        }
    }
    mCount.close();
   return sList;
}

public ArrayList<String> countDatabase1(Double LAT, Double LNG) {
    String destinationname=null;
    ArrayList<String> dList = new ArrayList<>();
    double min_distance=99999999;
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);
    mCount.moveToFirst();
    while (mCount.moveToNext()) {
        double Latitude = mCount.getDouble(2);
        double Longitude = mCount.getDouble(3);
        double dis=Math.sqrt( (Latitude-LAT)*(Latitude-LAT) + (Longitude-LNG)*(Longitude-LNG) );
        if (dis<min_distance){
            destinationname = mCount.getString(4);
            dList.add(destinationname);

        }
    }
    mCount.close();
    return dList;
}

public Boolean findBus(String sourcename, String desname){
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor mCount= db.rawQuery("select count(*) from search_table where name='" + sourcename + "' AND dname='"+desname+"'", null);
    mCount.moveToFirst();
    int count= mCount.getInt(0);
    mCount.close();
    if (count>0) return true;
    else return false;
}


public Cursor getAllData() {
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor res = db.rawQuery("select * from " + TABLE_NAME, null);
    return res;
}

}

Result.java

public class result extends Activity {
DatabaseHelper myDb;

@Override
protected void onCreate(Bundle savedInstanceState) {
    myDb = new DatabaseHelper(this);

    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_result);
    String url = getIntent().getExtras().getString("username");
    String url1 = getIntent().getExtras().getString("username1");
    TextView tv= (TextView)findViewById(R.id.textView2);
    TextView tv1= (TextView)findViewById(R.id.textView5);
    tv.setText(url);
    tv1.setText(url1);

    String[] separated = url.split("_");
    String srclat = separated[0];
        Double dsrclat= Double.parseDouble(srclat);
    String srclng = separated[1];
        Double dsrclng= Double.parseDouble(srclng);

    String[] separated1 = url.split("_");
    String deslat = separated1[0];
         Double ddeslat= Double.parseDouble(deslat);
    String deslng = separated1[1];
         Double ddeslng= Double.parseDouble(deslng);

}

public void Database(View view){
    Intent intent = new Intent(result.this, feeder.class);
    startActivity(intent);
}


public void NearestValue(View view){


    TextView tv= (TextView)findViewById(R.id.textView2);
    String s1 = tv.getText().toString();
    String[] separated = s1.split("_");
    String deslat = separated[0];
    Double Lat= Double.parseDouble(deslat);
    String deslng = separated[1];
    Double Lng= Double.parseDouble(deslng);
    ArrayList<String> ssList = new ArrayList<>();
    ssList = myDb.countDatabase(Lat,Lng);
    int ssize = ssList.size();
    TextView tvvv = (TextView) findViewById(R.id.textView8);
    for(int i=0;i<ssize;i++) {
        tvvv.setText(ssList.get(i));
    }

    TextView tv1= (TextView)findViewById(R.id.textView5);
    String s11 = tv1.getText().toString();
    String[] separated1 = s11.split("_");
    String deslat1 = separated1[0];
    Double Lat1= Double.parseDouble(deslat1);
    String deslng1 = separated1[1];
    Double Lng1= Double.parseDouble(deslng1);
    ArrayList<String> ddList = new ArrayList<>();
    ddList = myDb.countDatabase1(Lat1,Lng1);
    int dsize = ddList.size();
    TextView tvvvv = (TextView) findViewById(R.id.textView9);
    for(int i=0;i<dsize;i++) {
        tvvv.setText(ddList.get(i));
    }

        for(int i=0;i<ssize;i++){
            String source = ssList.get(i);
            for(int j=0;j<dsize;j++) {
                String destination = ddList.get(j);
                Boolean b = myDb.findBus(source, destination);
                if(b){
                    TextView tvv = (TextView) findViewById(R.id.textView7);
                    tvv.setText(source+" and "+destination);
                }
            }

        }

    }

}

结果,xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">


<TextView
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
    android:layout_marginStart="136dp"
    android:layout_marginTop="84dp"
    android:text="TextView"
    android:textColor="@color/colorAccent" />

<TextView
    android:id="@+id/textView5"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignStart="@+id/textView2"
    android:layout_below="@+id/textView2"
    android:layout_marginTop="97dp"
    android:text="TextView"
    android:textColor="@color/colorAccent" />

<TextView
    android:id="@+id/textView7"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/nearest"
    android:layout_marginEnd="14dp"
    android:layout_marginTop="88dp"
    android:layout_toStartOf="@+id/nearest"
    android:textColor="@color/colorAccent"
    android:textSize="30sp"
    tools:text="tv" />

<Button
    android:id="@+id/nearest"
    android:layout_width="130sp"
    android:layout_height="50dp"
    android:onClick="NearestValue"
    android:layout_alignStart="@+id/gotodb"
    android:layout_alignTop="@+id/gotodb"
    android:layout_marginTop="76dp"
    android:background="@drawable/buttonshape"
    android:shadowColor="#6C74A8"
    android:shadowDx="6"
    android:shadowDy="0"
    android:shadowRadius="9"
    android:text="nearest bus stop"
    android:textColor="#43456B"
    android:textColorLink="@android:color/holo_blue_bright"
    android:textSize="15sp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="1.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.95" />

<TextView
    android:id="@+id/gotodb"
    android:layout_width="130sp"
    android:layout_height="50dp"
    android:layout_alignParentEnd="true"
    android:layout_below="@+id/textView5"
    android:onClick="Database"

    android:text="database"
    android:textColor="@android:color/background_light"
    android:textColorLink="@android:color/holo_blue_bright"
    android:textSize="15sp" />

<TextView
    android:id="@+id/textView8"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/nearest"
    android:layout_marginEnd="38dp"
    android:layout_marginTop="20dp"
    android:layout_toStartOf="@+id/textView5"
    android:text="TextView" />

<TextView
    android:id="@+id/textView9"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignEnd="@+id/textView8"
    android:layout_alignTop="@+id/textView7"
    android:layout_marginTop="31dp"
    android:text="TextView" />

以下,假设 LAT 为 10,LNG 为 30,:-

Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);

等于:-

SELECT snme FROM halt_details 
    WHERE slati BETWEEN '10- 0.1' AND '10+ 0.1' 
        AND slng BETWEEN '30- 0.1' AND '30+ 0.1';

您遇到的第一个问题是没有列 slng 它实际上应该是 slong (至少根据代码你已经展示了)。

进行此更改将导致查询 运行,但结果不太可能是所需的结果(很可能什么也检索不到)。这是因为您用单引号将数值括起来,使它们成为一个完整的字符串,例如 10-0.1。不会执行算术运算,范围将在字符串之间。

而结果 SQL 应该是这样的:-

SELECT snme FROM halt_details 
    WHERE slati BETWEEN 10-0.1 AND (10+0.1) 
    AND slong BETWEEN (30-0.1) AND (30+0.1);

所以代码是:-

Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN (" +LAT+"- 0.1) AND "+LAT+" + 0.1) AND slong BETWEEN (" +LNG+"- 0.1) AND ("+LNG+" + 0.1)", null);

但是,如果您使用保存列名的可用变量,就不会遇到第一个错误。所以上面可能是:-

Cursor mCount= db.rawQuery("SELECT " + DatabaseHelper.COL_2 + " FROM " + DatabaseHelper.TABLE_NAME + "s WHERE " + DatabaseHelper.COL_3 + " BETWEEN (" +LAT+"- 0.1) AND "+LAT+" + 0.1) AND " + DatabaseHelper.COL_4 + " BETWEEN (" +LNG+"- 0.1) AND ("+LNG+" + 0.1)", null);
  • 当然,这种依赖单一定义的方法可以贯穿始终。

您在整个结果游标中移动以及尝试提取数据时似乎也有错误。以代码为例:-

Cursor mCount= db.rawQuery("SELECT snme FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);
mCount.moveToFirst();
while (mCount.moveToNext()) {
    double Latitude = mCount.getDouble(2);
    double Longitude = mCount.getDouble(3);
    double dis=Math.sqrt( (Latitude-LAT)*(Latitude-LAT) + (Longitude-LNG)*(Longitude-LNG) );
    if (dis<min_distance){
        destinationname = mCount.getString(4);
        dList.add(destinationname);

    }
}
mCount.close();

查询将 return 游标表示有 2 行。每行将有一个名为 snme.

的列

首先移动到第一行,然后移动到下一行。所以 2 行现在是 1。(删除行 mCount.moveToFirst(); 将导致所有行都被处理)。

然后您尝试在偏移量 2(第三列)处获取游标列。但是,游标只有一列,因此您会收到错误消息。与偏移量 3 相同。游标中唯一存在的列是偏移量 0。

假设您需要额外的列,最简单的解决方法可能是编写代码:-

Cursor mCount= db.rawQuery("SELECT * FROM halt_details WHERE slati BETWEEN '" +LAT+"- 0.1' AND '"+LAT+" + 0.1' AND slng BETWEEN '" +LNG+"- 0.1' AND '"+LNG+" + 0.1'", null);
    • 等于获取所有列。
  • 上面提到的注意更正没有包含在above.All上面显示的是如何获取所有列。

注意 上述代码尚未经过测试,仅用作 in-principle.