我正在尝试从数据库中填充列表视图。当我尝试使用光标时,我会得到一个错误:
android.database.sqlite.SQLiteException:编译时没有这样的列:_id(代码1):,SELECT _id FROM contacts WHERE _id ORDER BY name DESC
这是我的代码:
MainActivity.java
package com.boggs.barr.barrboggscontactlist;
import android.content.ContentValues;
import android.content.Loader;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
populateListView();
}
public static final String KEY_ID = "_id";
private void populateListView() {
String[] projection = {
KEY_ID
};
FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getApplicationContext());
SQLiteDatabase db = mDbHelper.getWritableDatabase();
String sortOrder =
FeedReaderContract.FeedEntry.COLUMN_NAME_NAME + " DESC";
Cursor cursor = db.query(
FeedReaderContract.FeedEntry.TABLE_NAME, // The table to query
projection, // The columns to return
KEY_ID, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
String[] fromColumns = new String[] {FeedReaderContract.FeedEntry.COLUMN_NAME_NAME, FeedReaderContract.FeedEntry.COLUMN_NAME_PHONE};
int[] toViews = {R.id.name, R.id.phone};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.name_and_number, cursor, fromColumns, toViews, 0);
ListView listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
FeedReaderDbHelper.java
package com.boggs.barr.barrboggscontactlist;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.sql.RowId;
/**
* Created by adnroid developer site
*/
public class FeedReaderDbHelper extends SQLiteOpenHelper {
// If you change the database schema, you must increment the database version.
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "FeedReader.db";
public static final String LONG_TYPE = " Long";
public static final String STRING_TYPE = " STRING";
public static final String BYTE_TYPE = " BYTE";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + FeedReaderContract.FeedEntry.TABLE_NAME + " (" +
FeedReaderContract.FeedEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
FeedReaderContract.FeedEntry.COLUMN_NAME_PICTURE + STRING_TYPE + COMMA_SEP +
FeedReaderContract.FeedEntry.COLUMN_NAME_NAME + STRING_TYPE + COMMA_SEP +
FeedReaderContract.FeedEntry.COLUMN_NAME_EMAIL + STRING_TYPE + COMMA_SEP +
FeedReaderContract.FeedEntry.COLUMN_NAME_PHONE + STRING_TYPE +
")";
private static final String SQL_DELETE_ENTRIES =
"DROP TABLE IF EXISTS " + FeedReaderContract.FeedEntry.TABLE_NAME;
public FeedReaderDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// This database is only a cache for online data, so its upgrade policy is
// to simply to discard the data and start over
db.execSQL(SQL_DELETE_ENTRIES);
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
FeedReaderContract.java
package com.boggs.barr.barrboggscontactlist;
import android.provider.BaseColumns;
import android.support.annotation.Nullable;
/**
* Created by android developer site.
* attempted to do database ran out of time
*/
public final class FeedReaderContract {
// To prevent someone from accidentally instantiating the contract class,
// give it an empty constructor.
public FeedReaderContract() {}
/* Inner class that defines the table contents */
public static abstract class FeedEntry implements BaseColumns {
public static final String TABLE_NAME = "contacts";
public static final String _ID = "_id";
public static final String COLUMN_NAME_PICTURE = "picture";
public static final String COLUMN_NAME_NAME = "name";
public static final String COLUMN_NAME_EMAIL = "email";
public static final String COLUMN_NAME_PHONE = "phone";
public static final Nullable COLUMN_NAME_NULLABLE = null;
}
}
我读到我需要将ID传递给光标?但我不确定这意味着什么。对我来说,它应该起作用,因为我将ID包含在要包含在光标中的列的列表中。感谢您的帮助!
编辑:我之所以问这个问题,是因为有同样问题的人提出的解决方案对我不起作用。他们一直建议尝试使用RowId或.moveToFirst来包含ID。Laalto被提出了一个对我有效的解决方案。
正如用户laalto所指出的,我需要从模拟器中卸载该应用程序,因为我更改了模式。一旦我这么做了,应用程序就开始工作了。