how I can get ID of selected item in Spinner from Database?
I know it's onItemSelected method, but I don't how to use it.
AddActivity:
spSpinner.setOnItemSelectedListener(
new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
id = Integer.parseInt(String.valueOf(((SpinnerObject)spSpinner.getSelectedItem()).getDatabaseId()));
Toast.makeText(getBaseContext(), "You have selected department with ID: " + id, Toast.LENGTH_LONG).show();
Log.d(TAG, "onItemSelected database id: " + id);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
);
DatabaseHandler:
public ArrayList<SpinnerObject> getAllDepartments(){
ArrayList<SpinnerObject> list = new ArrayList<>();
String selectQuery = "SELECT * FROM " + TABLE_DEPARTMENTS;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if(cursor.moveToFirst()){
do {
list.add(new SpinnerObject (cursor.getInt(0), cursor.getString(1)));
}while(cursor.moveToNext());
}
cursor.close();
db.close();
return list;
}
in this method I insert values to database. How can I insert id, which I'm getting in Spinner to database?
private void insertInStudentTable(String imie, String nazwisko, int indeks, String email, String telefon) {
SQLiteDatabase db = dbCreate.getWritableDatabase();
//ContentValues data_2 = new ContentValues();
//long idOfDepart = db.insertOrThrow("departments", null, data_2);
ContentValues data = new ContentValues();
data.put("imie", imie);
data.put("nazwisko", nazwisko);
data.put("indeks", indeks);
data.put("email", email);
data.put("numer", telefon);
data.put("dept_id", 1 ); // - here must be inserted an id of department
db.insertOrThrow("students", null, data);
}
Related
How can I save a query result in a String array?
The query is simple, it's got only one column i.e.:
SELECT NAME FROM MYTABLE
What I want is to store the ids in a String array so I can show them as clickable items in a ListView
Try this
String selectQuery = "SELECT * FROM table";
try {
Cursor cursor = db.rawQuery(selectQuery, null);
ArrayList<String> ids = new ArrayList<>();
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
String id = cursor.getString(cursor.getColumnIndex(KEY_ID));
ids.add(id);
} while (cursor.moveToNext());
}
cursor.close();
} catch (Exception e) {
e.printStackTrace();
}
Assuming you've already executed your query against a SQLiteDatabase object, and received a Cursor in return, you can iterate through the cursor and save the value of each row to a String[] array like so:
String[] names;
if (cursor.moveToFirst()) {
names = new String[cursor.getCount()];
int colIndex = cursor.getColumnIndex("NAME");
do {
names[cursor.getPosition()] = cursor.getString(colIndex);
} while (cursor.moveToNext());
}
Keep in mind that names will be null if no rows are returned, so make sure you do a null check.
create following method in SQLiteOpenHelper class
public List<String> getAllNames() {
List<String> retData = new ArrayList<String>();
String selectQuery = "SELECT NAME FROM MYTABLE";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
retData.add(cursor.getString(0));
} while (cursor.moveToNext());
}
return retData;
}
then assign this returned list to adapter
The issue with listing id's is that they tend to be meaningless to an end user. Really you want to display user meaningful data, e.g. a name, but to then be able to access the respective id to then efficiently act on a selection from the list presented to a user.
Using an ArrayList is frequently the cause of much frustration, as the list shows what is required but it's then found to be of little use when attempting to use the list beyond displaying data e.g. selecting an item to then do something such as delete or update (if the value is unique within the database it can be used).
As such an ArrayList<your_object> rather then an ArrayList<String> is generally more viable as the source of the List; a Cursor Adapter can also be used as data from the underlying row is easily obtained.
However, there is an issue, unless a Custom Array Adapter is utilised, when using an ArrayList in that the ArrayAdapter class uses the toString method of the object to retrieve the data that is displayed. The simple fix is to provide a suitable toString method in the object, if you don't you will get something long the lines of “SomeType#2f92e0f4”.
Example showing all 3
In the following working example :-
the database (mydb) has 1 table named mytable which has two columns _id (Note must be _id for a CursorAdapter)
There are 3 methods to get the 3 types of list (named accordingly) :-
getAllAsStringArrayList (gets ArrayList)
getAllAsMyTableObjectArrayList (gets ArrayList). Note uses the MyTableObject class (see note in class re overriding the default toString method)
getAllAsCursor
The App, when run, will have 3 lists, the left based upon the first ArrayList, the middle based upon the ArrayList and the last based upon the Cursor.
Clicking an item in any of the lists displays the respective name along with attempts to get the id.
The ArrayList, Left List, fails in this aspect as it can only get the position (i.e. the 4th parameter passed to the listener is the same value as the position).
The ArrayList, middle List, when getting the id from the object (which is retrieved via the getItem(position) method of the Adapter) successfully retrieves the correct id, the 4th parameter is the same as the position, and should not be used.
The Cursor, Right List, retrieves the correct id both via the Cursor and the 4th parameter.
The Code
MyTableObject.java :-
public class MyTableObject {
private long id;
private String name;
public MyTableObject(long id, String name) {
this.id = id;
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/*
NOTE toString method returns just the name
*/
#Override
public String toString() {
return name;
}
}
DatabaseHelper.java :-
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "mydb";
public static final int DBVERSION = 1;
public static final String TB_MYTABLE = "mytable";
public static final String COl_MYTABLE_ID = BaseColumns._ID; //<<<< use standard android id column name
public static final String COL_MYTABLE_NAME = "_name";
private static final String mytable_crtsql =
"CREATE TABLE IF NOT EXISTS " + TB_MYTABLE +
"(" +
COl_MYTABLE_ID + " INTEGER PRIMARY KEY, " +
COL_MYTABLE_NAME + " TEXT " +
")";
SQLiteDatabase mDB;
public DatabaseHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(mytable_crtsql);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public long addRow(String name) {
ContentValues cv = new ContentValues();
cv.put(COL_MYTABLE_NAME,name);
return mDB.insert(TB_MYTABLE,null,cv);
}
public ArrayList<String> getAllAsStringArrayList() {
ArrayList<String> rv = new ArrayList<>();
Cursor csr = mDB.query(
TB_MYTABLE,
null,
null,
null,
null,
null,
null
);
while (csr.moveToNext()) {
rv.add(csr.getString(csr.getColumnIndex(COL_MYTABLE_NAME)));
}
csr.close();
return rv;
}
public ArrayList<MyTableObject> getAllAsMyTableObjectArrayList() {
ArrayList<MyTableObject> rv = new ArrayList<>();
Cursor csr = mDB.query(
TB_MYTABLE,
null,
null,
null,
null,
null,
null
);
while (csr.moveToNext()) {
rv.add(new MyTableObject(
csr.getLong(csr.getColumnIndex(COl_MYTABLE_ID)),
csr.getString(csr.getColumnIndex(COL_MYTABLE_NAME))
)
);
}
csr.close();
return rv;
}
public Cursor getAllAsCursor() {
return mDB.query(
TB_MYTABLE,
null,
null,
null,
null,
null,
null
);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
DatabaseHelper mDBHlpr;
ListView mListView01,mListVeiw02,mListView03;
ArrayAdapter<String> mAdapterStringArrayList;
ArrayAdapter<MyTableObject> mAdapterMyTableObjectArrayList;
SimpleCursorAdapter mAdapterCursor;
ArrayList<String> mMyTableListAsStrings;
ArrayList<MyTableObject> mMyTableAsObjects;
Cursor mMyTableListAsCursor;
Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
mListView01 = this.findViewById(R.id.listview01);
mListVeiw02 = this.findViewById(R.id.listview02);
mListView03 = this.findViewById(R.id.listview03);
mDBHlpr = new DatabaseHelper(this);
mDBHlpr.addRow("Fred");
mDBHlpr.addRow("Bert");
mDBHlpr.addRow("Harry");
mDBHlpr.addRow("Fred");
//String Array List
mMyTableListAsStrings = mDBHlpr.getAllAsStringArrayList();
mAdapterStringArrayList = new ArrayAdapter<>(
this,
android.R.layout.simple_list_item_1,
mMyTableListAsStrings
);
mListView01.setAdapter(mAdapterStringArrayList);
//Object Array List
mMyTableAsObjects = mDBHlpr.getAllAsMyTableObjectArrayList();
mAdapterMyTableObjectArrayList = new ArrayAdapter<>(
this,
android.R.layout.simple_list_item_1,
mMyTableAsObjects
);
mListVeiw02.setAdapter(mAdapterMyTableObjectArrayList);
// Cursor
mMyTableListAsCursor = mDBHlpr.getAllAsCursor();
mAdapterCursor = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
mMyTableListAsCursor,
new String[]{DatabaseHelper.COL_MYTABLE_NAME},
new int[]{android.R.id.text1},
0
);
mListView03.setAdapter(mAdapterCursor);
mListView01.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String name = mAdapterStringArrayList.getItem(position);
Toast.makeText(
mContext,
"Name is " + name +
". ID is " + String.valueOf(id) +
" (note may not match)",
Toast.LENGTH_SHORT
).show();
}
});
mListVeiw02.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
MyTableObject mytable = mAdapterMyTableObjectArrayList.getItem(position);
String name = mytable.getName();
long id_in_object = mytable.getId();
Toast.makeText(
mContext,
"Name is " + name +
". ID from object is " + String.valueOf(id_in_object) +
". ID from adapter is " + String.valueOf(id),
Toast.LENGTH_SHORT
).show();
}
});
mListView03.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Cursor csr = mAdapterCursor.getCursor(); // already positioned
String name = csr.getString(csr.getColumnIndex(DatabaseHelper.COL_MYTABLE_NAME));
long id_in_cursor = csr.getLong(csr.getColumnIndex(DatabaseHelper.COl_MYTABLE_ID));
Toast.makeText(
mContext,
"Name is " + name +
". ID from object is " + String.valueOf(id_in_cursor) +
". ID from adapter is " + String.valueOf(id),
Toast.LENGTH_SHORT
).show();
}
});
}
}
This question has been asked before but none of the implementations helped me so far.
I'm building a to do app and I'm displaying my items in a listview, using SQLite for persistence. I'm able to dynamically add items to my listview and successfully store them in my database, but I'm not able to delete them from the screen or the table. I know the reason why. My SQLite Row ID does not match my ListView. But the other problem is that I should still be able to delete items off my screen and my table with positions that does match the SQLite Row ID (For example, my 3rd To Do in the list) but I'm not able to delete anything.
This is my method that is supposed to delete items from the database:
public boolean itemDeleteFromDatabase(long id) {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
boolean databaseDelete = database.delete(TABLE_NAME, TO_DO + "=?" + id, null) > 0;
listItems.setAdapter(adapter);
return databaseDelete;
}
And I'm calling this method from my OnItemLongClick method, passing in the ListView position as the parameter:
listItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapter, View item, int position, long id) {
toDoItems.remove(position);
itemDeleteFromDatabase(id);
MainActivity.this.adapter.notifyDataSetChanged();
return true;
}
});
This is the stacktrace. The problem with this is that it only addresses 1 problem in the code:
FATAL EXCEPTION: main
Process: ca.ozbek.preworktodoapp, PID: 2105
android.database.sqlite.SQLiteException: variable number must be between ?1 and ?999 (code 1): , while compiling: DELETE FROM student WHERE todo=?0
Adding Source Code per request
MainActivity.java
public class MainActivity extends AppCompatActivity {
DatabaseHelper databaseHelper;
private final int REQUEST_CODE = 10;
ArrayList <String> toDoItems = new ArrayList<>();
ArrayAdapter<String> adapter;
ListView listItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listItems = (ListView) findViewById(R.id.listViewItems);
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, toDoItems);
listItems.setAdapter(adapter);
databaseHelper = new DatabaseHelper(this);
getToDos();
listItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapter, View item, int position, long id) {
toDoItems.remove(position);
itemDeleteFromDatabase(id + 1);
MainActivity.this.adapter.notifyDataSetChanged();
return true;
}
});
listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View item, int pos, long id) {
Intent intent = new Intent(MainActivity.this, EditItemActivity.class);
intent.putExtra("item", toDoItems.get(pos));
intent.putExtra("itemPos", String.valueOf(pos));
startActivityForResult(intent, REQUEST_CODE);
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
String item = data.getStringExtra("item");
int itemPosition = Integer.parseInt(data.getStringExtra("itemPos"));
toDoItems.add(itemPosition, item);
toDoItems.remove(itemPosition + 1);
adapter.notifyDataSetChanged();
}
}
public void addItem(View v) {
EditText newItem = (EditText) findViewById(R.id.itemInputEditText);
if (newItem.getText().length() == 0) {
Toast.makeText(this, "You need to enter a to do.", Toast.LENGTH_SHORT).show();
} else {
String item = newItem.getText().toString();
databaseHelper.insertData(item);
adapter.add(item);
newItem.setText("");
}
}
public void getToDos(){
SQLiteDatabase database = databaseHelper.getWritableDatabase();
Cursor cursor = database.rawQuery("select * from student",null);
if (cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
String name = cursor.getString(cursor.getColumnIndex("todo"));
adapter.add(name);
adapter.notifyDataSetChanged();
cursor.moveToNext();
}
}
}
public boolean itemDeleteFromDatabase(Long id) {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
boolean databaseDelete = database.delete(TABLE_NAME, TO_DO + "=?", new String[]{Long.toString(id)}) > 0;
listItems.setAdapter(adapter);
return databaseDelete;
}
}
DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "todo.db";
public static final String TABLE_NAME = "student";
public static final String ID = "id";
public static final String TO_DO = "todo";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
String CREATE_TO_DO_TABLE = "CREATE TABLE "
+ TABLE_NAME
+ "("
+ ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ TO_DO
+ " TEXT"
+ ")";
sqLiteDatabase.execSQL(CREATE_TO_DO_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(sqLiteDatabase);
}
public boolean insertData(String todo) {
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(TO_DO, todo);
long result = sqLiteDatabase.insert(TABLE_NAME, null, contentValues);
if (result == -1) {
return false;
} else {
return true;
}
}
public Cursor getListContents() {
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
Cursor data = sqLiteDatabase.rawQuery("SELECT * FROM " + TABLE_NAME, null);
return data;
}
}
SQL is basically saying that you haven't provided an argument to match the placement ?. i.e.
boolean databaseDelete = database.delete(TABLE_NAME, TO_DO + "=?" + id, null) > 0;
Is effectively saying DELETE FROM table WHERE TO_DO =unobtainablevale 10
10 being a made-up id for demonstration
You could change it to
boolean databaseDelete = database.delete(TABLE_NAME, TO_DO + "=" + id, null) > 0;
or to
boolean databaseDelete = database.delete(TABLE_NAME, TO_DO + "=?", new String[]{Long.toString(id)}) > 0;
The latter probably being considered the better.
P.S. not tested so the odd typo might exist.
Solution 1 using a SimpleCursorAdapter as opposed to an ArrayAdpater
1) in DatabaseHelper change public static final String ID = "id"; to be public static final String ID = "_id"; (i.e add the underscore, suggest do this irrespective of method used but NEEDED for CursorAdapter)
Note! This will require the existing database to be deleted. Use Settings/Apps, select App and then clear data or uninstall app.
2) add the lines indicated with <<<<< to MainActivity (preparing to use Cursor Adapter, ps will leave the ArrayAdapter stuff generally asis but have to remove some)
ArrayList<String> toDoItems = new ArrayList<>();
ArrayAdapter<String> adapter;
SimpleCursorAdapter altadapter; //<<<<<<<<<
Cursor itemlistcursor; //<<<<<<<<<
ListView listItems;
3) Add override for onDestroy method (not required but cleans up cursor) :-
#Override
public void onDestroy() {
super.onDestroy();
itemlistcursor.close();
}
4) Add altertantive method e.g. getItemListAsCursor to get data:-
public void getItemListAsCursor() {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
itemlistcursor = database.query(TABLE_NAME,null,null,null,null,null,null);
}
Note! uses query method instead of rawQuery but equates to SELECT * FROM student;
5) Change itemDeleteFromDatabase to use ID column not the TODO column (didn't spot this before) and comment out lines as per the code below:-
public boolean itemDeleteFromDatabase(Long id) {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
boolean databaseDelete = database.delete(TABLE_NAME, ID + "=?", new String[]{Long.toString(id)}) > 0;
//listItems.setAdapter(adapter);
return databaseDelete;
}
6) Comment out the lines as below (get rid of using ArrayAdapater) :-
listItems = (ListView) findViewById(R.id.listViewItems);
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, toDoItems);
//listItems.setAdapter(adapter);
databaseHelper = new DatabaseHelper(this);
//getToDos();
7) Change onItemLongClickListener as below
listItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapter, View item, int position, long id) {
//toDoItems.remove(position);
itemDeleteFromDatabase(id); //<<<<<<
getItemListAsCursor(); //<<<<<<
//MainActivity.this.adapter.notifyDataSetChanged();
altadapter.swapCursor(itemlistcursor); //<<<<<<
return true;
}
});
Note! could keep notifyDatasetChanged (I just prefer swapCursor);
8) Finally add the following just after the commented out //getToDos line :-
getItemListAsCursor();
altadapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
itemlistcursor,
new String[]{ TO_DO},
new int[]{android.R.id.text1},
0);
listItems.setAdapter(altadapter);
Solution 2 using ArrayAdpater
1) Add the complimentary Array for the ID (as per the //<<<<<< line):-
ArrayList <String> toDoItems = new ArrayList<>();
ArrayList<Long> toDoItemsID = new ArrayList<>(); //<<<<<<
ArrayAdapter<String> adapter;
ListView listItems;
2) Change insertData method in DatabaseHelper to return the id by replacing the method with :-
public long insertData(String todo) {
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(TO_DO, todo);
return sqLiteDatabase.insert(TABLE_NAME, null, contentValues);
}
3) Change getToDos method to store id into the compliementary array (//<<<<< ):-
public void getToDos(){
SQLiteDatabase database = databaseHelper.getWritableDatabase();
Cursor cursor = database.rawQuery("select * from student",null);
if (cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
String name = cursor.getString(cursor.getColumnIndex(TO_DO));
adapter.add(name);
toDoItemsID.add(cursor.getLong(cursor.getColumnIndex(ID))); //<<<<<<
adapter.notifyDataSetChanged();
cursor.moveToNext();
}
}
}
Note! I have also replaced "todo" with TO_DO
4) Change addItem method to also store id
public void addItem(View v) {
EditText newItem = (EditText) findViewById(R.id.itemInputEditText);
if (newItem.getText().length() == 0) {
Toast.makeText(this, "You need to enter a to do.", Toast.LENGTH_SHORT).show();
} else {
String item = newItem.getText().toString();
//databaseHelper.insertData(item); //OLD
toDoItemsID.add(databaseHelper.insertData(item)); //<<<<<<<
adapter.add(item);
newItem.setText("");
}
}
Note! I don't like this at all I can envisage issue with keeping toDoItemsID in sync, plus this does currently cater for a not inserted (easy to do as return from insertData should be > 0).
5) Finally the onItemLongClickListener changes :-
listItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapter, View item, int position, long id) {
itemDeleteFromDatabase(toDoItemsID.get(position)); //<<<<<<
toDoItems.remove(position);
toDoItemsID.remove(position); //<<<<<<
//itemDeleteFromDatabase(id + 1); // REMOVE
MainActivity.this.adapter.notifyDataSetChanged();
return true;
}
});
I've tested the above, but may have inadvertently missed something when copying.
I am populating two spinner from sqlite. Now what I want that when my Activity is created then all state populate in spnState. But when I select any state from spinner then I want to bind District from sqlite in spnDistrict. I am getting problem when I select state after that list of district not showing in district spinner it is only showing "select district". How can I achieve that.
public void SpinnerValue(){
/*-----------------------Fill State start here----------------------------*/
try {
ArrayList<String> state_array = new ArrayList<String>();
state_array.add("Select State");
Cursor cursor_State = db.rawQuery("SELECT nSerialNo as _id,cCodeName FROM CodeMaster where nCtgId = 6", null);
if (cursor_State.moveToFirst()) {
do {
//assing values
String stateID = cursor_State.getString(0);
String stateName = cursor_State.getString(1);
stateData = stateName;
state_array.add(stateData);
} while (cursor_State.moveToNext());
}
ArrayAdapter my_Adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, state_array);
spnState.setAdapter(my_Adapter);
cursor_State.close();
spnState.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
state = spnState.getSelectedItem().toString();
Cursor cursor = db.rawQuery("SELECT nSerialNo FROM CodeMaster where cCodeName = '" + state + "'", null);
if (cursor.moveToFirst()) {
do {
//assing values
stateCodeId = cursor.getString(0);
} while (cursor.moveToNext());
}
cursor.close();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
/*-----------------------Fill District start here----------------------------*/
try {
ArrayList<String> district_array = new ArrayList<String>();
district_array.add("Select District");
Cursor cursor_District = db.rawQuery("SELECT nSerialNo as _id,cCodeName FROM CodeMaster where nParentSerialNo = '"+stateCodeId+"'", null);
if (cursor_District.moveToFirst()) {
do {
//assing values
String districtID = cursor_District.getString(0);
String districtName = cursor_District.getString(1);
districtData = districtName;
district_array.add(districtData);
} while (cursor_District.moveToNext());
}
ArrayAdapter district_Adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, district_array);
spnDistrict.setAdapter(district_Adapter);
cursor_District.close();
spnDistrict.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
district = spnDistrict.getSelectedItem().toString();
Cursor cursor = db.rawQuery("SELECT nSerialNo FROM CodeMaster where cCodeName = '" + district + "'", null);
if (cursor.moveToFirst()) {
do {
//assing values
districtCodeId = cursor.getString(0);
} while (cursor.moveToNext());
}
cursor.close();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
I have checked your code and you are setting all values in one simple method, therefore it will not take stateId to fetch districts, So just apply below two method and call first in onCreate method to resolve your issue,
Call Below method in onCreate() method
// In onCreate() method call below method
fillStateData();
public void fillStateData()
{
try {
ArrayList<String> state_array = new ArrayList<String>();
state_array.add("Select State");
Cursor cursor_State = db.rawQuery("SELECT nSerialNo as _id,cCodeName FROM CodeMaster where nCtgId = 6", null);
if (cursor_State.moveToFirst())
{
do {
//assing values
String stateID = cursor_State.getString(0);
String stateName = cursor_State.getString(1);
stateData = stateName;
state_array.add(stateData);
} while (cursor_State.moveToNext());
}
ArrayAdapter my_Adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, state_array);
spnState.setAdapter(my_Adapter);
cursor_State.close();
spnState.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
state = spnState.getSelectedItem().toString();
Cursor cursor = db.rawQuery("SELECT nSerialNo FROM CodeMaster where cCodeName = '" + state + "'", null);
if (cursor.moveToFirst()) {
stateCodeId = cursor.getString(0);
}
cursor.close();
fillDistrictData(stateCodeId);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public void fillDistrictData(String stateCodeId)
{
try {
ArrayList<String> district_array = new ArrayList<String>();
district_array.add("Select District");
Cursor cursor_District = db.rawQuery("SELECT nSerialNo as _id,cCodeName FROM CodeMaster where nParentSerialNo = '"+stateCodeId+"'", null);
if (cursor_District.moveToFirst()) {
do {
//assing values
String districtID = cursor_District.getString(0);
String districtName = cursor_District.getString(1);
districtData = districtName;
district_array.add(districtData);
} while (cursor_District.moveToNext());
}
ArrayAdapter district_Adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, district_array);
spnDistrict.setAdapter(district_Adapter);
cursor_District.close();
spnDistrict.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
district = spnDistrict.getSelectedItem().toString();
Cursor cursor = db.rawQuery("SELECT nSerialNo FROM CodeMaster where cCodeName = '" + district + "'", null);
if (cursor.moveToFirst()) {
do {
//assing values
districtCodeId = cursor.getString(0);
} while (cursor.moveToNext());
}
cursor.close();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
How to create cursor object to get item id from database?
Here is my method of DBHelper, see the Cursor method
public int getItemIdByPosition(int position) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from " + TABLE_NAME, null);
cursor.moveToPosition(position);
return Integer.parseInt(cursor.getString(0));
}
Seems to be correct.
Maybe the position passed through method is not correct, maybe is more efficient is you use, instead of pass a position on your method pass the ID:
"select * from " + TABLE_NAME + " where id = " = id
Also you can use:
cursor.getColumnIndex(COLUMN_NAME) instead of cursor.getString(0)
Your code seems to be right, I just would check the below things that I mentioned.
String selectQuery = "SELECT * FROM " + TABLE_NAME + " WHERE " + POSITION + " = " + position;
db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
int userId;
if (cursor.moveToFirst())
{
userId = cursor.getInt(0);
}
cursor.close();
return userId;
This is a sample code hope you can get a help from this
private void displayListView(String getter){
//get the customer data from the db and feed them to cursor and load the data to lest
Cursor cursor = dbHelper.fetchallcustomercompany(getter);
String[] columns = new String[] {
//get the needed columns of the db and feed them in to string array
DBCreater.Key_customer_Shop
};
int[] to = new int[]{
//get the textboxs in xml layout,which going to display the values in to integer array
R.id.tv_demo_search_text_Isuru
};
//address the xml list view to java
final ListView listView = (ListView)findViewById(R.id.lv_searchcustomer_cuzlist_Isuru);
// feed the context,displaying layout,data of db, data source of the data and distination of the data
if(cursor.getCount()==0){
Toast.makeText(getApplicationContext(), " No matching data", Toast.LENGTH_SHORT).show();
}
else{
dataAdapter = new SimpleCursorAdapter(this, R.layout.demo_search, cursor, columns, to,0);
//load the data to list view
listView.setAdapter(dataAdapter);
//what happen on when user click on the item of the list view
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Cursor cursor =(Cursor)listView.getItemAtPosition(arg2);
//get the value of the customer name from the clicked listitem
String name=cursor.getString(cursor.getColumnIndexOrThrow("customer_shop"));
}
});
}
}
Try this:
public int getItemIdByPosition(int position) {
int itemID = 0;
Cursor localCursor = database.rawQuery("select * from " + TABLE_NAME,
null);
int i = localCursor.getColumnIndex("ID");
if (localCursor.moveToFirst()) {
do {
itemID = Integer.parseInt(localCursor.getString(i));
} while (localCursor.moveToPosition(position));
}
localCursor.close();
return itemID;
}
this is what i have done, to retrieve the id but it says that getIndexColumn is not defined in the cursor... what i'm doing wrong?
protected void onListItemClick(ListView l, View v, int position, long id) {
Cursor data = (Cursor)l.getItemAtPosition(position);
String cat = Cursor.getString(Cursor.getIndexColumn(MySQLiteHelper.COLUMN_ID));
Intent myIntent = new Intent(MainActivity.this, sondaggioActivity.class);
myIntent.putExtra("categoriaId", cat);
MainActivity.this.startActivity(myIntent);
}
this is the category class:
public class categorie {
private long id;
private String nome;
private long preferita;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public long getPreferita() {
return preferita;
}
public void setPreferita(long preferita) {
this.preferita = preferita;
}
// Will be used by the ArrayAdapter in the ListView
#Override
public String toString() {
return nome;
}
}
and this is the datasource:
public class pollDataSource {
// Database fields
private SQLiteDatabase database;
private MySQLiteHelper dbHelper;
private String[] allCategorieColumns = { MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_PREF, MySQLiteHelper.COLUMN_NOME };
private String[] allSondaggiColumns = { MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_CATID, MySQLiteHelper.COLUMN_DOMANDA };
private String[] allRisposteColumns = { MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_SONDID, MySQLiteHelper.COLUMN_RISPOSTA,
MySQLiteHelper.COLUMN_SELEZIONATA };
public pollDataSource(Context context) {
dbHelper = new MySQLiteHelper(context);
}
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
public void close() {
dbHelper.close();
}
public categorie createCategoria(String categoria) {
ContentValues values = new ContentValues();
values.put(MySQLiteHelper.COLUMN_NOME, categoria);
values.put(MySQLiteHelper.COLUMN_PREF, 0);
long insertId = database.insert(MySQLiteHelper.TABLE_CATEGORIE, null,
values);
Cursor cursor = database.query(MySQLiteHelper.TABLE_CATEGORIE,
allCategorieColumns, MySQLiteHelper.COLUMN_ID + " = " + insertId, null,
null, null, null);
cursor.moveToFirst();
categorie newCategoria = cursorToCategorie(cursor);
cursor.close();
return newCategoria;
}
public void deleteCategoria(categorie categoria) {
long id = categoria.getId();
System.out.println("Categoria cancellata, id: " + id);
database.delete(MySQLiteHelper.TABLE_CATEGORIE, MySQLiteHelper.COLUMN_ID
+ " = " + id, null);
}
public sondaggi createSondaggio(String domanda, int catid) {
ContentValues values = new ContentValues();
values.put(MySQLiteHelper.COLUMN_DOMANDA, domanda);
values.put(MySQLiteHelper.COLUMN_CATID, catid);
long insertId = database.insert(MySQLiteHelper.TABLE_SONDAGGI, null,
values);
Cursor cursor = database.query(MySQLiteHelper.TABLE_SONDAGGI,
allSondaggiColumns, MySQLiteHelper.COLUMN_ID + " = " + insertId, null,
null, null, null);
cursor.moveToFirst();
sondaggi newSondaggio = cursorToSondaggi(cursor);
cursor.close();
return newSondaggio;
}
public void deleteSondaggio(sondaggi sondaggio) {
long id = sondaggio.getId();
System.out.println("Sondaggio cancellato, id: " + id);
database.delete(MySQLiteHelper.TABLE_SONDAGGI, MySQLiteHelper.COLUMN_ID
+ " = " + id, null);
}
public Cursor getAllCategorie() {
List<categorie> categorie = new ArrayList<categorie>();
Cursor cursor = database.query(MySQLiteHelper.TABLE_CATEGORIE,
allCategorieColumns, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
categorie categoria = cursorToCategorie(cursor);
categorie.add(categoria);
cursor.moveToNext();
}
// Make sure to close the cursor
// cursor.close();
return cursor;
}
private categorie cursorToCategorie(Cursor cursor) {
categorie categorie = new categorie();
categorie.setId(cursor.getLong(0));
categorie.setPreferita(cursor.getLong(1));
categorie.setNome(cursor.getString(2));
return categorie;
}
private sondaggi cursorToSondaggi(Cursor cursor) {
sondaggi sondaggi = new sondaggi();
sondaggi.setId(cursor.getLong(0));
sondaggi.setDomanda(cursor.getString(1));
sondaggi.setCatid(cursor.getLong(2));
return sondaggi;
}
}
the main activity:
public class MainActivity extends ListActivity {
private pollDataSource datasource;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
datasource = new pollDataSource(this);
datasource.open();
Cursor values = datasource.getAllCategorie();
String[] categorieColumns =
{
MySQLiteHelper.COLUMN_NOME // Contract class constant containing the word column name
};
int[] mWordListItems = { R.id.categoria_label };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
getApplicationContext(), // The application's Context object
R.layout.single_list_item, // A layout in XML for one row in the ListView
values, // The result from the query
categorieColumns, // A string array of column names in the cursor
mWordListItems, // An integer array of view IDs in the row layout
0); // Flags (usually none are needed)
setListAdapter(adapter);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.add:
datasource.createCategoria("peppe");
break;
}
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent myIntent = new Intent(MainActivity.this, sondaggioActivity.class);
myIntent.putExtra("categoriaId", id);
MainActivity.this.startActivity(myIntent);
//Toast.makeText(this, selection, Toast.LENGTH_LONG).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
I assume you have an activity with a list of categories, and onClick of a particular item you want to launch new activity with details of that Item.
I suggest you when you launch the listScreen, query all/some items and maintaine an arrayList of items and save that in some singleton class, then onClick of a particular item pass that index to detail screen via intent.putExtra("index", position) and on detail Screen get that index via getIntent().getIntExtra("index", -1) .now get details of that particular index from arraylist saved in singleton class.
This approach will reduce cost of querying every time from database and data will be available easily.
Change
Cursor data = (Cursor)l.getItemAtPosition(position);
String cat = Cursor.getString(Cursor.getIndexColumn(MySQLiteHelper.COLUMN_ID));
to
Cursor data = (Cursor)l.getItemAtPosition(position);
Long clid = data.getLong(data.getIndexColumn(MySQLiteHelper.COLUMN_ID));
String cat=Long.toString(clid);
those two lines:
Cursor data = (Cursor)l.getItemAtPosition(position);
String cat = Cursor.getString(Cursor.getIndexColumn(MySQLiteHelper.COLUMN_ID));
makes absolutely no sense at all! If you're using a CursorAdapter why are you creating an array of objects? If you're using a ArrayAdapter why are you getting data from cursor?
Also, Cursor don't have any static methods to be called like that. That shouldn't even compile.
If you're using a CursorAdater (or some class that extend it) you the id is passed to you long id here protected void onListItemClick(ListView l, View v, int position, long id)