我的问题是,当我点击ListView项目在另一个Activity中显示一些细节我的应用程序崩溃
Logcat:
java.lang.RuntimeException: Unable to resume activity {com.example.myapp/com.example.myapp.DetailsActivity}: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3137)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3168)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2515)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:114)
Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:460)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at com.khalilteache.eventsreminder.DetailsActivity.populateFields(DetailsActivity.java:171)
at com.khalilteache.eventsreminder.DetailsActivity.onResume(DetailsActivity.java:88)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1259)
at android.app.Activity.performResume(Activity.java:6327)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3126)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3168)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2515)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:114)
这时我执行项目点击:
ListView events = (ListView)findViewById(android.R.id.list);
events.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(EventsActivity.this, DetailsActivity.class);
i.putExtra(ReminderDbAdapter.KEY_ROWID, id);
startActivityForResult(i, ACTIVITY_EDIT);
}
});
这里是问题所在的DetailsActivity
public class DetailsActivity extends Activity {
//
// Dialog Constants
//
private static final int DATE_PICKER_DIALOG = 0;
private static final int TIME_PICKER_DIALOG = 1;
private static final int ACTIVITY_EDIT=1;
//
// Date Format
//
private static final String DATE_FORMAT = "yyyy-MM-dd";
private static final String TIME_FORMAT = "kk:mm";
public static final String DATE_TIME_FORMAT = "yyyy-MM-dd kk:mm:ss";
private EditText mTitleText;
private EditText mBodyText;
private Button mDateButton;
private Button mTimeButton;
private Button mConfirmButton;
private Long mRowId;
private ReminderDbAdapter mDbHelper;
private Calendar mCalendar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDbHelper = new ReminderDbAdapter(this);
setContentView(R.layout.activity_details);
mCalendar = Calendar.getInstance();
mTitleText = (EditText) findViewById(R.id.title);
mBodyText = (EditText) findViewById(R.id.body);
mDateButton = (Button) findViewById(R.id.reminder_date);
mTimeButton = (Button) findViewById(R.id.reminder_time);
mConfirmButton = (Button) findViewById(R.id.confirm);
mRowId = savedInstanceState != null ? savedInstanceState.getLong(KEY_ROWID)
: null;
registerButtonListenersAndSetDefaultText();
}
private void setRowIdFromIntent() {
if (mRowId == null) {
Bundle extras = getIntent().getExtras();
mRowId = extras != null ? extras.getLong(ReminderDbAdapter.KEY_ROWID)
: null;
}
}
@Override
protected void onPause() {
super.onPause();
mDbHelper.close();
}
@Override
protected void onResume() {
super.onResume();
mDbHelper.open();
setRowIdFromIntent();
populateFields();
}
@Override
protected Dialog onCreateDialog(int id) {
switch(id) {
case DATE_PICKER_DIALOG:
return showDatePicker();
case TIME_PICKER_DIALOG:
return showTimePicker();
}
return super.onCreateDialog(id);
}
private DatePickerDialog showDatePicker() {
DatePickerDialog datePicker = new DatePickerDialog(DetailsActivity.this, new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
mCalendar.set(Calendar.YEAR, year);
mCalendar.set(Calendar.MONTH, monthOfYear);
mCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
updateDateButtonText();
}
}, mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH));
return datePicker;
}
private TimePickerDialog showTimePicker() {
TimePickerDialog timePicker = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
mCalendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
mCalendar.set(Calendar.MINUTE, minute);
updateTimeButtonText();
}
}, mCalendar.get(Calendar.HOUR_OF_DAY), mCalendar.get(Calendar.MINUTE), true);
return timePicker;
}
private void registerButtonListenersAndSetDefaultText() {
mDateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog(DATE_PICKER_DIALOG);
}
});
mTimeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog(TIME_PICKER_DIALOG);
}
});
mConfirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
setResult(RESULT_OK);
Toast.makeText(DetailsActivity.this,"ooo", Toast.LENGTH_SHORT).show();
finish();
}
});
updateDateButtonText();
updateTimeButtonText();
}
private void populateFields() {
if (mRowId != null) {
Cursor reminder = mDbHelper.fetchReminder(mRowId);
startManagingCursor(reminder);
mTitleText.setText(reminder.getString(
reminder.getColumnIndexOrThrow(KEY_TITLE)));
mBodyText.setText(reminder.getString(
reminder.getColumnIndexOrThrow(KEY_BODY)));
}
}
private void updateTimeButtonText() {
// Set the time button text based upon the value from the database
SimpleDateFormat timeFormat = new SimpleDateFormat(TIME_FORMAT);
String timeForButton = timeFormat.format(mCalendar.getTime());
mTimeButton.setText(timeForButton);
}
private void updateDateButtonText() {
// Set the date button text based upon the value from the database
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
String dateForButton = dateFormat.format(mCalendar.getTime());
mDateButton.setText(dateForButton);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(KEY_ROWID, mRowId);
}
}
我花了15个多小时寻找解决方案,但我失败了。每个答案都将不胜感激。
这是我的ReminderDbAdapter
public class ReminderDbAdapter {
//
// Databsae Related Constants
//
private static final String DATABASE_NAME = "data";
private static final String DATABASE_TABLE = "reminders";
private static final int DATABASE_VERSION = 3;
public static final String KEY_TITLE = "title";
public static final String KEY_BODY = "body";
public static final String KEY_DATE_TIME = "reminder_date_time";
public static final String KEY_ROWID = "_id";
public static final String KEY_COLORID = "_id_color";
public static final String KEY_IMAGEID = "_id_image";
private static final String TAG = "ReminderDbAdapter";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
/**
* Database creation SQL statement
*/
private static final String DATABASE_CREATE =
"create table " + DATABASE_TABLE + " ("
+ KEY_ROWID + " integer primary key autoincrement, "
+ KEY_TITLE + " text not null, "
+ KEY_BODY + " text not null, "
+ KEY_COLORID + " integer not null, "
+ KEY_IMAGEID + " integer not null, "
+ KEY_DATE_TIME + " text not null);";
private final Context mCtx;
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
/**
* Constructor - takes the context to allow the database to be
* opened/created
*
* @param ctx the Context within which to work
*/
public ReminderDbAdapter(Context ctx) {
this.mCtx = ctx;
}
/**
* Open the database. If it cannot be opened, try to create a new
* instance of the database. If it cannot be created, throw an exception to
* signal the failure
*
* @return this (self reference, allowing this to be chained in an
* initialization call)
* @throws SQLException if the database could be neither opened or created
*/
public ReminderDbAdapter open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() {
mDbHelper.close();
}
/**
* Create a new reminder using the title, body and reminder date time provided.
* If the reminder is successfully created return the new rowId
* for that reminder, otherwise return a -1 to indicate failure.
*
* @param title the title of the reminder
* @param body the body of the reminder
* @param reminderDateTime the date and time the reminder should remind the user
* @return rowId or -1 if failed
*/
public long createReminder(String title, String body, String reminderDateTime, int color_id, int image_id) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_TITLE, title);
initialValues.put(KEY_BODY, body);
initialValues.put(KEY_COLORID, color_id);
initialValues.put(KEY_IMAGEID, image_id);
initialValues.put(KEY_DATE_TIME, reminderDateTime);
return mDb.insert(DATABASE_TABLE, null, initialValues);
}
/**
* Delete the reminder with the given rowId
*
* @param rowId id of reminder to delete
* @return true if deleted, false otherwise
*/
public boolean deleteReminder(long rowId) {
return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
/**
* Return a Cursor over the list of all reminders in the database
*
* @return Cursor over all reminders
*/
public Cursor fetchAllReminders() {
return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TITLE,
KEY_BODY, KEY_COLORID, KEY_IMAGEID, KEY_DATE_TIME}, null, null, null, null, null);
}
/**
* Return a Cursor positioned at the reminder that matches the given rowId
*
* @param rowId id of reminder to retrieve
* @return Cursor positioned to matching reminder, if found
* @throws SQLException if reminder could not be found/retrieved
*/
public Cursor fetchReminder(long rowId) throws SQLException {
Cursor mCursor =
mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
KEY_TITLE, KEY_BODY, KEY_COLORID, KEY_IMAGEID, KEY_DATE_TIME}, KEY_ROWID + "=" + rowId, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
/**
* Update the reminder using the details provided. The reminder to be updated is
* specified using the rowId, and it is altered to use the title, body and reminder date time
* values passed in
*
* @param rowId id of reminder to update
* @param title value to set reminder title to
* @param body value to set reminder body to
* @param reminderDateTime value to set the reminder time.
* @return true if the reminder was successfully updated, false otherwise
*/
public boolean updateReminder(long rowId, String title, String body, String reminderDateTime, int color_id, int image_id) {
ContentValues args = new ContentValues();
args.put(KEY_TITLE, title);
args.put(KEY_BODY, body);
args.put(KEY_COLORID, color_id);
args.put(KEY_IMAGEID, image_id);
args.put(KEY_DATE_TIME, reminderDateTime);
return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}
}