When you try to display the contents of a database in TextView
pops up here this error:
02-27 19:44:59.519: E/AndroidRuntime(5696): FATAL EXCEPTION: main
02-27 19:44:59.519: E/AndroidRuntime(5696): android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
02-27 19:44:59.519: E/AndroidRuntime(5696): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:418)
02-27 19:44:59.519: E/AndroidRuntime(5696): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
02-27 19:44:59.519: E/AndroidRuntime(5696): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
02-27 19:44:59.519: E/AndroidRuntime(5696): at ru.zloyel.manager_sutochnoy_arendy_1.ViewContact$LoadContactTask.onPostExecute(ViewContact.java:98)
02-27 19:44:59.519: E/AndroidRuntime(5696): at ru.zloyel.manager_sutochnoy_arendy_1.ViewContact$LoadContactTask.onPostExecute(ViewContact.java:1)
02-27 19:44:59.519: E/AndroidRuntime(5696): at android.os.AsyncTask.finish(AsyncTask.java:631)
02-27 19:44:59.519: E/AndroidRuntime(5696): at android.os.AsyncTask.access$600(AsyncTask.java:177)
02-27 19:44:59.519: E/AndroidRuntime(5696): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
02-27 19:44:59.519: E/AndroidRuntime(5696): at android.os.Handler.dispatchMessage(Handler.java:99)
02-27 19:44:59.519: E/AndroidRuntime(5696): at android.os.Looper.loop(Looper.java:137)
02-27 19:44:59.519: E/AndroidRuntime(5696): at android.app.ActivityThread.main(ActivityThread.java:4745)
02-27 19:44:59.519: E/AndroidRuntime(5696): at java.lang.reflect.Method.invokeNative(Native Method)
02-27 19:44:59.519: E/AndroidRuntime(5696): at java.lang.reflect.Method.invoke(Method.java:511)
02-27 19:44:59.519: E/AndroidRuntime(5696): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
02-27 19:44:59.519: E/AndroidRuntime(5696): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-27 19:44:59.519: E/AndroidRuntime(5696): at dalvik.system.NativeStart.main(Native Method)
My DB ContactDBmoy.java
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
import android.util.Log;
public class ContactDBmoy extends SQLiteOpenHelper implements BaseColumns {
// константы для конструктора
private static final String DATABASE_NAME = "contact_db.db";
private static final int DATABASE_VERSION = 1;
public static final String TABLE_NAME = "contact_table";
public static final String COLUMN_NAME = "name_contact";
public static final String COLUMN_PHONE = "phone";
public static final String COLUMN_BIRTHDAY = "birthday";
public static final String COLUMN_PASSPORT_SN = "passport_sn";
public static final String COLUMN_ADRESS = "adress";
public static final String COLUMN_SITE = "site";
ContactDBmoy cqh;
SQLiteDatabase sdb;
private static final String SQL_CREATE_CONTACTS = "CREATE TABLE "
+ TABLE_NAME + " (" + BaseColumns._ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_NAME
+ " text not null, " + COLUMN_PHONE + " text not null, "
+ COLUMN_BIRTHDAY + " integer, " + COLUMN_PASSPORT_SN
+ " text not null, " + COLUMN_ADRESS + " text not null, "
+ COLUMN_SITE + " text not null " + ");";
private static final String SQL_DELETE_CONTACTS = "DROP TABLE IF EXISTS "
+ TABLE_NAME;
public ContactDBmoy(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
public ContactDBmoy(Context context, String name, CursorFactory factory,
int version, DatabaseErrorHandler errorHandler) {
super(context, DATABASE_NAME, null, DATABASE_VERSION, errorHandler);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(SQL_CREATE_CONTACTS);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
Log.w(ContactDBmoy.class.getName(), "Обновление базы данных с версии "
+ oldVersion + " до версии " + newVersion
+ ", которое удалит все старые данные");
// Удаляем предыдущую таблицу при апгрейде
db.execSQL(SQL_DELETE_CONTACTS);
// Создаём новый экземпляр таблицы
onCreate(db);
}
/**
* Создаёт новый элемент списка. Если создан успешно - возвращается номер
* строки rowId, иначе -1
*/
public long createNewContact(String name_contact, String phone,
String birthday, String passport_sn, String adress, String site) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues initialValues = createContentValues(name_contact, phone,
birthday, passport_sn, adress, site);
long row = db.insert(TABLE_NAME, null, initialValues);
db.close();
return row;
}
/**
* Обновляет список
*/
public boolean updateContact(long rowId, String name_contact, String phone,
String birthday, String passport_sn, String adress, String site) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues updateValues = createContentValues(name_contact, phone,
birthday, passport_sn, adress, site);
return db.update(TABLE_NAME, updateValues, _ID + "=" + rowId, null) > 0;
}
/**
* Удаляет элемент списка
*/
public void deleteContact(long rowId) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME, _ID + "=" + rowId, null);
db.close();
}
/**
* Возвращает курсор со всеми элементами списка
*
* @return курсор с результатами всех записей
*/
public Cursor getAllContact() {
SQLiteDatabase db = this.getWritableDatabase();
return db.query(TABLE_NAME, new String[] { BaseColumns._ID,
COLUMN_NAME, COLUMN_PHONE, COLUMN_BIRTHDAY, COLUMN_PASSPORT_SN,
COLUMN_ADRESS, COLUMN_SITE }, null, null, null, null, null);
}
/**
* Возвращает курсор с указанной записи
*/
public Cursor getContact(long rowId) throws SQLException {
SQLiteDatabase db = this.getReadableDatabase();
Cursor mCursor = db.query(true, TABLE_NAME, new String[] { COLUMN_NAME,
COLUMN_PHONE, COLUMN_BIRTHDAY, COLUMN_PASSPORT_SN,
COLUMN_ADRESS, COLUMN_SITE }, _ID + "=" + rowId, null, null,
null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
/*
* Создаёт пару ключ-значение и записывает в базу
*/
private ContentValues createContentValues(String name_contact,
String phone, String birthday, String passport_sn, String adress,
String site) {
ContentValues cv = new ContentValues();
cv.put(COLUMN_NAME, name_contact);
cv.put(COLUMN_PHONE, phone);
cv.put(COLUMN_BIRTHDAY, birthday);
cv.put(COLUMN_PASSPORT_SN, passport_sn);
cv.put(COLUMN_ADRESS, adress);
cv.put(COLUMN_SITE, site);
return cv;
}
}
ViewContact.java
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;
public class ViewContact extends Activity {
private long rowID; // имя выбранного контакта
private TextView nameTV; // отображает имя контакта
private TextView phoneTV; // номер телефона контакта
private TextView birthdayTV; // дата рождения контакта
private TextView passportTV; // паспортные данные контакта
private TextView adressTV; // адрес прописки контакта
private TextView siteTV; // адрес прописки контакта
public static final String COLUMN_NAME = "name_contact";
public static final String COLUMN_PHONE = "phone";
public static final String COLUMN_BIRTHDAY = "birthday";
public static final String COLUMN_PASSPORT_SN = "passport_sn";
public static final String COLUMN_ADRESS = "adress";
public static final String COLUMN_SITE = "site";
ContactDBmoy cqh;
SQLiteDatabase sdb;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.contact_view_moy);
nameTV = (TextView) findViewById(R.id.nameTV);
phoneTV = (TextView) findViewById(R.id.phoneTV);
birthdayTV = (TextView) findViewById(R.id.birthdayTV);
passportTV = (TextView) findViewById(R.id.passportTV);
adressTV = (TextView) findViewById(R.id.adressTV);
siteTV = (TextView) findViewById(R.id.siteTV);
// получение ID строки выбранного контакта
Bundle extras = getIntent().getExtras();
rowID = extras.getLong(ContactDBmoy._ID);
}
@Override
protected void onResume() {
super.onResume();
// создание нового класса LoadContactTask и вызов его
new LoadContactTask().execute(rowID);
}
// выполняет запрос к базе данных за пределами потока GUI
private class LoadContactTask extends AsyncTask<Long, Object, Cursor> {
ContactDBmoy cqh = new ContactDBmoy(ViewContact.this);
// выполнение доступа к базе данных
@Override
protected Cursor doInBackground(Long... params) {
sdb = cqh.getWritableDatabase();
// получение курсора, содержащего все данные выбранной записи
return cqh.getContact(params[0]);
}
// использование объекта типа Cursor, возвращаемого методом
// doInBackground
@Override
protected void onPostExecute(Cursor mCursor) {
super.onPostExecute(mCursor);
mCursor.moveToFirst(); // перемещение к первому элементу
// получение индекса столбца для каждого элемента данных
int nameIndex = mCursor.getColumnIndex(COLUMN_NAME);
int phoneIndex = mCursor.getColumnIndex(COLUMN_PHONE);
int birthdayIndex = mCursor.getColumnIndex(COLUMN_BIRTHDAY);
int passportIndex = mCursor.getColumnIndex(COLUMN_PASSPORT_SN);
int adressIndex = mCursor.getColumnIndex(COLUMN_ADRESS);
int siteIndex = mCursor.getColumnIndex(COLUMN_SITE);
// заполнение компонентов TextViews выбранными данными
nameTV.setText(mCursor.getString(nameIndex));
phoneTV.setText(mCursor.getString(phoneIndex));
birthdayTV.setText(mCursor.getString(birthdayIndex));
passportTV.setText(mCursor.getString(passportIndex));
adressTV.setText(mCursor.getString(adressIndex));
siteTV.setText(mCursor.getString(siteIndex));
mCursor.close(); // закрытие курсора результата
sdb.close(); // закрытие подключения к базе данных
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.view_contact_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.editItem:
// создание Intent для запуска AddEditContact
Intent addEditContact = new Intent(this, Contact.class);
// передача данных выбранного контакта
addEditContact.putExtra(ContactDBmoy._ID, rowID);
addEditContact.putExtra("name", nameTV.getText());
addEditContact.putExtra("phone", phoneTV.getText());
addEditContact.putExtra("birthday", birthdayTV.getText());
addEditContact.putExtra("passport_sn", passportTV.getText());
addEditContact.putExtra("adress", adressTV.getText());
addEditContact.putExtra("site", siteTV.getText());
startActivity(addEditContact);
return true;
case R.id.deleteItem:
deleteContact(); // удаление отображенного контакта
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// удаление контакта
private void deleteContact() {
// создание нового AlertDialog Builder
AlertDialog.Builder builder = new AlertDialog.Builder(ViewContact.this);
builder.setTitle(R.string.confirmTitle);
builder.setMessage(R.string.confirmMessage);
builder.setPositiveButton(R.string.button_delete,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int button) {
final ContactDBmoy cqh = new ContactDBmoy(
ViewContact.this);
// создание класса AsyncTask, удаляющего контакт
// из другого потока, после удаления вызывается finish
AsyncTask<Long, Object, Object> deleteTask = new AsyncTask<Long, Object, Object>() {
@Override
protected Object doInBackground(Long... params) {
cqh.deleteContact(params[0]);
return null;
}
@Override
protected void onPostExecute(Object result) {
finish(); // возврат в AddressBook
}
};
// вызов класса AsyncTask для удаления контакта с rowID
deleteTask.execute(new Long[] { rowID });
}
});
builder.setNegativeButton(R.string.button_cancel, null);
builder.show();
}
}
What is my error?
You are getting no values in the cursor, like MH. pointed in the comments. You can change your code to the following to avoid CursorIndexOutOfBoundsException
Hope it helps.