• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

sort function in my dictionary app isn't working

oncebuddy

Lurker
Feb 2, 2018
1
0
I have a dictionary app which stores a word with the meaning, type (English,Chinese,Japanese etc) and favorite status (whether it's a favorite word). On 1 of my menu items, there's this item called sort. When I click on it, I am expecting the words in my main page to be sorted in ascending order but instead I got this error in ListFragment.java: 'java.lang.IllegalStateException: Couldn't read row 0, col 4 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.'

MainActivity.java

Code:
    package mapp.com.sg.pocketdictionary;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.content.Intent;
    import android.view.Menu;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import mapp.com.sg.pocketdictionary.db.WordsDataSource;
    public class MainActivity extends AppCompatActivity implements ListFragment.OnContactSelectedInterface/*,SearchView.OnQueryTextListener*/ {
        protected WordsDataSource myDataSource;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
 
            myDataSource = new WordsDataSource(this);
            this.setTitle("PD");
            //The code here decides whether to create the fragment because it can be destroyed by the Android system
            //when it reclaims memory
            ListFragment savedFragment = (ListFragment) getSupportFragmentManager().findFragmentByTag("WORDS_FRAGMENT");
            if (savedFragment == null) {
                ListFragment fragment = new ListFragment();
                Bundle bundle = new Bundle();
                bundle.putBoolean("isFavourite", false);
                fragment.setArguments(bundle);
                android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
                android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.add(R.id.placeHolder, fragment, "WORDS_FRAGMENT");
                fragmentTransaction.commit();
            }
 
        }
 
 
        @Override
        protected void onResume() {
            //The code here is required because when I save the data and navigate back
            //I need my applicationn logic to refresh the fragement content to reflect the changes
            //to avoid the list interface listing the old data.
            super.onResume();
            ListFragment savedFragment = (ListFragment) getSupportFragmentManager().findFragmentByTag("WORDS_FRAGMENT");
            if (savedFragment != null) {
                android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
                android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.detach(savedFragment);
                fragmentTransaction.attach(savedFragment);
                fragmentTransaction.commit();
            }
        }
 
        @Override
        public void onListContactSelected(int index) {
            //When tap on a row display word, this logic here will start collecting the
            //id which is tied to the data and navigate the user to another Activity
            //and at the same time pass the id over.
            //   Toast.makeText(this, "PUMPKINNNNNN", Toast.LENGTH_SHORT).show(); for testing if tap detected
            Intent intent = new Intent(this, WordsDetailActivity.class);
            intent.putExtra("WordId", index);//index variable name may not be suitable here
            startActivity(intent);
        }
 
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            MenuInflater myMenuInflater = getMenuInflater();
            myMenuInflater.inflate(R.menu.menu, menu);
        }
 
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
 
            String itemTitle = item.getTitle().toString();
            if (item.getItemId() == R.id.favourite) {
                // Toast.makeText(this, "GER" , Toast.LENGTH_SHORT).show();//Go to favorite action choice detected
                startActivity(new Intent(this, FavouriteActivity.class));
            } else if (item.getItemId() == R.id.Add) {
                //   Toast.makeText(this, "EEEEYEERR", Toast.LENGTH_SHORT).show();//Go to add word action choice detected
                startActivity(new Intent(this, AddWordsActivity.class));
            } else if (item.getItemId() == R.id.sort) {
                Bundle bundle = new Bundle();
                bundle.putBoolean("isSortByAsc", true);
 
                ListFragment savedFragment = (ListFragment) getSupportFragmentManager().findFragmentByTag("WORDS_FRAGMENT");
 
                if (savedFragment != null) {
                    savedFragment.setArguments(bundle);
                    android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
                    android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                    fragmentTransaction.detach(savedFragment);
                    fragmentTransaction.attach(savedFragment);
                    fragmentTransaction.commit();
                }
            }
        }
            return super.onOptionsItemSelected(item);
    }
    }


ListFragment.java

