0

我成功地设置了一个 ListView,其中填充了 SQLite 数据库中的纬度和经度对。我编写了代码,以便我可以点击其中一对来调用谷歌地图并从用户的当前位置导航到那里。当我按住 click 时,我得到一个 dialogFragment 询问我是否要删除 LatLang 对;如果用户确认,该对将从 SQLite 数据库中删除,从列表中删除,并重新填充列表。

在让它运行良好后,我尝试重写代码以在 SQLite 数据库中包含另一列来保存 LatLang 对的字符串标签。但是现在,当我单击 LatLang 对时,没有打开 Google 地图意图,没有任何反应。当我按住单击然后确认删除时,应用程序崩溃并出现 CursorIndexOutofBoundsException。我已经尝试过调试,进一步阅读并检查 stackoverflow 档案,但我仍然不确定发生了什么。

如果有人看到任何明显的东西,请告诉我。一般来说,我对编程还是很陌生。

这是我的 SQLite DatabaseHandler 类:

package com.detimil.breadcrumbs1;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHandler extends SQLiteOpenHelper {

// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;

// Database Name
private static final String DATABASE_NAME = "breadcrumbsManager";

// Contacts table name
private static final String TABLE_BREADCRUMBS = "breadcrumbs";

// Contacts Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_LABEL = "longitude";
private static final String KEY_LATITUDE = "latitude";
private static final String KEY_LONGITUDE = "longitude";


public DatabaseHandler(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

// Creating Tables
@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_BREADCRUMBS_TABLE = "CREATE TABLE " + TABLE_BREADCRUMBS + "("
            + KEY_ID + " INTEGER PRIMARY KEY," + KEY_LABEL + " TEXT," + KEY_LATITUDE + " TEXT,"
            + KEY_LONGITUDE + " TEXT" + ")";
    db.execSQL(CREATE_BREADCRUMBS_TABLE);
}

// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // Drop older table if existed
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_BREADCRUMBS);

    // Create tables again
    onCreate(db);
}

/**
 * All CRUD(Create, Read, Update, Delete) Operations
 */


    // Adding new location/breadcrumb
public void addBreadcrumb(Breadcrumb breadcrumb) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_LABEL, breadcrumb.getBreadcrumbLabel()); // Label
        values.put(KEY_LATITUDE, breadcrumb.getBreadcrumbLatitude()); // Latitude
        values.put(KEY_LONGITUDE, breadcrumb.getBreadcrumbLongitude()); // Longitude

        // Inserting Row
        db.insert(TABLE_BREADCRUMBS, null, values);
        db.close(); // Closing database connection
    }


    // Getting single breadcrumb
public Breadcrumb getBreadcrumb(int id) {
    SQLiteDatabase db = this.getReadableDatabase();

    Cursor cursor = db.query(TABLE_BREADCRUMBS, new String[] { KEY_ID, KEY_LABEL,
            KEY_LATITUDE, KEY_LONGITUDE }, KEY_ID + "=?",
            new String[] { String.valueOf(id) }, null, null, null, null);

//(I just edited this snippet as per advice from comment below. Unfortunately, the code still does not run correctly.)
if (cursor.getCount() > 0){
        cursor.moveToFirst();
}
        Breadcrumb breadcrumb = new Breadcrumb(Integer.parseInt(cursor.getString(0)), cursor.getString(1),
        cursor.getInt(2), cursor.getInt(3));
    // return breadcrumb
    cursor.close();
    return breadcrumb;
}


    // Getting All breadcrumbs
    public List<Breadcrumb> getAllBreadcrumbs() {
 List<Breadcrumb> breadcrumbList = new ArrayList<Breadcrumb>();
    // Select All Query
    String selectQuery = "SELECT  * FROM " + TABLE_BREADCRUMBS;

    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    // looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            Breadcrumb breadcrumb = new Breadcrumb();
            breadcrumb.setId(Integer.parseInt(cursor.getString(0)));
            breadcrumb.setBreadcrumbLabel(cursor.getString(1));
            breadcrumb.setBreadcrumbLatitude(cursor.getInt(2));
            breadcrumb.setBreadcrumbLongitude(cursor.getInt(3));
            // Adding location to list
            breadcrumbList.add(breadcrumb);
        } while (cursor.moveToNext());
    }

    // return locations list
    cursor.close();
    return breadcrumbList;
}

