2014-01-28 18 views
0

我想创建一个简单的联系人列表应用程序。当我想创建一个新的联系人并输入联系人的字段并按下保存按钮时,我遇到了“非法异常列ID不存在”的错误。使用简单的适配器不存在列_id'

我正在使用简单的游标适配器来显示数据库中的数据以列出小部件。

这里是我的源代码:

public class WebpreneurActivity extends ListActivity { 

    private static final int CONTACT_CREATE = 0; 
    private static final int CONTACT_EDIT = 1; 

    //select the second one, Android view menu 
    private static final int INSERT_ID = Menu.FIRST; 
    private static final int DELETE_ID = Menu.FIRST + 1; 

    private DBHandler dbHelper; 
    private Cursor c; 
    ImageButton imageButton; 
    long rowid; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     Log.d("database1" ,"0"); 
     Log.d("Your Location4", "ok4:"); 
     super.onCreate(savedInstanceState); 
     Log.d("database1" ,"1"); 
     setContentView(R.layout.activity_webpreneur); 
     Log.d("database1" ,"2"); 
     dbHelper = new DBHandler(this); 
     Log.d("database1" ,"3"); 
     dbHelper.open(); 
     //addListenerOnButton(); 
     //dbHelper.addContact(); 

     imageButton = (ImageButton) findViewById(R.id.imageButton1); 
     Log.d("database1" ,"button"); 
     imageButton.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       Log.d("database1" ,"b4"); 
       Intent i = new Intent(getApplicationContext(), ContactEdit.class); 
       startActivityForResult(i, CONTACT_CREATE); 

       Log.d("database1" ,"button3"); 
       //fillData(); 

      } 

     }); 

     //dbHelper.close(); 
    } 

    @SuppressWarnings("deprecation") 
    public void fillData() { 
     Log.d("Your Location4", "ok6:"); 
     c = dbHelper.fetchAllRows(); 
     Log.d("Your Location4", "ok8:"); 
     startManagingCursor(c); 
     Log.d("Your Location4", "ok2:"); 
     // point of error !!!! 
     //////  ListAdapter adapter = new SimpleCursorAdapter(this, 
     R.layout.contact_row, c, new String[] { DBHandler.Key_Name, 
         DBHandler.Key_Phone }, new int[] { R.id.name, 
         R.id.phonenumber }); 
     setListAdapter(adapter); 
    } 

    protected void onListItemClick(ListView l, View v, int position, long id) { 
     super.onListItemClick(l, v, position, id); 

     Intent i = new Intent(this, ContactEdit.class); 
     i.putExtra(DBHandler.Key_ID, c.getLong(c.getColumnIndex(DBHandler.Key_ID))); 
     i.putExtra(DBHandler.Key_Name, c.getString(c.getColumnIndex(DBHandler.Key_Name))); 
     i.putExtra(DBHandler.Key_Address, c.getString(c.getColumnIndex(DBHandler.Key_Address))); 
     i.putExtra(DBHandler.Key_Phone, c.getString(c.getColumnIndex(DBHandler.Key_Phone))); 
     i.putExtra(DBHandler.Key_Website, c.getString(c.getColumnIndex(DBHandler.Key_Home))); 
     startActivityForResult(i, CONTACT_EDIT); 
    } 

    protected void onActivityResult(int requestCode, int resultCode, 
      Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 

     if (resultCode == RESULT_OK) { 
      String name = data.getStringExtra(DBHandler.Key_Name); 
      String address = data.getStringExtra(DBHandler.Key_Address); 
      String mobile = data.getStringExtra(DBHandler.Key_Phone); 
      String home = data.getStringExtra(DBHandler.Key_Home); 
      switch (requestCode) { 
       case CONTACT_CREATE: 
        Log.d("Your Location4", "jj:"); 
        dbHelper.createRow(name, address, mobile, home); 
        Log.d("Your Location4", "ok90:"); 
        fillData(); 
        break; 
       case CONTACT_EDIT: 

        String id = data.getStringExtra(DBHandler.Key_ID); 


        long rowId=Long.parseLong(id); 

        if (rowId != (Long)null){ 
         dbHelper.updateRow(rowId, name, address, mobile, home); 
        } 
        fillData(); 
        break; 

      } 
     } 
    } 
} 

