I am stuck with SimpleCursorAdapter, I am calling my local SQLite DB and putting it into a cursor which then is passed to the SimpleCursorAdapter.
For same reason the Log Cat keeps showing this error below. I have no idea what is going on and I have been working on this for 6 hours, I didn't think SimpleCursorAdapter would be so difficult to understand.
05-28 19:47:27.524: ERROR/AndroidRuntime(9353): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nyneaxis.android.mpg/com.nyneaxis.android.mpg.userInfo}: java.lang.IllegalArgumentException: column '_id' does not exist
setArray();
rec.open();
Cursor c = rec.getAllVeh();
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.userinfo, c, new String[]{c.getString(1)}, new int[]{R.id.nameTxtL});
this.setListAdapter(adapter);
rec.close();
//data adapter
public Cursor getAllVeh() {
try{
return db.query(database_table, new String[] { key_rowid, vehicle_name,
year, make, model, style, vin, plate, notes }, null, null,
null, null, null);
}finally{
}
}
Okay I have modified my code to a rawQuery and I get this error again:
05-28 22:41:48.876: ERROR/AndroidRuntime(1359): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nyneaxis.android.mpg/com.nyneaxis.android.mpg.userInfo}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0
private static final String db_sel = "SELECT id as _id, vehicle_name FROM vehicle";
public Cursor getAllVeh() {
try{
return db.rawQuery(db_sel, null);
/*return db.query(database_table, new String[] { key_rowid, vehicle_name,
year, make, model, style, vin, plate, notes }, null, null,
null, null, null);*/
}finally{
}
}
See my answer to this question Android: column '_id' does not exist problem. It explains about the need for the _id column and how to alias it if your DB tables don't have a column with that name.
****EDIT:**** To alias the column in the DB which contains 'unique identifiers' you need to use db.rawQuery(...) instead of db.query(...). The db.rawQuery(...) method takes a SQL string which will allow you to alias the column name to '_id' which is required by the adapter. Example...
Cursor c = db.rawQuery("SELECT <my_unique_column_name> as _id, vehicle_name, ... FROM vehicles");
In the above, replace <my_unique_column_name> with the actual name of the column in the vehicles table which contains unique identifiers. Also, use the actual column names for any other columns that you're requesting the data for.
Well, as the error says your database table definition is missing the default _id column that SimpleCursorAdapter expects to use as the ID column. What is your database table defined as? Add the CREATE TABLE statement you are using to your question.
SimpleCursorAdapter relies on the presence of an _id column: if you don't have it then you'll get that error.
Thanks guys for all you help. I managed to do it a different way and it seems to work like a charm. If anyone has any question or suggestions let me know.
Cursor c = rec.getAllVeh();
while (c.moveToNext()) {
String vehName = c.getString(1);
vehInfo.add(vehName);
}
//put information into the addapter for listview
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_single_choice, vehInfo);
//applies adapter to listview
list.setAdapter(adapter);
Related
I have two tables atm, users and notes. I am trying to retrieve data that belongs to the user. So all data to list must be owned by the original user and shown only to him. I have made my table in Databasehelper.
I have made a new class that controls the notes table. In listNotes() I want to loop through the cursor row and get all data owned by the user. Am I quering it correctly?
// Listing all notes
public Cursor listNotes() {
Cursor c = db.query(help.NOTE_TABLE, new String[]{help.COLUMN_TITLE,help.COLUMN_BODY, help.COLUMN_DATE}, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
db.close();
return c;
}
I then want to display the cursor data collected in a listview
public void populateList(){
Cursor cursor = control.listNotes();
getActivity().startManagingCursor(cursor);
//Mapping the fields cursor to text views
String[] fields = new String[]{help.COLUMN_TITLE,help.COLUMN_BODY, help.COLUMN_DATE};
int [] text = new int[] {R.id.item_title,R.id.item_body, R.id.item_date};
adapter = new SimpleCursorAdapter(getActivity(),R.layout.list_layout,cursor, fields, text,0);
//Calling list object instance
listView = (ListView) getView().findViewById(android.R.id.list);
adapter.notifyDataSetChanged();
listView.setAdapter(adapter);
}
You aren't creating the NOTE_TABLE right.
You miss a space and a comma here
+ COLUMN_DATE + "DATETIME DEFAULT CURRENT_TIMESTAMP"
It has to be
+ COLUMN_DATE + " DATETIME DEFAULT CURRENT_TIMESTAMP,"
There are two issues here:
One is you have missed a comma (after the Timestamp as specified in an earlier answer).
The other error you have is when using a SimpleCursorAdapter, you need to ensure that the Projection string array includes something to index the rows uniquely and this must be an integer column named as "_id". SQLite already has a feature built in for this and provides a column named "_id" for this purpose (however you can have your own integer column which you can rename to _id). To solve this, change your projection string array to something like:
new String[] {"ROW_ID AS _id", help.COLUMN_TITLE,help.COLUMN_BODY, help.COLUMN_DATE}
I guess the NullPointerException stems from this (but without the stacktrace I don't know for sure).
So yeah, I've seen questions about this all over the place, and so have accordingly added an _id alias to my query as below:
SimpleCursorAdapter sca = new SimpleCursorAdapter(getActivity(),
R.layout.activity_contact_list, cursor, new String[] {
"rowid _id", DBOps.COL_CATNAME },
new int[] { R.id.contact_list }, CursorAdapter.NO_SELECTION);
I'm creating my cursor like so:
public Cursor getAllCategories() {
return mDB.query(TABLE_NAME, new String[] { "rowid _id", COL_ID,
COL_CATNAME,
COL_ICONPATH }, null, null, null, null, null);
}
mDB in the above is a SQLite database.
I've tried changing the string to rowid as _id, which also doesn't work. Also apparently there's no need to change my table structure by adding another _id column as a few others have noted, so where am I going wrong here?
Update - here's the stack trace -
Caused by: java.lang.IllegalArgumentException: column 'rowid _id' does not exist
at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:303)
at android.widget.SimpleCursorAdapter.findColumns(SimpleCursorAdapter.java:333)
at android.widget.SimpleCursorAdapter.<init>(SimpleCursorAdapter.java:107)
at com.rex.bizcontacts.ContactListFragment.onCreate(ContactListFragment.java:77)
No, you're not getting the problem.
The comment you are complaining about has the right idea. rowid _id is not a valid name. You can tell that by looking at the exception.
You are welcome to try "rowid AS _id" instead of "rowid _id". I would recommend rawQuery() rather than query(), so this can be written more naturally ("SELECT rowid AS _id, ...").
I am trying to Query in the database.The database is not created in the app, I have created outside, and I am using as this tutorial explain. But I have an error related with column _id.
In the Class DatabaseHelper, I have the following code:
public Cursor Search(Context context,String search){
SQLiteDatabase db= getReadableDatabase();
String cursorFactory = "SELECT * FROM words WHERE eng || ' ' || rus LIKE ?";
Cursor cursor = db.rawQuery(cursorFactory, new String[]{"%" + search + "%"});
return cursor;
}
In the Activity, the code I wrote is:
public void search(View v){
text2search= searchText.getText().toString();
cursor= myDbHelper.Search(mContext, text2search);
adapter =new SimpleCursorAdapter(getBaseContext(),R.layout.list_item,
cursor,
new String[]{"rusword","engword","kind"},
new int[]{R.id.rusWord,R.id.engWord,R.id.knd});
wordsList.setAdapter(adapter);
}
And I get the error related with the _id:(in the LogCat)
09-03 14:12:38.018: E/AndroidRuntime(16581): Caused by:
java.lang.IllegalArgumentException: column '_id' does not exist
But the data base, that I create, it has the "_id" column:( I cant upload image, so here is the link https://www.dropbox.com/s/9a2ol1acrnxmzob/sql-db-rusWjpg.png )
Thank you!
So problem isn't too tricky. Some adapters, in you case SimpleCursorAdapter this adapter needs when are try to select something you need to select column _id.
So try this:
new String[] {"_id", "rusword", "engword", "kind"}
String cursorFactory = "SELECT _id, [next columns] FROM ...;
now it should works.
Similar question is here:
App Crashes On Startup Due To java.lang.IllegalArgumentException:
column '_id' does not
exist
Note: In the case you don't want to have _id column you can use this simple trick:
SELECT keyID AS _id FROM TableName
Since a few month I am engaged with Android development and now I have a problem I dont get the right answer.
I have a ListView with data filled from a SimpleCursorAdapter. The query which should provides the results has a where statement, but it returns all records of the table.
final Cursor c = mStorage.loadList();
startManagingCursor(c);
c.moveToFirst();
final ListCursorAdapter adapter =
new ListCursorAdapterAusgabe(this, R.layout.listview,
c, FROM, TO);
adapter.setViewBinder(new ListViewBinderAusgabe());
setListAdapter(adapter);
The query:
int mode = 0;
public Cursor loadList() {
return mDb.getReadableDatabase().query(TABLE.NAME, TABLE.ALL_COLUMNS,
"mode=?", new String [] {String.valueOf(mode)}, null, null, null, null);
}
In read in this forum that there must be an _id column: In the above mentioned table there is one column with "_id". I also tried to enter "mode" in single quotations and double quotations but it didn't work. Has anybody an idea?
Thank you in advance,
Hadja
Have you tried
return mDb.getReadableDatabase().query(TABLE.NAME, TABLE.ALL_COLUMNS,
"mode=" + String.valueOf(mode), null, null, null, null, null);
?
Here is my code for a simple cursor adapter.
public class CursorList extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DatabaseAdapter da = new DatabaseAdapter(this, "mydb.sqlite");
da.open();
Cursor cur = da.fetchAllRecords("Doctors", new String[]{"FirstName"});
startManagingCursor(cur);
cur.moveToFirst();
do {
Log.v("Info", cur.getString(cur.getColumnIndex("FirstName")));
} while(cur.moveToNext());
cur.moveToFirst();
String[] from = new String[]{"FirstName"};
int[] to = new int[]{R.id.row};
SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.row_item, cur, from, to);
setListAdapter(sca);
}
}
The data records are displayed correctly in the log, but the code stops working when it reaches the
SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.row_item, cur, from, to);
line.
The error I get is :
ERROR/AndroidRuntime(26746): Uncaught handler: thread main exiting due to uncaught exception
ERROR/AndroidRuntime(26746): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.arnab.cursorlist/com.arnab.cursorlist.CursorList}:
java.lang.IllegalArgumentException: column '_id' does not exist
Where am I going wrong?
Why does it give an error that column '_id' doesn't exist? Is it a necessary column which we have to have in our tables?
EDIT:
When I put the cursor related code in a try catch block, something like this:
try {
SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.row_item, cur, from, to);
setListAdapter(sca);
}
catch(Exception E) {
Log.v("Error", E.getMessage());
}
I get the message :
VERBOSE/Error(1026): column '_id' does not exist
#Rasel : Here is the fetchAllRecords method
public Cursor fetchAllRecords(String table, String columns[]) {
return mDb.query(table, columns, null, null, null, null, null);
}
Why does it give an error that column '_id' doesn't exist? Is it a necessary column which we have to have in our tables?
Yes, if you want to use your database information in a cursor adapter. The adapter uses it for internal purposes. Your table must have an '_id' column, and you must select it in your query (so it is in the Cursor result set). You do not have to actually display it in your ListView.
Revised for Posterity
Instead of actually adding the '_id' column, you can SELECT your own 'id' column as '_id', and it will work just the same.
Write Cursor related code in try catch block.Your problem will be solved.Check when created table you typed different column rather than '_id'
You need to include the table _id in the projection. the list cursor adapter needs the _id to keep track of the rows. you don't have to actually display it anywhere or use it but the cursor needs to contain that column. also a primary key column named _id is mandatory in every android table.