// Getting All breadcrumb labels (leaving out the Lats and Langs)
public List<Breadcrumb> getAllBreadcrumbLabels() {
 List<Breadcrumb> breadcrumbLabelList = new ArrayList<Breadcrumb>();
// Select All Query
String selectQuery = "SELECT  * FROM " + TABLE_BREADCRUMBS;

SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);

// looping through all rows and adding to list
if (cursor.moveToFirst()) {
    do {
        Breadcrumb breadcrumb = new Breadcrumb();
        breadcrumb.setId(Integer.parseInt(cursor.getString(0)));
        breadcrumb.setBreadcrumbLabel(cursor.getString(2));
        // Adding label to list
        breadcrumbLabelList.add(breadcrumb);
    } while (cursor.moveToNext());
}

// return locations list
cursor.close();
return breadcrumbLabelList;
}

// Getting breadcrumbs/locations Count
    public int getBreadcrumbsCount() {
        String countQuery = "SELECT  * FROM " + TABLE_BREADCRUMBS;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);
        cursor.close();

        // return count
        return cursor.getCount();
    }


      //Updating single location
    public int updateBreadcrumbs(Breadcrumb breadcrumb) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_LABEL, breadcrumb.getBreadcrumbLabel());
        values.put(KEY_LATITUDE, breadcrumb.getBreadcrumbLatitude());
        values.put(KEY_LONGITUDE, breadcrumb.getBreadcrumbLongitude());

         //updating row
        return db.update(TABLE_BREADCRUMBS, values, KEY_ID + " = ?",
              new String[] { String.valueOf(breadcrumb.getId()) });
    }

    // Deleting single location
      public void deleteBreadcrumb(Breadcrumb breadcrumb) {
        SQLiteDatabase db = this.getWritableDatabase();
        int id = breadcrumb.getId();
        System.out.println("Comment deleted with id: " + id);
        db.delete(TABLE_BREADCRUMBS, KEY_ID
                + " = " + id, null);
        db.close();
          }

}

这是我在 ListView 上的活动:

package com.detimil.breadcrumbs1;

import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;


public class CollectedBreadcrumbsActivity extends Activity {

private ListView listview;
private DatabaseHandler db;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_collected_breadcrumbs);

    db = new DatabaseHandler(this);
    List<Breadcrumb> breadcrumbs = db.getAllBreadcrumbLabels();

    listview = (ListView) findViewById(R.id.list);
    ArrayAdapter<Breadcrumb> adapter = new ArrayAdapter<Breadcrumb>(this,
            android.R.layout.simple_list_item_1, breadcrumbs);
        listview.setAdapter(adapter);

this.listview.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView<?> l, View v, int position, long id) {

ArrayAdapter<Breadcrumb> adapter = (ArrayAdapter<Breadcrumb>) listview.getAdapter();
if (listview.getAdapter().getCount() > 0) {
    Breadcrumb breadcrumb = db.getBreadcrumb(position);

    final Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://maps.google.com/maps" + "&daddr=" + breadcrumb.getBreadcrumbLatitude()/1e6 + "," + breadcrumb.getBreadcrumbLongitude()/1e6));
    intent.setClassName("com.google.android.apps.maps","com.google.android.maps.MapsActivity");
    startActivity(intent);}}});