这里是我的LOG CAT

01-28 13:34:34.841: D/AndroidRuntime(24324): Shutting down VM 
     01-28 13:34:34.841: W/dalvikvm(24324): threadid=1: thread exiting with uncaught exception (group=0x4001d578) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): FATAL EXCEPTION: main 
     01-28 13:34:34.871: E/AndroidRuntime(24324): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { (has extras) }} to activity {com.webpreneur_contactlist/com.webpreneur_contactlist.WebpreneurActivity}: java.lang.IllegalArgumentException: column '_id' does not exist 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.app.ActivityThread.deliverResults(ActivityThread.java:2553) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.app.ActivityThread.handleSendResult(ActivityThread.java:2595) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.app.ActivityThread.access$2000(ActivityThread.java:121) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:973) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.os.Handler.dispatchMessage(Handler.java:99) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.os.Looper.loop(Looper.java:138) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.app.ActivityThread.main(ActivityThread.java:3701) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at java.lang.reflect.Method.invokeNative(Native Method) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at java.lang.reflect.Method.invoke(Method.java:507) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at dalvik.system.NativeStart.main(Native Method) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): Caused by: java.lang.IllegalArgumentException: column '_id' does not exist 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.support.v4.widget.CursorAdapter.init(CursorAdapter.java:174) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.support.v4.widget.CursorAdapter.<init>(CursorAdapter.java:122) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.support.v4.widget.ResourceCursorAdapter.<init>(ResourceCursorAdapter.java:54) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.support.v4.widget.SimpleCursorAdapter.<init>(SimpleCursorAdapter.java:63) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at com.webpreneur_contactlist.WebpreneurActivity.fillData(WebpreneurActivity.java:82) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at com.webpreneur_contactlist.WebpreneurActivity.onActivityResult(WebpreneurActivity.java:117) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.app.Activity.dispatchActivityResult(Activity.java:3908) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): at android.app.ActivityThread.deliverResults(ActivityThread.java:2549) 
     01-28 13:34:34.871: E/AndroidRuntime(24324): ... 11 more 

我Dbhandler类 ///////////////// 公共类DBHandler延伸SQLiteOpenHelper {

private static final int DB_Version = 1; 

    private static final String DB_Name = "Places"; 

    protected static final String Places_Table = "Places"; 
    private String DB_PATH=""; 

    String name, Address, Website,ID; 
    //WebpreneurActivity Contact; 