Code:
   package mapp.com.sg.pocketdictionary;
 
    import android.database.Cursor;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import java.util.ArrayList;
 
    import mapp.com.sg.pocketdictionary.db.WordsDataSource;
    public class ListFragment extends Fragment {
        protected WordsDataSource mDataSource;
        private boolean isFavourite;
        private boolean isSortByAsc;
 
        public interface OnContactSelectedInterface {
 
            void onListContactSelected(int index);
 
        }
 
 
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 
            OnContactSelectedInterface listener = (OnContactSelectedInterface) getActivity();
 
            isFavourite = getArguments().getBoolean("isFavourite");
            isSortByAsc = getArguments().getBoolean("isSortByAsc");
            View view = inflater.inflate(R.layout.fragment_recycler, container,false);
 
            //-------------------
            //The rest of the code below is to read all or favorite word data
            //and fill up the ArrayList variable.
            mDataSource = new WordsDataSource(getContext());
            mDataSource.open();
            Cursor cursor;
            if(isFavourite){
                 cursor = mDataSource.selectFavouriteWords();
            }
          else if (isSortByAsc){
 
                cursor = mDataSource.sortWords();
            }
 
            else{
                 cursor = mDataSource.selectAllWords();
        }
 
            ArrayList<Words> wordsList = new ArrayList<>();
            cursor.moveToFirst();
 
            while(!cursor.isAfterLast()){
 
 
                boolean tempFav = true;//The database uses 0 and 1 to represent true or false
                //Therefore I used this tempFav so that my logic here can store true or false
                //during the getString() call
                //Error occurs here
                if (cursor.getInt(4) != 0) {
                    tempFav = false;
                }
 
 
                Words tempWords =new Words(cursor.getString(1),cursor.getString(2),cursor.getString(3),tempFav);
                tempWords.setId(cursor.getInt(0));
                wordsList.add(tempWords);
                //Log.d("MY Activity", "onCreateView: "+  tempWords.getId()+" " + tempWords.getWord()+" " +tempWords.getMeaning()+" "+ tempWords.getType()+" "+  cursor.getInt(4));
                Log.d("MY Activity", "cursor: "+  cursor.getInt(0)+ " "+cursor.getString(1)+" " + cursor.getString(2)+" "+cursor.getString(3)+" " + cursor.getInt(4));
                //Column 0 is id, column 1 is word, column 2 is meaning, column 3 is type, column 4 is favorite status(0 for true and 1 for false)
                cursor.moveToNext();
 
            }
            mDataSource.close();
            //-----------------------
            //After the ArrayList variable is filled with data,
            //create a listAdapter type object
            RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
            //Creating a ListAdapter object and at the same time pass in a "walkie-talkie" so that it can
            //yell out if any related events happening and also the ArrayList of contect information
            ListAdapter listAdapter = new ListAdapter(listener, wordsList);
            recyclerView.setAdapter(listAdapter);//Start using it
            RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
            recyclerView.setLayoutManager(layoutManager);
            return view;
        }
    }


WordsDataSource.java

