This question already has answers here:
When does SQLiteOpenHelper onCreate() / onUpgrade() run?
(15 answers)
Closed 6 years ago.
So i'm having a little trouble with SQLite in Android. I followed a guide with which i created a table and wrote a working method to insert data. After i had a lot of data in it i wanted to delete it again so i wrote a method which dropped my table.
Now i have the problem that it won't create the table anymore. If i want to insert data it says "no such table".I don't really get why it won't create it anymore. Relevant code:
public class MeFragment extends Fragment implements View.OnClickListener {
private SQLiteDatabase newDB;
private DatabaseHelper dbHelper;
private String TABLE_NAME = DatabaseHelper.TABLE_NAME;
ArrayList<String> myCategoryList = new ArrayList<String>() {
};
ListView lv1;
ArrayAdapter<String> adapter1;
EditText editText;
Button addButton;
public MeFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_me, container, false);
dbHelper = new DatabaseHelper(this.getActivity());
preFillCategories();
getCategories();
editText = (EditText) view.findViewById(R.id.addCategory);
addButton = (Button) view.findViewById(R.id.addCategoryButton);
addButton.setOnClickListener(this);
lv1 = (ListView) view.findViewById(R.id.listView1);
adapter1 = new ArrayAdapter<String>(this.getActivity(), android.R.layout.simple_list_item_1, myCategoryList);
lv1.setAdapter(adapter1);
Utility.setDynamicHeight(lv1);
//dbHelper.removeAllData();
return view;
}
And my Database Helper Class:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "categories.db";
public static final String TABLE_NAME = "categories_table";
public static final String COL = "CATEGORYNAME";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
SQLiteDatabase db = this.getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME +" (CATEGORYNAME TEXT PRIMARY KEY)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d("Hallo", "hallo");
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
public boolean insertData(String CATEGORYNAME){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL, CATEGORYNAME);
long result = db.insert(TABLE_NAME, null, contentValues);
if(result == -1){
return false;
}
else{
return true;
}
}
public void removeAllData(){
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DROP TABLE "+TABLE_NAME);
}
Any help would be very much appreciated
Can you add the removeAllData method to the dbhelper so we can see what you were doing?
Also, you're not doing anything to manage the db version number. If you're constantly using the same version number even after making changes, that could be a potential source of you problem.
Also, you should avoid calling any lifecycle methods directly (such as onCreate in your onUpgrade method). If you have code you want to invoke from multiple lifecycle methods, break that out into its own method so you don't run the risk of possibly introducing lifecycle issues on top of your current problem.
Related
**Good day everyone ...
I badly need your help.
Can I ask on why my listview doesnt display and also my alert dialog?
here is my code
I've already inserted table values in the sqlite database and Im confused on why nothing displays on my listview and dialog.
the listview uses an adapter that i queried in the DBHelper
MainActivity
public class MainActivity extends AppCompatActivity {
private QuestionaireDB commandQuery;
private ListView showQuestion;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
commandQuery = new QuestionaireDB(this);
ShowTables();
ArrayList getQuestion = commandQuery.getAllQuestions();
ArrayAdapter arrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,getQuestion);
showQuestion = (ListView)findViewById(R.id.viewAll);
showQuestion.setAdapter(arrayAdapter);
}
private void ShowTables(){
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setMessage("You have "+commandQuery.numberOfRows()+"");
alertDialogBuilder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
finish();
}
});
}
}
QuestionaireDB
public class QuestionaireDB extends SQLiteOpenHelper{
//tblQuestion
public static final String DATABASE_NAME = "QuestionaireDB.db";
public static final String DATABASE_TABLE_tblQuestion = "tblQuestion";
public static final String DATABASE_TABLE_tblChoices = "tblChoices";
public static final String DATABASE_TABLE_tblAnswers = "tblAnswers";
public static final String DATABASE_TABLE_tblCategory = "tblCategory";
public QuestionaireDB(Context context) {
super(context, DATABASE_NAME , null, 3);
}
#Override
public void onCreate(SQLiteDatabase db) {
//tblQuestion
String CreatetblQueston="CREATE TABLE "+DATABASE_TABLE_tblQuestion +
"(questionID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,categoryID INTEGER,
questionName TEXT)";
//tblChoices
String CreatetblChoices="CREATE TABLE "+DATABASE_TABLE_tblChoices +
"(questionID INTEGER NOT NULL, ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
questionChoices TEXT)";
//tblAnswers
String CreatetblAnswers="CREATE TABLE "+DATABASE_TABLE_tblAnswers+
"(questionID INTEGER NOT NULL, questionCorrectAnswer TEXT, ID INTEGER PRIMARY KEY
AUTOINCREMENT NOT NULL)";
//tblCategory
String CreateCategory="CREATE TABLE "+DATABASE_TABLE_tblCategory+
" (categoryID INTEGER NOT NULL,categoryName TEXT, PRIMARY KEY (categoryID ASC))";
db.execSQL(CreatetblQueston);
db.execSQL(CreatetblChoices);
db.execSQL(CreatetblAnswers);
db.execSQL(CreateCategory);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String confirmationQuestion="DROP TABLE IF EXISTS "+DATABASE_TABLE_tblQuestion ;
String confirmationChoices="DROP TABLE IF EXISTS "+DATABASE_TABLE_tblChoices ;
String confirmationAnswers="DROP TABLE IF EXISTS "+DATABASE_TABLE_tblAnswers ;
String confirmationCategory="DROP TABLE IF EXISTS "+DATABASE_TABLE_tblCategory ;
db.execSQL(confirmationQuestion);
db.execSQL(confirmationChoices);
db.execSQL(confirmationAnswers);
db.execSQL(confirmationCategory);
}
public ArrayList<String> getAllQuestions() {
ArrayList<String> array_list = new ArrayList<String>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery( "select * from tblQuestion", null );
res.moveToFirst();
while(res.isAfterLast() == false){
array_list.add(res.getString(res.getColumnIndex("questionName")));
res.moveToNext();
}
return array_list;
}
public int numberOfRows(){
SQLiteDatabase db = this.getReadableDatabase();
int numRows = (int) DatabaseUtils.queryNumEntries(db, DATABASE_TABLE_tblQuestion);
return numRows;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="#+id/viewAll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
`
First of all you need to call show() method of dialog like written below,
alertDialogBuilder.show(); //add this line in your ShowTables()
Replace line
ArrayList getQuestion=commandQuery.getAllQuestions();
with
ArrayList<String> getQuestion=commandQuery.getAllQuestions();
And check whether you are getting atleast one data from your database(check list size)
I'm having trouble loading data from my ListView that I've populated with my CharacterSheetDBHelper. I've tried searching for several answers, one including using SimpleCursorAdapter, but I'm still having trouble. Can someone steer me into the right direction for this? I want to click on a list item and then fill out the form with the data stored on the database for editing.
My Code below:
The LoadCharacter class
public class LoadCharacter extends AppCompatActivity {
TextView testView;
ListView charListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.load_character);
CharacterDBHelper db = new CharacterDBHelper(getApplicationContext());
charListView = (ListView) findViewById(R.id.charListView);
//get list of names from the Database helper.
List<String> names = new ArrayList<>(db.getNames());
//attempting to create a listAdapter
ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, names);
charListView.setAdapter(adapter);
charListView.setTextFilterEnabled(true);
charListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent passIntent = new Intent(getApplicationContext(), CreateCharacter.class);
//Logically onItemClick would open up a game in progress rather than the character sheet screen.
//I was going to load character data into the Create Character class as an example.
//This is not working right now.
//Cursor c= (Cursor)charListView.getItemAtPosition(position);
//passIntent.putExtra("Characters", c.getColumn);
startActivity(passIntent);
}
});
}
public boolean onCreateOptionsMenu(Menu menu){
menu.add(0,0,0, "New Character");
return(super.onCreateOptionsMenu(menu));
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==0){
Intent intent = new Intent(this, CreateCharacter.class);
startActivity(intent);
}
return super.onOptionsItemSelected(item);
}
}
My CharacterDBHelper Class:
public class CharacterDBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "char.db";
private static final int DATABASE_VERSION = 1;
private SQLiteDatabase charDB = null;
public CharacterDBHelper(Context context) {
super(context, DB_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
//Create database
String CREATE_CHAR_TABLE = "CREATE TABLE IF NOT EXISTS Characters(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, " +
"brawling TEXT NOT NULL, highflying TEXT NOT NULL, technical TEXT NOT NULL, startinghealth TEXT NOT NULL," +
"remainingpoints TEXT NOT NULL)";
db.execSQL(CREATE_CHAR_TABLE);
}
public List<String> getNames(){
List<String> names = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
//Read from database and get ALL entries by name.
Cursor cursor = db.rawQuery("SELECT * FROM Characters", null);
if (cursor.moveToFirst()){
do {
//add extracted names to array.
names.add(cursor.getString(cursor.getColumnIndex("name")));
}while(cursor.moveToNext());
}
//close cursor and database.
cursor.close();
db.close();
return names;
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS Characters");
onCreate(db);
}
public void insertData(String name, String brawl, String flying, String tech, String health, String points){
SQLiteDatabase charDB = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", name);
values.put("brawling", brawl);
values.put("highflying", flying);
values.put("technical", tech);
values.put("startinghealth", health);
values.put("remainingpoints", points);
//row insert
charDB.insert("Characters", null, values);
charDB.close();
}
}
I believe that you look like you are having problems using intent extras. Here's and example of adding some from a cursor, from within onItemClickListener:-
intent.putExtra("Caller", THIS_ACTIVITY + "Update");
intent.putExtra("AisleID", aisleadapter.getCursor().getString(ShopperDBHelper.AISLES_COLUMN_ID_INDEX));
intent.putExtra("AISLEID", aisleadapter.getCursor().getLong(ShopperDBHelper.AISLES_COLUMN_ID_INDEX));
intent.putExtra("AisleName", aisleadapter.getCursor().getString(ShopperDBHelper.AISLES_COLUMN_NAME_INDEX));
intent.putExtra("AisleOrder", aisleadapter.getCursor().getString(ShopperDBHelper.AISLES_COLUMN_ORDER_INDEX));
intent.putExtra("AisleShopRef", aisleadapter.getCursor().getString(ShopperDBHelper.AISLES_COLUMN_SHOP_INDEX));
intent.putExtra("SHOPID", aisleadapter.getCursor().getLong(ShopperDBHelper.AISLES_COLUMN_SHOP_INDEX));
startActivity(intent);
Note!! ShopperDBHelper.AISLES_COLUMN_??????_INDEX equates to the offset within the cursor of the column.
Here's an example of retrieving from the intent within the started actvity:-
shopid = getIntent().getLongExtra("SHOPID", -1)
Note cursor should be set to the appropriate position. However, you could always use cursor.moveToPosition(position)
Here's an example CursorAdapter :-
package mjt.shopper;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.TextView;
/**
* Created by Mike092015 on 6/02/2016.
*/
class AislesCursorAdapter extends CursorAdapter {
public AislesCursorAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, 0);
}
#Override
public View getView(int position, View convertview, ViewGroup parent) {
View view = super.getView(position, convertview, parent);
Context context = view.getContext();
if (position % 2 == 0) {
view.setBackgroundColor(ContextCompat.getColor(context, R.color.colorlistviewroweven));
} else {
view.setBackgroundColor(ContextCompat.getColor(context, R.color.colorlistviewrowodd));
}
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView textviewaisleid = (TextView) view.findViewById(R.id.aisle_id_entry);
TextView textviewaislename = (TextView) view.findViewById(R.id.aisle_name_entry);
TextView textviewaisleorder = (TextView) view.findViewById(R.id.aisle_order_entry);
TextView textviewaisleshopref = (TextView) view.findViewById(R.id.aisle_shopref_entry);
textviewaisleid.setText(cursor.getString(ShopperDBHelper.AISLES_COLUMN_ID_INDEX));
textviewaislename.setText(cursor.getString(ShopperDBHelper.AISLES_COLUMN_NAME_INDEX));
textviewaisleorder.setText(cursor.getString(ShopperDBHelper.AISLES_COLUMN_ORDER_INDEX));
textviewaisleshopref.setText(cursor.getString(ShopperDBHelper.AISLES_COLUMN_SHOP_INDEX));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.activity_aisle_list_entry, parent, false);
}
}
Note. bindView (set the Listview's line/item/entry views with values) and newView (tell the adapter what layout to use) are required.
getView is optional (used here to alternate row background)
I have a listview that contains some data which I got from the web. Now I can make changes in the list item and once I make changes to the item, I am storing the updated value in the db. When i login in next time to the app, I am downloading the content from net and showing it in the listview with the changes that I have done last time. So my approach here is, I am querying the db for each item in the getview method of the list adapter to check for changes. Is it a good practice to do a db query for each item's getview method of the adapter? If not could you please suggest me some alternative. Thanks.
Never, really, never do that.
If you put your data download code in the getView method of the adapter it will make a network call for each row of the list.
Even worst, it will call it anytime that row appears on the screen, not only one time for row.
You should get all your data first, then use the adapter only to draw it.
You can at anytime call the db to check for changes and, if needed, notify the adapter to redraw the list to show the changes.
Hope this helps.
In Android development, any time you want to show a vertical list of items you will want to use a ListView which is populated using an Adapter to a data source. When we want the data for the list to be sourced directly from a SQLite database query we can use a CursorAdapter.
The CursorAdapter fits in between a Cursor (data source from SQLite query) and the ListView (visual representation) and configures two aspects:
Which layout template to inflate for an item
Which fields of the cursor to bind to views in the template
Creating the View Template
When we want to display a series of items into a list using a custom representation of the items, we need to use our own custom XML layout template for each item. We can simply create an XML layout template in res/layout/item_todo.xml representing a particular cursor row:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:id="#+id/tvBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Study cursors"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/tvPriority"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="3"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
Defining the Adapter
public class ViewAdapter extends BaseAdapter {
LayoutInflater mInflater;
public ViewAdapter() {
mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return favoriteList.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listitem,null);
}
final TextView nameText = (TextView) convertView.findViewById(R.id.nameText);
nameText.setText("Name : "+favoriteList.get(position).getName());
final TextView ageText = (TextView) convertView.findViewById(R.id.ageText);
ageText.setText("Age : "+favoriteList.get(position).getAge());
final Button edit = (Button) convertView.findViewById(R.id.edit);
edit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.row);
dialog.setTitle("Add Data to Database");
final EditText name = (EditText) dialog.findViewById(R.id.name);
final EditText age = (EditText) dialog.findViewById(R.id.age);
Button Add = (Button) dialog.findViewById(R.id.Add);
Add.setText("Add");
Add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(name.getText().toString() != null && name.getText().toString().length() >0 ){
if(age.getText().toString() != null && age.getText().toString().length() >0 ){
db.updateRow(favoriteList.get(position).getId(), name.getText().toString(), age.getText().toString());
favoriteList = db.getFavList();
listView.setAdapter(new ViewAdapter());
dialog.dismiss();
}else{
Toast.makeText(getApplicationContext(), "Please Enter the Age", Toast.LENGTH_LONG).show();
}
}else{
Toast.makeText(getApplicationContext(), "Please Enter the Name", Toast.LENGTH_LONG).show();
}
}
});
dialog.show();
}
});
final Button delete = (Button) convertView.findViewById(R.id.delete);
delete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
db.removeFav(favoriteList.get(position).getId());
notifyDataSetChanged();
favoriteList = db.getFavList();
listView.setAdapter(new ViewAdapter());
}
});
return convertView;
}
}
Create database
DatabaseHandler.java
public class DatabaseHandler extends SQLiteOpenHelper {
//Database Version
private static final int DATABASE_VERSION = 1;
//Database Name
private static final String DATABASE_NAME = "Test";
//Table Name
private static final String TABLE_TEST = "TestTable";
//Column Name
private static final String KEY_ID = "id";
private static final String KEY_NAME = "name";
private static final String KEY_AGE = "age";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
//Create Table
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_TEST + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
+ KEY_AGE + " TEXT" + ")";
db.execSQL(CREATE_CONTACTS_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_TEST);
onCreate(db);
}
//Insert Value
public void adddata(Context context,String movieId,String songId) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, movieId);
values.put(KEY_AGE, songId);
db.insert(TABLE_TEST, null, values);
db.close();
}
//Get Row Count
public int getCount() {
String countQuery = "SELECT * FROM " + TABLE_TEST;
int count = 0;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
if(cursor != null && !cursor.isClosed()){
count = cursor.getCount();
cursor.close();
}
return count;
}
//Delete Query
public void removeFav(int id) {
String countQuery = "DELETE FROM " + TABLE_TEST + " where " + KEY_ID + "= " + id ;
SQLiteDatabase db = this.getReadableDatabase();
db.execSQL(countQuery);
}
//Get FavList
public List<FavoriteList> getFavList(){
String selectQuery = "SELECT * FROM " + TABLE_TEST;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
List<FavoriteList> FavList = new ArrayList<FavoriteList>();
if (cursor.moveToFirst()) {
do {
FavoriteList list = new FavoriteList();
list.setId(Integer.parseInt(cursor.getString(0)));
list.setName(cursor.getString(1));
list.setAge(cursor.getString(2));
FavList.add(list);
} while (cursor.moveToNext());
}
return FavList;
}
}
Enojoys.... :)
It is better to use cursor adapter to bind the list view.You can use Loader to get the list updated even if there is a change in the data base.
onLoadFinished (Loader loader, D data) of the Loader call back would be monitor for changes to the data, and report them to you through new calls. You should not monitor the data yourself.
I have one dropdown when i click dropdown option then it will hit database and retrieve the data to my another dropdown list. For ex i have one drop down list with class names as options when i click on class name it will retrieve that class students names into another dropdown list from database. after send those details to the database when click on submit button?
i used to implement code based on this example for populating spinner based in another spinner selection
http://www.javaknowledge.info/populate-second-spinner-based-on-selection-of-first-spinner/
and for populating spinner from sqlite database i used this sample...please check this link
http://instinctcoder.com/android-studio-spinner-populate-data-sqlite/
my problem is resolved
//DATABASE HANdler.java
public class DatabaseHandler extends SQLiteOpenHelper {
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "spinnerExample";
// Labels table name
private static final String TABLE_LABELS = "labels";
// Labels Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_NAME = "name";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Creating Tables
#Override
public void onCreate(SQLiteDatabase db) {
// Category table create query
String CREATE_CATEGORIES_TABLE = "CREATE TABLE " + TABLE_LABELS + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT)";
db.execSQL(CREATE_CATEGORIES_TABLE);
}
// Upgrading database
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_LABELS);
// Create tables again
onCreate(db);
}
/**
* Inserting new lable into lables table
* */
public void insertLabel(String label){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, label);
// Inserting Row
db.insert(TABLE_LABELS, null, values);
db.close(); // Closing database connection
}
/**
* Getting all labels
* returns list of labels
* */
public List<String> getAllLabels(){
List<String> labels = new ArrayList<String>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_LABELS;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
labels.add(cursor.getString(1));
} while (cursor.moveToNext());
}
// closing connection
cursor.close();
db.close();
// returning lables
return labels;
}
}
//In your Main Acticity ,my one is AndroidSpinnerFromSQLiteActivity
public class AndroidSpinnerFromSQLiteActivity extends Activity implements
OnItemSelectedListener {
// Spinner element
Spinner spinner;
// Add button
Button btnAdd;
// Input text
EditText inputLabel;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Spinner element
spinner = (Spinner) findViewById(R.id.spinner);
// add button
btnAdd = (Button) findViewById(R.id.btn_add);
// new label input field
inputLabel = (EditText) findViewById(R.id.input_label);
// Spinner click listener
spinner.setOnItemSelectedListener(this);
// Loading spinner data from database
loadSpinnerData();
/**
* Add new label button click listener
* */
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
String label = inputLabel.getText().toString();
if (label.trim().length() > 0) {
// database handler
DatabaseHandler db = new DatabaseHandler(
getApplicationContext());
// inserting new label into database
db.insertLabel(label);
// making input filed text to blank
inputLabel.setText("");
// Hiding the keyboard
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(inputLabel.getWindowToken(), 0);
// loading spinner with newly added data
loadSpinnerData();
} else {
Toast.makeText(getApplicationContext(), "Please enter label name",
Toast.LENGTH_SHORT).show();
}
}
});
}
/**
* Function to load the spinner data from SQLite database
* */
private void loadSpinnerData() {
// database handler
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
// Spinner Drop down elements
List<String> lables = db.getAllLabels();
// Creating adapter for spinner
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, lables);
// Drop down layout style - list view with radio button
dataAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
spinner.setAdapter(dataAdapter);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
// On selecting a spinner item
String label = parent.getItemAtPosition(position).toString();
// Showing selected spinner item
Toast.makeText(parent.getContext(), "You selected: " + label,
Toast.LENGTH_LONG).show();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
I've been able to successfully link two spinners to a database using a SimpleCursorAdapter. But, I need to make the second spinner selection dependant on the first spinner selection.
Here is how I linked the data:
public class epa_estimates_button extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.epa_estimates);
final Cursor cYear;
final Cursor cMake;
final Spinner mMakeSpinner;
final Spinner mModelSpinner;
cYear = (Cursor) DataBaseHelper.getEPADataYear();
this.startManagingCursor(cYear);
SimpleCursorAdapter scaYear = new SimpleCursorAdapter(this, R.layout.spinner_layout,cYear,new String[] {DataBaseHelper.EPA_COLUMN_ONE},new int[]{R.id.text1});
scaYear.setDropDownViewResource(R.layout.spinner_dropdown);
mYearSpinner = (Spinner) findViewById(R.id.yearSpinner);
mYearSpinner.setAdapter(scaYear);
cMake = (Cursor) DataBaseHelper.getEPADataMake();
this.startManagingCursor(cMake);
SimpleCursorAdapter scaMake = new SimpleCursorAdapter(this, R.layout.spinner_layout,cMake,new String[] {DataBaseHelper.EPA_COLUMN_TWO},new int[]{R.id.text1});
scaMake.setDropDownViewResource(R.layout.spinner_dropdown);
mMakeSpinner = (Spinner) findViewById(R.id.makeSpinner);
mMakeSpinner.setAdapter(scaMake);
}}
Here is my DataBaseHelper
public class DataBaseHelper extends SQLiteOpenHelper {
private static String DB_PATH = "/data/data/org.application.ocdmpg/databases/";
private static String DB_NAME = "ocd_mpg.mp3";
private final int DB_VERSION = 1;
private static SQLiteDatabase myDataBase;
private final Context myContext;
private static final String EPA_TABLE_NAME = "epa_data";
private static final String EPA_COLUMN_ID = "_id";
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
public static Cursor getEPADataYear()
{
return myDataBase.query(EPA_TABLE_NAME, //table name
new String[] {EPA_COLUMN_ID, EPA_COLUMN_ONE}, //list of columns to return
null, //filter declaring which rows to return; formatted as SQL WHERE clause
null,
EPA_COLUMN_ONE, //filter declaring how to group rows; formatted as SQL GROUP BY clause
null, //filter declaring which row groups to include in cursor; formatted as SQL HAVING clause
null); //how to order rows; formatted as SQL ORDER BY clause
}
public static Cursor getEPADataMake()
{
return myDataBase.query(EPA_TABLE_NAME, new String[] {
EPA_COLUMN_ID,
EPA_COLUMN_TWO,
},
null,
null,
EPA_COLUMN_TWO,
null,
null);
}}
I've found code for setOnItemSelectedListener and tried to add my code for linking the data to the spinner but the startManagingCursor method and SimpleCursorAdapter constructors give me an error as undefined. Should I use an ArrayAdapter to populate my spinners? Or is there a way to correct the code below?
mYearSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
// your code here
cMake = (Cursor) DataBaseHelper.getEPADataMake();
this.startManagingCursor(cMake);
SimpleCursorAdapter scaMake = new SimpleCursorAdapter(this, R.layout.spinner_layout,cMake,new String[] {DataBaseHelper.EPA_COLUMN_TWO},new int[]{R.id.text1});
scaMake.setDropDownViewResource(R.layout.spinner_dropdown);
mMakeSpinner = (Spinner) findViewById(R.id.makeSpinner);
mMakeSpinner.setAdapter(scaMake);
}
#Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
Updated based on your edit and comments
Your call to this.startManagingCursor(cMake) needs to be changed to either startManagingCursor(cMake) or epa_estimates_button.this.startManagingCursor(cMake), since it's being made from within an inner class (an OnItemSelectedListener). It works without 'this' (the former case) because, well, basically, Java figures out which this you meant. And it works with the classname because that makes explicit what Java would have figured out for itself. But the unqualified this implies that you're referring to the inner class this, and that wouldn't work.
Very similarly, in your onItemSelectedListener, your call to startManagingCursor needs to be rewritten as:
SimpleCursorAdapter scaMake = new SimpleCursorAdapter(epa_estimates_button.this,
R.layout.spinner_layout,cMake,new String[] {DataBaseHelper.EPA_COLUMN_TWO},
new int[]{R.id.text1});
(I think your database queries are going to need work -- you don't seem to use any sort of WHERE clause to restrict the 'make' results to the appropriate year. But if you do get stuck on that, please post it as another question.)