0

I am in the process of making my contacts manager application and suddenly I have got an error. It was working fine before but now I seem to receive errors when I am viewing a contact details (from the main screen) and also contacts are not being added correctly to the database.

Here is my Database code:
import java.util.ArrayList;
import java.util.HashMap;

import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

//SQLiteOpenHelper helps you open or create a database

public class DBTools extends SQLiteOpenHelper {

    public DBTools(Context applicationcontext) {
        // Creating the contacts database
        super(applicationcontext, "contactbook.db", null, 1);

    }

    // onCreate is called the first time the database is created
    public void onCreate(SQLiteDatabase database) {


        // Creating table in SQLite
        String query = "CREATE TABLE contacts ( contactId INTEGER PRIMARY KEY, firstName TEXT, " +
                "lastName TEXT, mobileNumber TEXT, homeNumber TEXT, workNumber TEXT, homeEmailAddress TEXT, workEmailAddress TEXT, homeAddress TEXT, workAddress TEXT, dateOfBirth TEXT, image BLOB)";  
        //Executes the query
        database.execSQL(query);

    }
    // onUpgrade is used to drop tables, add tables, or do anything 
    // else it needs to upgrade
    // This is dropping the table to delete the data and then calling
    // onCreate to make an empty table

    public void onUpgrade(SQLiteDatabase database, int version_old, int current_version) {
        String query = "DROP TABLE IF EXISTS contacts";

        //Executes the query
        database.execSQL(query);
        onCreate(database);
    }

    public void insertContact(HashMap<String, String> queryValues, byte[] img) {


        // Open a database for reading and writing
        SQLiteDatabase database = this.getWritableDatabase();
        // Stores key value pairs being the column name and the data
        // ContentValues data type is needed because the database
        // requires its data type to be passed

        ContentValues values = new ContentValues();

        values.put("firstName", queryValues.get("firstName"));
        values.put("lastName", queryValues.get("lastName"));
        values.put("mobileNumber", queryValues.get("mobileNumber"));
        values.put("homeNumber", queryValues.get("homeNumber"));
        values.put("workNumber", queryValues.get("workNumber"));
        values.put("homeEmailAddress", queryValues.get("homeEmailAddress"));
        values.put("workEmailAddress", queryValues.get("workEmailAddress"));
        values.put("homeAddress", queryValues.get("homeAddress"));
        values.put("workAddress", queryValues.get("workAddress"));
        values.put("dateOfBirth", queryValues.get("dateOfBirth"));
        values.put("image", img);



        // Inserts the data in the form of ContentValues into the
        // table name provided
        database.insert("contacts", null, values);

        database.close();
    }

    public int updateContact(HashMap<String, String> queryValues) {

        // Open a database for reading and writing

        SQLiteDatabase database = this.getWritableDatabase();   

        // Stores key value pairs being the column name and the data



        ContentValues values = new ContentValues();

        values.put("firstName", queryValues.get("firstName"));
        values.put("lastName", queryValues.get("lastName"));
        values.put("mobileNumber", queryValues.get("mobileNumber"));
        values.put("homeNumber", queryValues.get("homeNumber"));
        values.put("workNumber", queryValues.get("workNumber"));
        values.put("homeEmailAddress", queryValues.get("homeEmailAddress"));
        values.put("workEmailAddress", queryValues.get("workEmailAddress"));
        values.put("homeAddress", queryValues.get("homeAddress"));
        values.put("workAddress", queryValues.get("workAddress"));
        values.put("dateOfBirth", queryValues.get("dateOfBirth"));

        // update(TableName, ContentValueForTable, WhereClause, ArgumentForWhereClause)

        return database.update("contacts", values, "contactId" + " = ?", new String[] { queryValues.get("contactId") });
    }



    public void deleteContact(String id) {

        // Open a database for reading and writing
        SQLiteDatabase database = this.getWritableDatabase();

        String deleteQuery = "DELETE FROM  contacts where contactId='"+ id +"'";


        database.execSQL(deleteQuery);
    }

