I have 2 activities(Novamensagem & Mensagenssalva) in Novamensagem.java I have a spinner with contacts values, a EditText and a Save button. I select a contact and write a text and hit save. The TEXT gets saved, and when i open Mensagenssalva.java all the TEXTs i write and save is there in a ListView. So i want to know how to the ListView show the name of the contact i selected in the Spinner and then show the message. eg:
Person's name
Message i have written.
//EDIT//
now the error is: Force to Close the app when i compile it. The code now:
ListView user = (ListView) findViewById(R.id.lvShowContatos);
//String = simple value ||| String[] = multiple values/columns
String[] campos = new String[] {"nome", "telefone"};
list = new ArrayList<String>();
c = db.query( "contatos", campos, null, null, null, null, null);
c.moveToFirst();
if(c.getCount() > 0) {
while(true) {
list.add(c.getString(c.getColumnIndex("nome")).toString());
list.add(c.getString(c.getColumnIndex("telefone")).toString());
if(!c.moveToNext()) break;
}
}
// the XML defined views which the data will be bound to
int[] to = new int[] { R.id.nome_entry, R.id.telefone_entry };
SimpleCursorAdapter myAdap = new SimpleCursorAdapter(this, R.layout.listview, c , campos, to, 0);
user.setAdapter(myAdap);
The LogCat errors:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.mensagem/com.example.mensagem.Contato}: java.lang.IllegalArgumentException: column '_id' does not exist
So the thing is, its trying to pull a "_id" from my database, but i dont have a "_id" column/row in it.
Posted from comments
You will have more control over your app while writing less lines of code by using a SimpleCursorAdapter as we discussed.
In order to use any CursorAdapter, your table must have a _id INTEGER PRIMARY KEY column, which you don't have. While I still recommend altering your table to add this column, there is a quick fix. If you don't specify a primary key all SQLite tables create an integer primary key by default, you can reference it with rowid, oid or _rowid_. But Android requires that the integer primary key column is named _id... Simply create an alias with the keyword AS for the meantime:
String[] campos = new String[] {"rowid as _id", "nome", "telefone"};
You need to create customAdapter instead of ArrayAdapter. Check out this link http://devtut.wordpress.com/2011/06/09/custom-arrayadapter-for-a-listview-android/
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).
I have a ListView with 5 TextViews and so I am using a SimpleCursorAdapter to populate it. The data's coming from a content provider.
My problem is the with the _id column. I know I have to include it for the adapter to work. My problem is, I have 5 text views and I'll set the projection array for six columns.
Arrays of to[] and from[]
static {
from = new String[] {
EmployeeProviderContract.ROW_ID,
EmployeeProviderContract.F_NAME,
EmployeeProviderContract.L_NAME,
EmployeeProviderContract.ROW_EMP_ID,
EmployeeProviderContract.AGE,
EmployeeProviderContract.SEX
};
to = new int[] {
R.id.employee_first_name,
R.id.employee_last_name,
R.id.e_employee_id,
R.id.e_age,
R.id.e_sex
};
}
As you can see, I have 5 items in the to[] and 6 items in the from[] (because of the _id).
The simple cursor adapter
mAdapter = new SimpleCursorAdapter(getApplicationContext(),
R.layout.single_row_layout, // The row template
null, // Cursor but we dont have one right now, so NULL. Will come from swapCursor()
from,// Columns to show from
to, // The layout ids i.e individual text views to show the data in
0); // Default 0 as FLAG
So as a result, when the cursor returns, it sets the value of _id in the R.id.employee_first_name and so on with the rest of the values. I dont want to show the _id in the text views. I cant remove the _id otherwise it throws an exception. How do I fix this ? Very stupid problem but I can't seem to find a proper way.
This is what is content provider query looks like
Cursor returnCursor = db.query(EmployeeProviderContract.EMP_PERSONAL_TABLE_NAME,
projection, selection , selectionArgs, null, null, sortOrder);
Note: I am extending Activity and not ListActivity.
Maybe the Cursor returned from the ContentProvider does not include an "_id" column. Check if your database table has an _id column. The best practice is to implement the BaseColumns interface in the inner class(table class) inside your Contract class, which is used by your implementation of SQLiteOpenHelper to create the database..
I have the following two queries:
A.
db.query(DBHelper.TABLE, new String[] {
DBHelper._ID, DBHelper._DATE_AND_TIME,
DBHelper._SOURCE, DBHelper._MODE,
"SUM(" + DBHelper._AMOUNT + ")" },
DBHelper._DATE_AND_TIME + " BETWEEN ? AND ?",
new String[] { date_min, date_max }, null, null, null, null);
and result of sum goes to textview like this
String.valueOf(cursor.getString(4)).
Second query B.
db.query(DBHelper.TABLE, new String[] {
DBHelper._ID, DBHelper._DATE_AND_TIME,
DBHelper._SOURCE, DBHelper._MODE,
DBHelper._AMOUNT }, DBHelper._DATE_AND_TIME
+ " BETWEEN ? AND ?", new String[] { date_min, date_max },
null, null, null, null);
and result goes to
adapter = new SimpleCursorAdapter(this, R.layout.item, cursor, from,
to, FLAG_AUTO_REQUERY);
What I want is to combine both queries. Close cursor after first query and to use same query (A) for adapter. So far I have added DBHelper._AMOUNT to SELECT of A query but ListView shows only the last entry result (not the whole data). How can I modify query A for showing SUM in TextView and then use same query for adapter.
In a normal query (like B), the database returns a result record for each table record that matches the WHERE filter.
However, when you are using an aggregate function like SUM(), the database computes a single value from all table records (or from all records in a group if you're using GROUP BY) and returns that as a single result record.
Therefore, your two queries are fundamentally different and cannot be combined into a single query.
(Please note that the first four result columns of your query A do not have any meaningful value because the result record is not guaranteed to correspond to any particular record in the original table; you should ask only for the SUM value.)
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);
I want to show "Contact name" and "contact number" in a list. But my code repeats "contact name" depends on how many number or other attributes (i.e. email id ) associated with that particular Name. For example .
In Contact directory contact list as..
Pankaj Kumar and numbers 000000-000 and 00000-2222. I want output as only Pankaj Kumar and primary_number, but output comes with ( Pankaj kumar and number 000000-000) and its repeat with ( Pankaj kumar and number 00000-2222).
How can I solve it..
My code is as below ..
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// We'll define a custom screen layout here (the one shown above), but
// typically, you could just use the standard ListActivity layout.
setContentView(R.layout.contacts_list_item);
Cursor mCursor = getContentResolver().query(Data.CONTENT_URI,
null, // projection
null, // selection
null, // selectionArgs
Data.DISPLAY_NAME); // sortOrder
startManagingCursor(mCursor);
// Now create a new list adapter bound to the cursor.
// SimpleListAdapter is designed for binding to a Cursor.
contactAdapter = new SimpleCursorAdapter(
this, // Context.
android.R.layout.two_line_list_item, // Specify the row template to use (here, two columns bound to the two retrieved cursor rows).
mCursor, // Pass in the cursor to bind to.
new String[] {Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}, // Array of cursor columns to bind to.
new int[] {android.R.id.text1, android.R.id.text2}); // Parallel array of which template objects to bind to those columns.
// Bind to our new adapter.
setListAdapter(contactAdapter);
}
If you put your query as follow
Cursor cursor = getContentResolver().
query( Contacts.CONTENT_URI,
new String[]{Contacts.DISPLAY_NAME}, null, null,null);
if(cursor!=null){
while(cursor.moveToNext()){
Cursor c = getContentResolver().query(Phone.CONTENT_URI, new String[]{Phone.NUMBER, Phone.TYPE},
" DISPLAY_NAME = '"+cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME))+"'", null, null);
while(c.moveToNext()){
switch(c.getInt(c.getColumnIndex(Phone.TYPE))){
case Phone.TYPE_MOBILE :break;
case Phone.TYPE_HOME :break;
case Phone.TYPE_WORK : String workNo = c.getString(c.getColumnIndex(Phone.NUMBER));break;
case Phone.TYPE_OTHER :break;
}
}
}
}
your contact name will not repeat for same number and select whichever number you want to
put as primary form mobile, work, other or home.