public static final String Key_ID = "ID"; 
public static final String Key_Name = "Name"; 
public static final String Key_Phone = "Phone"; 
public static final String Key_Address = "Address"; 
public static final String Key_Website = "Website"; 
public static final String Key_Home = "HOME"; 
public static final String PROJECTION[] = { 
    Key_ID, 
    Key_Name, 
    Key_Address, 
    Key_Phone, 
    Key_Home 
}; 

    String CREATE_PLACES_TABLE = "create table if not exists Places_Table (id integer primary key ,"+ 
      "name VARCHAR not null, phone VARCHAR not null, address VARCAHR not null, website VARCHAR not null,Home VARCHAR not null)"; 

    private final Context context; 
    private static SQLiteDatabase db; 

    public DBHandler(Context context) { 

     super(context, DB_Name, null, DB_Version); 
     this.context = context; 
     DB_PATH = "/data/data/" + context.getPackageName() + "/" + "databases/"; 
     Log.d("database1" ,"4"); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     try{ 
      Log.d("DB", "DB creationnewwwww"); 
       db.execSQL("CREATE TABLE " + Places_Table + " (" + 
         Key_ID + " INTEGER PRIMARY KEY autoincrement," + 
         Key_Name + " TEXT NOT NULL," + 
         Key_Phone + " TEXT NOT NULL," + 
         Key_Address + " TEXT NOT NULL," + 
         Key_Website + " TEXT," + 
         Key_Home + " TEXT)"); 
       Log.d("DB", "DB creationnewwwwwwwwwwwwwwwwwwwwwwwwwww"); 
     } 
     catch(SQLiteException e){ 
      Log.d("DB", "DB creation excptionhhhhhhhhhhhhhhh"); 
      e.printStackTrace(); 
     } 

    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     // TODO Auto-generated method stub 

     db.execSQL("Drop Table If Exists" + Places_Table); 
     onCreate(db); 
    } 

    /* void addContact() { 
      SQLiteDatabase db = this.getWritableDatabase(); 

      ContentValues values = new ContentValues(); 
      values.put(Key_Name,Name); // Contact Name 
      values.put(KEY_COST,cost); // Contact Phone 
      values.put(Key_Address, contact.Address); //Contact phone no 

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

    public void open() 
    {Log.d("DB", "DB creation 9"); 
    db = this.getWritableDatabase(); 
     //onCreate(db); 
    Log.d("DB", "DB creation 9"); 
    String myPath = DB_PATH + DB_Name; 
    db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); 
    } 
    @Override 
    public synchronized void close() { 
     if(db != null) 
      db.close(); 
     super.close(); 
    } 

    //Adding Places 
    void addPlaces(int id, String name,String phone, String address,String url){ 

     Log.d("DB", "DB creation 1"); 
     //SinglePlaceActivity single = new SinglePlaceActivity(); Log.d("DB", "DB creation 2"); 
     ContentValues contentValues = new ContentValues(); 
     Log.d("DB", "DB creation 3"); 
     contentValues.put(Key_ID, id); 
     Log.d("DB", "DB creation 4"); 
     contentValues.put(Key_Name, name); 
     contentValues.put(Key_Phone, phone); 
     contentValues.put(Key_Address, address); 
     contentValues.put(Key_Website, url); 
     Log.d("DB", "DB creation 4"); 
     db.insert(Places_Table, null, contentValues); 
     Log.d("DB", "DB creation 5555"); 
     //db.close(); 
    } 

    public String getdata() { 
     // TODO Auto-generated method stub 
     String [] columns =new String[]{Key_ID ,Key_Name,Key_Address,Key_Website}; 
     Cursor c =db.query(DB_Name, columns, null, null, null, null, null); 
     String Result=""; 
     int iRow=c.getColumnIndex(Key_ID); 
     int iName=c.getColumnIndex(Key_Name); 
     int iAddress=c.getColumnIndex(Key_Address); 
     int iWebsite=c.getColumnIndex(Key_Website); 
     for(c.moveToFirst();!c.isAfterLast();c.moveToNext()){ 
      Result=Result+c.getString(iRow)+" "+c.getString(iName)+ " "+c.getString(iAddress)+ " "+c.getString(iWebsite)+ "\n"; 
     } 

     return Result; 
    } 


    public void createRow(String name, String address, String Phone, String home) 
    {SQLiteDatabase db = this.getWritableDatabase(); 
     ContentValues initialValues = new ContentValues(); 
     initialValues.put(Key_Name, name); 
     initialValues.put(Key_Address, address); 
     initialValues.put(Key_Phone, Phone); 
     initialValues.put(Key_Home, home); 
       //pass the initialValues to the database to insert the row 
     Log.d(Key_Home, home); 
     db.insert(Places_Table, null, initialValues); 
     Log.d("Your Location4", "okna:"); 
    } 

     public void deleteRow(long rowId){ 
     db.delete(Places_Table, Key_ID+"="+rowId,null); 
    } 

     public boolean updateRow (long rowId, String name, String address, String Phone, String home){ 
     ContentValues args = new ContentValues(); 
     args.put(Key_Name, name); 
     args.put(Key_Address, address); 
     args.put(Key_Phone, Phone); 
     args.put(Key_Home, home); 
     return db.update(Places_Table, args, Key_ID +"="+ rowId, null)>0; 
    } 
     public Cursor fetchRow(long rowId) throws SQLException{ 
      Cursor result = db.query(Places_Table, null, 
        Key_ID + "=" + rowId, null, null, null,null); 
      if ((result.equals(rowId)) || !result.isFirst()) { 
       throw new SQLException("No note matching ID: " + rowId); 
      } 
      return result; 
     } 

     public Cursor fetchAllRows(){ 
      Log.d("Your Location4", "ok99:"); 
      return db.query(Places_Table, PROJECTION, 
        null, null, null, null, null); 

     } 

} 
+0

确定你有一列_id? – Raghunandan

+0

我MADE key_id autoincremented,否则我没有任何colomn编号据我所知,但请帮我解决这个问题,因为我累了。 – Shazar

+0

您是否对数据库结构进行了任何更改?如果您这样做了,则需要卸载该应用程序,然后将其重新安装到您正在测试的设备/模拟器中。 – 2014-01-28 08:44:48

回答

2

光标适配器需要一个_id字段在光标上工作。 http://developer.android.com/reference/android/widget/CursorAdapter.html

您可以使用的是以下CursorWrapper,它允许您将_id设置为所需的任何字段。 https://groups.google.com/d/msg/ormlite-user/SbRoHIov5pI/-8Ir3pEycw0J

如前所述由谷歌用户JC:你fillData

@SuppressWarnings("deprecation") 
public void fillData() { 
    Log.d("Your Location4", "ok6:"); 
    // Load the Cursor in the normal way 
    c = dbHelper.fetchAllRows(); 
    // wrap the cursor in the NoIdCursorWrapper to handle the missing _id field 
    // (int this case the DBHandler.Key_ID field will act as the _id) 
    NoIdCursorWrapper nc = new NoIdCursorWrapper(c, DBHandler.Key_ID); 
    Log.d("Your Location4", "ok8:"); 
    startManagingCursor(c); 
    Log.d("Your Location4", "ok2:"); 

    // Add the NoIdCursorWrapper instead of the Cursor itself 
    ListAdapter adapter = new SimpleCursorAdapter(this, 
        R.layout.contact_row, nc, new String[] { DBHandler.Key_Name, 
        DBHandler.Key_Phone }, new int[] { R.id.name, 
        R.id.phonenumber }); 
    setListAdapter(adapter); 
} 
+0

你能帮我解决这个问题现在我完全空白来解决这个问题吗? – Shazar

+0

但我如何将此代码与我的代码集成? – Shazar

+0

您在适配器中使用CursorWrapper而不是您的光标。以正常的方式阅读Cursor,然后创建'Cursor作为参数的NoIdCursorWrapper',并将Wrapper传递给Adapter而不是Cursor。 –

-1

/** 
* A {@link CursorWrapper} implementation that allows a {@link Cursor} 
* without a field named "_id" to be used with various Android {@link ListView} 
* classes that expect a column named "_id". This is done by specifying an 
* alias field name to be used in place of "_id". 
* 
* @author [email protected] 
*/ 
public class NoIdCursorWrapper extends CursorWrapper { 