    public void deleteAllContacts(){
        // Open a database for reading and writing
        SQLiteDatabase database = this.getWritableDatabase();

        String deleteQuery = "DELETE FROM  contacts";


        database.execSQL(deleteQuery);
    }

    public ArrayList<HashMap<String, String>> getAllContacts(String sortOrder) {

        // ArrayList that contains every row in the database
        // and each row key / value stored in a HashMap

        ArrayList<HashMap<String, String>> contactArrayList;

        contactArrayList = new ArrayList<HashMap<String, String>>();

        //Sorting the contacts alphabetically by first name

        String selectQuery = "SELECT  * FROM contacts ORDER BY "+ sortOrder;

        // Open a database for reading and writing

        SQLiteDatabase database = this.getWritableDatabase();

        // Cursor provides read and write access for the 
        // data returned from a database query

        // rawQuery executes the query and returns the result as a Cursor

        Cursor cursor = database.rawQuery(selectQuery, null);   

        // Move to the first row

        if (cursor.moveToFirst()) {
            do {
                HashMap<String, String> contactMap = new HashMap<String, String>();

                // Store the key / value pairs in a HashMap
                // Access the Cursor data by index that is in the same order
                // as used when creating the table
                contactMap.put("contactId", cursor.getString(0));
                contactMap.put("firstName", cursor.getString(1));
                contactMap.put("lastName", cursor.getString(2));
                contactMap.put("mobileNumber", cursor.getString(3));
                contactMap.put("homeNumber", cursor.getString(4));
                contactMap.put("workNumber", cursor.getString(5));
                contactMap.put("homeEmailAddress", cursor.getString(6));
                contactMap.put("workEmailAddress", cursor.getString(7));
                contactMap.put("homeAddress", cursor.getString(8));
                contactMap.put("workAddress", cursor.getString(9));
                contactMap.put("dateOfBirth", cursor.getString(10));


                contactArrayList.add(contactMap);
            } while (cursor.moveToNext()); // Move Cursor to the next row
        }

     // return contact list
        return contactArrayList;
    }

    public HashMap<String, String> getContactInfo(String id) {
        HashMap<String, String> contactMap = new HashMap<String, String>();

        // Open a database for reading only
        SQLiteDatabase database = this.getReadableDatabase();

        String selectQuery = "SELECT * FROM contacts where contactId='"+id+"'";


        // rawQuery executes the query and returns the result as a Cursor
        Cursor cursor = database.rawQuery(selectQuery, null);
        if (cursor.moveToFirst()) {
            do {
                contactMap.put("contactId", cursor.getString(0));   
                contactMap.put("firstName", cursor.getString(1));
                contactMap.put("lastName", cursor.getString(2));
                contactMap.put("mobileNumber", cursor.getString(3));
                contactMap.put("homeNumber", cursor.getString(4));
                contactMap.put("workNumber", cursor.getString(5));
                contactMap.put("homeEmailAddress", cursor.getString(6));
                contactMap.put("workEmailAddress", cursor.getString(7));
                contactMap.put("homeAddress", cursor.getString(8));
                contactMap.put("workAddress", cursor.getString(9));
                contactMap.put("dateOfBirth", cursor.getString(10));




            } while (cursor.moveToNext());
        }                   
    return contactMap;
    }

    public byte[] getImage(String id){
        SQLiteDatabase database = this.getReadableDatabase();
        byte[] theByte;
        String selectQuery = "SELECT * FROM contacts where contactId='"+id+"'";

        Cursor cursor = database.rawQuery(selectQuery, null);
        cursor.moveToFirst();
        theByte = cursor.getBlob(11);


        return theByte;
    }


}

