Android 联系人管理器

标签 android sqlite

我正在制作联系人管理器应用程序,突然出现错误。之前它工作正常,但现在我在查看联系人详细信息(从主屏幕)时似乎收到错误消息,而且联系人未正确添加到数据库中。

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

最佳答案

看起来您试图读取不存在的第 12 列。

希望这能帮助那些陷入同样错误的人....

StackOverFlow 上有一些类似的问题,答案已被接受。 你应该在那里检查它是否回答了当前的问题

关于Android 联系人管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19553170/

相关文章:

android - 在 Android 中随机启动 Activity

android - 如何使用 Intent 打开 FB 应用程序并在 FB 应用程序中显示喜欢的页面?

android - 三星 android 时钟应用程序 - 源代码?

iphone - 比 -forwardInspiration : to perform messages on a specific thread 更快的方法

mysql - (SQL)将最后一个逗号后面的文本从一列复制到新一列

java - Android Nougat 在捕获视频时返回 null

android - 停止/销毁线程

sqlite - 这个查询有什么问题?

ruby-on-rails - 在新的 Rails 项目中从 SQLite 更改为 PostgreSQL

android - GreenDAO - 多列上的主键