    private int idColumnIndex; 

    /** 
    * Create a NoIdCursorWrapper using the alias column index. 
    * @param c the cursor to wrap 
    * @param idColumnIndex the column index to use as the _id column 
     alias 
    */ 
    public NoIdCursorWrapper(Cursor c, int idColumnIndex) { 
      super(c); 
      this.idColumnIndex = idColumnIndex; 
    } 

    /** 
    * Create a NoIdCursorWrapper using the alias column name. 
    * @param c the cursor to wrap 
    * @param idColumnName the column name to use as the _id column alias 
    */ 
    public NoIdCursorWrapper(Cursor c, String idColumnName) { 
      super(c); 
      idColumnIndex = c.getColumnIndex(idColumnName); 
    } 

    @Override 
    public int getColumnIndex(String columnName) { 
      int index = super.getColumnIndex(columnName); 
      if (index < 0 && "_id".equals(columnName)) { 
        index = idColumnIndex; 
      } 
      return index; 
    }; 


    @Override 
    public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException { 
      int index = getColumnIndex(columnName); 
      if (index>=0) { 
        return index; 
      } 
      // let the AbstractCursor generate the exception 
      return super.getColumnIndexOrThrow(columnName); 
    }; 

}

然后你必须包括在您的适配器_id列,即使你不要显示它。

ListAdapter adapter = new SimpleCursorAdapter(this, 
    R.layout.contact_row, c, new String[] { "_id", DBHandler.Key_Name, 
        DBHandler.Key_Phone }, new int[] { R.id.name, 
        R.id.phonenumber }); 
+0

在游标中,是的,不在'from'列中。 – laalto

0

PROJECTIONKey_ID这是"ID"。所有CursorAdapters都要求有一个名称为"_id"的列。你应该真的将你的id列重命名为_id。作为一个快速的解决方法,你也可以创建一个列别名:

public static final String PROJECTION[] = { 
    Key_ID + " AS _id",