首页 > 解决方案 > 异常:- android.database.CursorIndexOutOfBoundsException:请求索引 0,大小为 0

问题描述

创建警报通知,但无法弄清楚为什么我一直遇到错误

android.database.CursorIndexOutOfBoundsException: 请求索引 0,大小为 0

它失败了(在计划课程警报()部分。

alarmManager.set(AlarmManager.RTC_WAKEUP, time, PendingIntent.getBroadcast(context, nextAlarmId, intentAlarm, PendingIntent.FLAG_ONE_SHOT));

第一部分


private boolean createTestAlarm() {
        long now = DateUtil.todayLong();
        if (now <= DateUtil.getDateTimestamp(course.start)) {
            AlarmHandler.scheduleCourseAlarm(getApplicationContext(), courseId, DateUtil.getDateTimestamp(course.start),
                    "Course starts today!", course.name + " begins on " + course.start);
        }

第二部分


public class AlarmHandler extends BroadcastReceiver {
    public static final String courseAlarmFile = "courseAlarms";
    public static final String assessmentAlarmFile = "assessmentAlarms";
    public static final String alarmFile = "alarmFile";
    public static final String nextAlarmField = "nextAlarmId";
    @Override
    public void onReceive(Context context, Intent intent) {
        String destination = intent.getStringExtra("destination");
        if (destination == null || destination.isEmpty()) {
            destination = "";
        }
        int id = intent.getIntExtra("id", 0);
        String alarmTitle = intent.getStringExtra("title");
        String alarmText = intent.getStringExtra("text");
        int nextAlarmId = intent.getIntExtra("nextAlarmId", getAndIncrementNextAlarmId(context));
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
                .setSmallIcon(R.drawable.ic_calendar_clock)
                .setContentTitle(alarmTitle)
                .setContentText(alarmText);
        Intent resultIntent;
        Uri uri;
        SharedPreferences sharedPreferences;
        switch (destination) {
            case "course":
                Course course = DatabaseControl.getCourse(context, id);
                if (course != null && course.notifications == 1) {
                    resultIntent = new Intent(context, CourseViewerActivity.class);
                    uri = Uri.parse(DatabaseData.COURSES_URI + "/" + id);
                    resultIntent.putExtra(DatabaseData.COURSE_CONTENT_TYPE, uri);
                }
                else {
                    return;
                }
                break;
            case "assessment":
                Assessment assessment = DatabaseControl.getAssessment(context, id);
                if (assessment != null && assessment.notifications == 1) {
                    resultIntent = new Intent(context, AssessmentViewerActivity.class);
                    uri = Uri.parse(DatabaseData.ASSESSMENTS_URI + "/" + id);
                    resultIntent.putExtra(DatabaseData.ASSESSMENT_CONTENT_TYPE, uri);
                }
                else {
                    return;
                }
                break;
            default:
                resultIntent = new Intent(context, MainActivity.class);
                break;
        }
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
        stackBuilder.addParentStack(MainActivity.class);
        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(resultPendingIntent).setAutoCancel(true);
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(nextAlarmId, builder.build());
    }
    public static boolean scheduleCourseAlarm(Context context, long id, long time, String title, String text) {
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        int nextAlarmId = getNextAlarmId(context);
        Intent intentAlarm = new Intent(context, AlarmHandler.class);
        intentAlarm.putExtra("id", id);
        intentAlarm.putExtra("title", title);
        intentAlarm.putExtra("text", text);
        intentAlarm.putExtra("destination", "course");
        intentAlarm.putExtra("nextAlarmId", nextAlarmId);
        alarmManager.set(AlarmManager.RTC_WAKEUP, time, PendingIntent.getBroadcast(context, nextAlarmId, intentAlarm, PendingIntent.FLAG_ONE_SHOT));
        SharedPreferences sp = context.getSharedPreferences(courseAlarmFile, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putInt(Long.toString(id), nextAlarmId);
        editor.commit();
        incrementNextAlarmId(context);
        return true;
    }
    private static int getNextAlarmId(Context context) {
        SharedPreferences alarmPrefs;
        alarmPrefs = context.getSharedPreferences(alarmFile, Context.MODE_PRIVATE);
        int nextAlarmId = alarmPrefs.getInt(nextAlarmField, 1);
        return nextAlarmId;
    }

    private static void incrementNextAlarmId(Context context) {
        SharedPreferences alarmPrefs;
        alarmPrefs = context.getSharedPreferences(alarmFile, Context.MODE_PRIVATE);
        int nextAlarmId = alarmPrefs.getInt(nextAlarmField, 1);
        SharedPreferences.Editor alarmEditor = alarmPrefs.edit();
        alarmEditor.putInt(nextAlarmField, nextAlarmId + 1);
        alarmEditor.commit();
    }
    private static int getAndIncrementNextAlarmId(Context context) {
        int nextAlarmId = getNextAlarmId(context);
        incrementNextAlarmId(context);
        return nextAlarmId;
    }
}

第 3 部分 - 数据库代码

public static Course getCourse(Context context, long courseId) {
    Cursor cursor = context.getContentResolver().query(DatabaseData.COURSES_URI, Database.COURSES_COLUMNS,
            Database.COURSES_TABLE_ID + " = " + courseId, null, null);
    cursor.moveToFirst();
    Long termId = cursor.getLong(cursor.getColumnIndex(Database.COURSE_TERM_ID));
    String courseName = cursor.getString(cursor.getColumnIndex(Database.COURSE_NAME));
    String courseDescription = cursor.getString(cursor.getColumnIndex(Database.COURSE_DESCRIPTION));
    String courseStart = cursor.getString(cursor.getColumnIndex(Database.COURSE_START));
    String courseEnd = cursor.getString(cursor.getColumnIndex(Database.COURSE_END));
    String courseMentor = cursor.getString(cursor.getColumnIndex(Database.COURSE_MENTOR));
    String courseMentorPhone = cursor.getString(cursor.getColumnIndex(Database.COURSE_MENTOR_PHONE));
    String courseMentorEmail = cursor.getString(cursor.getColumnIndex(Database.COURSE_MENTOR_EMAIL));
    String courseNote = cursor.getString(cursor.getColumnIndex(Database.COURSE_NOTE));
    int courseNotifications = (cursor.getInt(cursor.getColumnIndex(Database.COURSE_NOTIFICATIONS)));

    Course c = new Course();
    c.courseId = courseId;
    c.termId = termId;
    c.name = courseName;
    c.description = courseDescription;
    c.start = courseStart;
    c.end = courseEnd;
    c.mentor = courseMentor;
    c.mentorPhone = courseMentorPhone;
    c.mentorEmail = courseMentorEmail;
    c.note = courseNote;
    c.notifications = courseNotifications;
    return c;
}

标签: androidindexingnotificationsalarm

解决方案


当然错误消息说:

android.database.CursorIndexOutOfBoundsException: 请求索引 0,大小为 0

所以这意味着:

CursorIndexOutOfBoundsException把游标想象成一个集合,你已经越界了

Index 0 requested您想在集合中的位置 0 访问

with a size of 0但集合大小为 0(空),因此超出范围。

如果您希望您的数据库架构正确,则不应使用getColumnIndex而是使用getColumnIndexOrThrow https://developer.android.com/reference/android/database/Cursor#getColumnIndexOrThrow(java.lang.String)这样您将快速失败并查看您的哪一部分数据不正确。

但是,基本上你的光标是空的,检查你正在做的查询。您还可以在游标上设置断点,并在内容解析器上尝试替代查询。


您还可以使用 Stetho 之类的工具来检查您的设备数据库以查看它是否有任何数据(并练习一些查询)

http://facebook.github.io/stetho/


或者完全远离游标并使用更新的推荐数据库访问库的 opne,例如 Room:

https://developer.android.com/topic/libraries/architecture/room


推荐阅读