And here is my code for Viewing a Contact:

    public class ViewContactDetails extends Activity {

        private EditText firstName;
        private EditText lastName;
        private EditText dateOfBirth;
        private EditText mobileNumber;
        private EditText homeNumber;
        private EditText workNumber;
        private EditText homeEmail;
        private EditText workEmail;
        private EditText homeAddress;
        private EditText workAddress;
        private String contactId;
        private Button callContact;
        private byte[] contactByteImage;
        private ImageView img;
        DBTools dbTools = new DBTools(this);


        @Override
        public void onCreate(Bundle savedInstanceState) {

            // Get saved data if there is any

            super.onCreate(savedInstanceState);


            setContentView(R.layout.activity_view_contact_details);

            // Initialize the EditText objects

            initilizeEditTextObjects();

            Intent theIntent = getIntent();

            contactId = theIntent.getStringExtra("contactId");
            callContact= (Button) findViewById(R.id.callContactButton);




            HashMap<String, String> contactList = dbTools.getContactInfo(contactId);
            contactByteImage = dbTools.getImage(contactId);
            if (contactByteImage == null){
                img.setImageResource(R.drawable.contact);
            }
            else{
                Bitmap bm = BitmapFactory.decodeByteArray(contactByteImage, 0, contactByteImage.length);
                Bitmap resizedBitMap = Bitmap.createScaledBitmap(bm, bm.getWidth()/4, bm.getHeight()/4, false); 
                img.setImageBitmap(resizedBitMap);
            }


            if(contactList.size()!=0){
                firstName.setText(contactList.get("firstName"));
                lastName.setText(contactList.get("lastName"));
                mobileNumber.setText(contactList.get("mobileNumber"));
                homeNumber.setText(contactList.get("homeNumber"));
                workNumber.setText(contactList.get("workNumber"));
                homeEmail.setText(contactList.get("homeEmailAddress"));
                workEmail.setText(contactList.get("workEmailAddress"));
                homeAddress.setText(contactList.get("homeAddress"));
                workAddress.setText(contactList.get("workAddress"));
                dateOfBirth.setText(contactList.get("dateOfBirth"));



            }

            callContact.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    String number = "tel:" +mobileNumber.getText().toString();
                    Intent intent = new Intent(Intent.ACTION_CALL,Uri.parse(number));
                    startActivity(intent);


                }
            });


        }
        // Initializes all the Edit Text Fields and makes the text boxes non editable (since on this particular screen, 
        // the details are only viewed).
        public void initilizeEditTextObjects(){
            firstName = (EditText) findViewById(R.id.firstName);
            firstName.setKeyListener(null);
            lastName = (EditText) findViewById(R.id.lastName);
            lastName.setKeyListener(null);
            dateOfBirth = (EditText) findViewById(R.id.dateOfBirth);
            dateOfBirth.setKeyListener(null);
            mobileNumber = (EditText) findViewById(R.id.mobileNumber);
            mobileNumber.setKeyListener(null);
            homeNumber = (EditText) findViewById(R.id.homeNumber);
            homeNumber.setKeyListener(null);
            workNumber = (EditText) findViewById(R.id.workNumber);
            workNumber.setKeyListener(null);
            homeEmail = (EditText) findViewById(R.id.emailAddressHome);
            homeEmail.setKeyListener(null);
            workEmail = (EditText) findViewById(R.id.emailAddressWork);
            workEmail.setKeyListener(null);
            homeAddress = (EditText) findViewById(R.id.homeAddress);
            homeAddress.setKeyListener(null);
            workAddress = (EditText) findViewById(R.id.workAddress);
            workAddress.setKeyListener(null);
            img = (ImageView) findViewById(R.id.viewContactImage);
        }

        // This method receives the information that was given when this activity was created. 
        // It receives messages from the bundle and it represents the contact that is being edited.
        // This information is initialized in the fields.


        @Override
        public boolean onCreateOptionsMenu(Menu menu){
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.view_contact_details, menu);
            return true;
        }



        public boolean onOptionsItemSelected(MenuItem item) {
            switch(item.getItemId()) {
            // If the delete button is pressed, a dialog box will appear. This will inform the user
            // that the contact will be deleted. If the user clicks "OK", the contact is deleted
            // from the list and the application returns to the Main Activity. If the user clicks
            // "cancel", the application stays in the current screen and nothing happens.

            case R.id.deleteImageButton:
                AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(ViewContactDetails.this);

                dialogBuilder.setTitle("Delete Contact");
                dialogBuilder.setMessage("Contact will be deleted");

                dialogBuilder.setNegativeButton("Cancel", null);
                dialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dbTools.deleteContact(contactId);

                        Intent theIntent = new Intent(getApplicationContext(), MainActivity.class);
                        startActivity(theIntent);

                    }
                });
                dialogBuilder.setCancelable(true);

                dialogBuilder.create().show();

                break;

                // If the edit button is pressed, the contact details (fields) are retrieved from the text boxes.
                // These details are put as additional data for the Edit Contact class. The application then
                // goes to the Edit Contact screen.

            case R.id.editButton:


                Intent theIntent = new Intent(getApplicationContext(), EditContact.class);
                theIntent.putExtra("contactId", contactId);

                startActivity(theIntent);           
            default:
                return super.onOptionsItemSelected(item);
            }

            return true;
        }
    }



LogCat:

10-23 18:02:52.697: E/CursorWindow(1082): Failed to read row 0, column 11 from a CursorWindow which has 1 rows, 11 columns.
10-23 18:02:52.697: D/AndroidRuntime(1082): Shutting down VM
10-23 18:02:52.697: W/dalvikvm(1082): threadid=1: thread exiting with uncaught exception (group=0x41465700)
10-23 18:02:52.747: E/AndroidRuntime(1082): FATAL EXCEPTION: main
10-23 18:02:52.747: E/AndroidRuntime(1082): java.lang.RuntimeException: Unable to start activity ComponentInfo{dgop507.softeng206.contactsmanagerapplication/dgop507.softeng206.contactsmanagerapplication.ViewContactDetails}: java.lang.IllegalStateException: Couldn't read row 0, col 11 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.os.Looper.loop(Looper.java:137)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.app.ActivityThread.main(ActivityThread.java:5103)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at java.lang.reflect.Method.invokeNative(Native Method)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at java.lang.reflect.Method.invoke(Method.java:525)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at dalvik.system.NativeStart.main(Native Method)
10-23 18:02:52.747: E/AndroidRuntime(1082): Caused by: java.lang.IllegalStateException: Couldn't read row 0, col 11 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.database.CursorWindow.nativeGetBlob(Native Method)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.database.CursorWindow.getBlob(CursorWindow.java:399)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.database.AbstractWindowedCursor.getBlob(AbstractWindowedCursor.java:45)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at dgop507.softeng206.contactsmanagerapplication.DBTools.getImage(DBTools.java:224)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at dgop507.softeng206.contactsmanagerapplication.ViewContactDetails.onCreate(ViewContactDetails.java:64)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.app.Activity.performCreate(Activity.java:5133)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
10-23 18:02:52.747: E/AndroidRuntime(1082):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
10-23 18:02:52.747: E/AndroidRuntime(1082):     ... 11 more
Dheeraj
  • 313
  • 1
  • 3
  • 12
  • Just a hint, in your getImage method, you should either check the count of the cursor or check the return value of Cursor.moveToFirst(). It will return false if the cursor is empty. https://developer.android.com/reference/android/database/Cursor.html#moveToFirst() – Arnaud Oct 23 '13 at 22:12
  • something like this? public byte[] getImage(String id){ SQLiteDatabase database = this.getReadableDatabase(); byte[] theByte; String selectQuery = "SELECT * FROM contacts where contactId='"+id+"'"; Cursor cursor = database.rawQuery(selectQuery, null); if (cursor.moveToFirst()){ do{ theByte = cursor.getBlob(11); } while (cursor.moveToNext()); return theByte; } else{ return null; } } – Dheeraj Oct 23 '13 at 22:38
  • still givin me an error. seems like my getContactInfo() method is also not correct... – Dheeraj Oct 23 '13 at 22:40

1 Answers1

0

It's look like you try to read the 12th column which doesn't exists.

Hope this will help those getting into the same error ....

There is some similar questions on StackOverFlow with accepted answers. you should check there if it's answer the current question

Community
  • 1
  • 1
Ester Kaufman
  • 708
  • 10
  • 20