Code:
    package mapp.com.sg.pocketdictionary.db;
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteDatabase;
    import android.util.Log;
 
    import mapp.com.sg.pocketdictionary.Words;
    public class WordsDataSource {
 
            private SQLiteDatabase mDatabase;
            private WordsHelper mWordsHelper;
            private Context mContext;
 
        public WordsDataSource(Context context){
            mContext = context;
            mWordsHelper = new WordsHelper(mContext);
        }
 
        //open data base
        public void open() throws SQLException {
            mDatabase = mWordsHelper.getWritableDatabase();
 
        }
        //close
        public void close() {
            mDatabase.close();
        }
        //insert
        public void insertWords(Words words) {
            mDatabase.beginTransaction();
            try{
                ContentValues values = new ContentValues();
 
                values.put(WordsHelper.COLUMN_WORD, words.getWord());
                values.put(WordsHelper.COLUMN_MEANING, words.getMeaning());
                values.put(WordsHelper.COLUMN_TYPE, words.getType());
 
                int fav = 0;
                if (!words.isFavourite()) {
                    fav = 1;
                }
                values.put(WordsHelper.COLUMN_FAVOURITE, fav);
                mDatabase.insert(WordsHelper.TABLE_WORDS, null, values);
 
                mDatabase.setTransactionSuccessful();
            } finally {
                mDatabase.endTransaction();
            }
        }
 
        //sort
        public Cursor sortWords (){
            String[] wordname = new String[]{ WordsHelper.COLUMN_WORD };
            Cursor cursor= mDatabase.query(WordsHelper.TABLE_WORDS,wordname , null, null, null, null, WordsHelper.COLUMN_WORD+" ASC");
 
    return cursor;
        }
        //select
        public Cursor selectAllWords(){
            Cursor cursor = mDatabase.rawQuery("Select * from " + WordsHelper.TABLE_WORDS, null);
            return cursor;
        }
 
        public Cursor selectOneWord(int Id){
            Cursor cursor = mDatabase.rawQuery("Select * from " + WordsHelper.TABLE_WORDS+" where "
                    + WordsHelper.COLUMN_ID+" = " + Id, null);
            return cursor;
        }
        public Cursor selectFavouriteWords() {
            Cursor cursor = mDatabase.rawQuery("Select * from " + WordsHelper.TABLE_WORDS+" where "
                    + WordsHelper.COLUMN_FAVOURITE+" = 0" , null);
            return cursor;
        }
        //update
        public boolean updateWords(int id, String word, String meaning,String type, boolean fav){
            ContentValues values = new ContentValues();
            int success = -1;
 
            values.put(WordsHelper.COLUMN_WORD, word);
            values.put(WordsHelper.COLUMN_MEANING, meaning);
            values.put(WordsHelper.COLUMN_TYPE, type);
 
            int favDigit = 0;
            if(!fav){
                favDigit = 1;
            }
 
 
            values.put(WordsHelper.COLUMN_FAVOURITE, favDigit);
 
 
            success =  mDatabase.update(
                    WordsHelper.TABLE_WORDS,
                    values,
                    WordsHelper.COLUMN_ID + " = " + id,
                    null
 
            );
            if(success != -1 && success != 0) {
                return true;
            } else {
                return false;
            }
 
        }
 
        public boolean setFavourite (int id, boolean fav) {
            ContentValues values = new ContentValues();
            int success = -1;
            int favDigit = 0;
            if(!fav){
                favDigit = 1;
            }
            values.put(WordsHelper.COLUMN_FAVOURITE, favDigit);
            success =  mDatabase.update(
                    WordsHelper.TABLE_WORDS,
                    values,
                    WordsHelper.COLUMN_ID + " = " + id,
                    null
 
            );
            if(success != -1 && success != 0) {
                return true;
            } else {
                return false;
            }
        }
 
        public boolean updateWords(int id, String word, String meaning,String type){
            ContentValues values = new ContentValues();
            int success = -1;
            if(word != null ){
                values.put(WordsHelper.COLUMN_WORD, word);
            }
 
            if(meaning != null ){
                values.put(WordsHelper.COLUMN_MEANING, meaning);
            }
 
            if(type != null ){
                values.put(WordsHelper.COLUMN_TYPE, type);
            }
 
 
            success =  mDatabase.update(
                    WordsHelper.TABLE_WORDS,
                    values,
                    WordsHelper.COLUMN_ID + " = " + id,
                    null
 
            );
            if(success != -1 && success != 0) {
                return true;
            } else {
                return false;
            }
 
        }
 
        //delete
        public boolean deleteWords(int id) {
            int success = -1;
            success = mDatabase.delete(
                    WordsHelper.TABLE_WORDS,
                    WordsHelper.COLUMN_ID + " = " + id,
                    null
            );
            if(success != -1 && success !=0) {
                return true;
            } else {
                return false;
            }
        }
 
        public boolean deleteWords() {
            int success = -1;
            success = mDatabase.delete(
                    WordsHelper.TABLE_WORDS,
                    null,
                    null
            );
            if(success != -1 ) {
                return true;
            } else {
                return false;
            }
        }
 
    }


WordsHelper.java
Code:
    package mapp.com.sg.pocketdictionary.db;
 
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    //Helps make all code in WordsDataSource neater, readable and maintainable.
 
    public class WordsHelper extends SQLiteOpenHelper {
        public static final String TABLE_WORDS ="WORDS";
        public static final String COLUMN_ID = "_ID";
        public static final String COLUMN_WORD = "WORD";
        public static final String COLUMN_MEANING = "MEANING";
        public static final String COLUMN_TYPE = "TYPE";
        public static final String COLUMN_FAVOURITE = "FAVOURITE";
 
 
 
        private static final String DB_NAME = "words.db";
        private static final int DB_VER = 1;
        private static final String DB_CREATE = "CREATE TABLE "+TABLE_WORDS+
                " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT" +
                ", " + COLUMN_WORD + " TEXT, "  +
                COLUMN_MEANING + " TEXT,"+
                COLUMN_TYPE + " TEXT,"+ COLUMN_FAVOURITE +" INTEGER)";
 
 
        public WordsHelper(Context context){
            super(context, DB_NAME, null, DB_VER);
 
        }
 
        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase) {
            sqLiteDatabase.execSQL(DB_CREATE);
        }
 
        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
 
        }
    }
 

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones