我正在制作我的联系人管理器应用程序,突然出现错误。它以前工作正常,但现在我在查看联系人详细信息(从主屏幕)时似乎收到错误,并且联系人没有正确添加到数据库中。
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