this.listview.setOnItemLongClickListener(new OnItemLongClickListener() {

public boolean onItemLongClick(AdapterView<?> l, View v, final int position, long id) {
    Log.d("HelloListView", "You clicked Item: " + id + " at position:" + position);
    Log.d("HelloListView", "Number of items in adapter:" + listview.getAdapter().getCount());

    AlertDialog.Builder alertbox = new AlertDialog.Builder(CollectedBreadcrumbsActivity.this);

    // set the message to display
    alertbox.setMessage("Delete Breadcrumb?");

    // set a positive/yes button and create a listener
    alertbox.setPositiveButton("Delete", new DialogInterface.OnClickListener() {

        // do something when the button is clicked
        public void onClick(DialogInterface arg0, int arg1) {                
            @SuppressWarnings("unchecked")
            ArrayAdapter<Breadcrumb> adapter = (ArrayAdapter<Breadcrumb>) listview.getAdapter();
            if (listview.getAdapter().getCount() > 0) {
                Breadcrumb listedBreadcrumb = (Breadcrumb) listview.getAdapter().getItem(position);
                Breadcrumb breadcrumb = db.getBreadcrumb(position);
                db.deleteBreadcrumb(breadcrumb);
                adapter.remove(listedBreadcrumb);
                }
            adapter.notifyDataSetChanged();



        }
    });

    // set a negative/no button and create a listener
    alertbox.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

        // do something when the button is clicked
        public void onClick(DialogInterface arg0, int arg1) {
        }
    });

    alertbox.show();

    return true;
    }
});

listview.setEmptyView(findViewById(R.id.empty));
}
}

SQLite 数据库首先通过单击 MainActivity 中的按钮来填充。下面的代码片段显示了按下该按钮时会发生什么:它启动另一个活动,并且(理论上?)创建一个 SQLite 行,其中包含一个字符串标签、一个表示为 int 的纬度和一个表示为诠释。

public void dropBreadcrumb(View view) {
    Intent intent = new Intent(this, DroppedCrumb.class);
    DatabaseHandler db = new DatabaseHandler(this);
    String label = "Breadcrumb"+db.getBreadcrumbsCount()+1; 
    BREADCRUMB_LATITUDE = (BREADCRUMB_LATITUDE * 1e6);
    int lat = (int)BREADCRUMB_LATITUDE;
    BREADCRUMB_LONGITUDE = (BREADCRUMB_LONGITUDE * 1e6);
    int lng = (int)BREADCRUMB_LONGITUDE;
    db.addBreadcrumb(new Breadcrumb(label, lat, lng));
    startActivity(intent);
} 

这是当我持有一个 listView 项目并确认我要删除它时得到的实际错误信息。应用程序崩溃...

05-19 14:05:25.512: D/HelloListView(2086): You clicked Item: 0 at position:0
05-19 14:05:25.512: D/HelloListView(2086): Number of items in adapter:4
05-19 14:05:25.602: I/Adreno200-EGLSUB(2086): <ConfigWindowMatch:2087>: Format RGBA_8888.
05-19 14:05:26.653: W/dalvikvm(2086): threadid=1: thread exiting with uncaught exception ( (group=0x40e4c438)
05-19 14:05:26.663: E/AndroidRuntime(2086): FATAL EXCEPTION: main
05-19 14:05:26.663: E/AndroidRuntime(2086): android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0
05-19 14:05:26.663: E/AndroidRuntime(2086):     at android.database.AbstractCursor.checkPosition(AbstractCursor.java:418)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at com.detimil.breadcrumbs1.DatabaseHandler.getBreadcrumb(DatabaseHandler.java:84)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at com.detimil.breadcrumbs1.CollectedBreadcrumbsActivity$2$1.onClick(CollectedBreadcrumbsActivity.java:72)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at android.os.Looper.loop(Looper.java:137)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at android.app.ActivityThread.main(ActivityThread.java:4950)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at java.lang.reflect.Method.invokeNative(Native Method)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at java.lang.reflect.Method.invoke(Method.java:511)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
05-19 14:05:26.663: E/AndroidRuntime(2086):     at dalvik.system.NativeStart.main(Native Method)

如果您有任何想法,我将不胜感激。请让我知道是否有任何其他信息/代码对您有用。

非常感谢。

编辑/更新:

我刚刚根据用户 nikhil 在下面的初步建议编辑了我的 getBreadcrumb 方法,但主要问题仍然存在。这是我收到的错误消息...

05-20 17:48:48.966: D/HelloListView(15738): You clicked Item: 2 at position:2
05-20 17:48:48.966: D/HelloListView(15738): Number of items in adapter:4
05-20 17:48:49.056: I/Adreno200-EGLSUB(15738): <ConfigWindowMatch:2087>: Format RGBA_8888.
05-20 17:48:50.297: W/dalvikvm(15738): threadid=1: thread exiting with uncaught exception (group=0x414db438)
05-20 17:48:50.297: E/AndroidRuntime(15738): FATAL EXCEPTION: main
05-20 17:48:50.297: E/AndroidRuntime(15738): android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0
05-20 17:48:50.297: E/AndroidRuntime(15738):    at android.database.AbstractCursor.checkPosition(AbstractCursor.java:418)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at com.detimil.breadcrumbs1.DatabaseHandler.getBreadcrumb(DatabaseHandler.java:86)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at com.detimil.breadcrumbs1.CollectedBreadcrumbsActivity$2$1.onClick(CollectedBreadcrumbsActivity.java:72)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at android.os.Handler.dispatchMessage(Handler.java:99)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at android.os.Looper.loop(Looper.java:137)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at android.app.ActivityThread.main(ActivityThread.java:4950)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at java.lang.reflect.Method.invokeNative(Native Method)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at java.lang.reflect.Method.invoke(Method.java:511)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
05-20 17:48:50.297: E/AndroidRuntime(15738):    at dalvik.system.NativeStart.main(Native Method)
4

2 回答 2

1

您有 2 列同名经度

private static final String KEY_ID = "id";
private static final String KEY_LABEL = "longitude";
private static final String KEY_LATITUDE = "latitude";
private static final String KEY_LONGITUDE = "longitude";
于 2013-05-21T09:02:32.680 回答
0

问题在于您的 getBreadCrumb 方法。当您长按第一行时,位置变量为 0(零),因此当您将此值传递给 getBreadCrumb 方法时,sql 查询失败(这意味着它不返回任何数据),因为 id(主键)始终以 1 开头. 这个问题就是因为这个语句: public Breadcrumb getBreadcrumb(int id) { SQLiteDatabase db = this.getReadableDatabase();

Cursor cursor = db.query(TABLE_BREADCRUMBS, new String[] { KEY_ID, KEY_LABEL,
        KEY_LATITUDE, KEY_LONGITUDE }, KEY_ID + "=?",
        new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor.getCount() > 0)
    cursor.moveToFirst();

    Breadcrumb breadcrumb = new Breadcrumb(Integer.parseInt(cursor.getString(0)), cursor.getString(1),

if 条件不满足,这就是为什么你的光标没有移动到指向第一行的原因,所以你在 logcat 中得到了错误。修改后的代码是:

public Breadcrumb getBreadcrumb(int id) {
SQLiteDatabase db = this.getReadableDatabase();

Cursor cursor = db.query(TABLE_BREADCRUMBS, new String[] { KEY_ID, KEY_LABEL,
        KEY_LATITUDE, KEY_LONGITUDE }, KEY_ID + "=?",
        new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor.getCount() > 0)
   { 
       cursor.moveToFirst();
       Breadcrumb breadcrumb = new Breadcrumb(Integer.parseInt(cursor.getString(0),
       cursor.getString(1),cursor.getInt(2),cursor.getInt(3));
//  return breadcrumb
   }
       cursor.close();
       return breadcrumb;

}

注意 if 条件周围的括号。

于 2013-05-19T21:55:33.880 回答