0

Creating an alarm notification and just cant figure out why i keep running into the error of

android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0

it is failing on(in the schedule course alarm() part.

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

Part one


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);
        }

part two


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;
    }
}

part 3 -database code

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;
}
Blundell
  • 75,855
  • 30
  • 208
  • 233
Jason
  • 1
  • 1
  • What is the code in `DatabaseControl.getCourse(context, id)` as your error says about Cursor's, which is usually database access – Blundell Nov 04 '19 at 08:53
  • @Jason, this [answer](https://stackoverflow.com/a/24782159/8208808) might help you. – MihaiBC Nov 04 '19 at 09:18
  • @Blundell edited to show the database part – Jason Nov 04 '19 at 16:47
  • @MihaiBC i looked at the answer and based on that it looks like the cursor is coming back empty so its erroring out, but if i add those checks the error stops, but i get no alarm as the cursor never finds anything. I am not sure why its coming back empty... – Jason Nov 04 '19 at 16:58

1 Answers1

0

Sure the error message says:

android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0

So this means:

CursorIndexOutOfBoundsException think of a cursor as a collection, you are out of bounds

Index 0 requested You wanted to access at position 0 in the collection

with a size of 0 but the collections size is 0 (empty) therefore Out of Bounds.

If you are expecting your database schema to be correct you should not use getColumnIndex but use getColumnIndexOrThrow https://developer.android.com/reference/android/database/Cursor#getColumnIndexOrThrow(java.lang.String) that way you will fail fast and see which part of your data is incorrect.

But yeah basically your cursor is empty, check the query that you are doing. You can also breakpoint on a cursor, and to try alternative queries on teh content resolver.


You could also use a Tool like Stetho, to inspect your on device database to see if it has any data (and practice some queries)

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


Or move away from cursors altogther and use opne of the newer recommended database access libraries like Room:

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

Blundell
  • 75,855
  • 30
  • 208
  • 233
  • @Jason If you found this helpful pls remember to upvote or mark it as answered https://stackoverflow.com/help/someone-answers – Blundell Feb 15 '20 at 23:11