ItsMeElvis
ItsMeElvis

Reputation: 21

How to use AlarmManager with the data that is stored in SQLite Database?

I am making an alarm application where the user selects date and time. The data is stored in an SQL database. What i want to do is to call a notification once that time is reached. I tried doing this by simply using the time slected by the user, but the alarm still exists even if I delete the alarm or edit the time. That is why I need to use the data from the database, so if the alarm is deleted, the notification would not go through. I have looked at everything related on the internet, and nothing seemed to work. This is the code where I insert the data in the database and where I display the date and time in text views.

databaseHelperAlarm = new DatabaseHelperAlarm(this);

final Calendar c = Calendar.getInstance();
        final int mYear = c.get(Calendar.YEAR);
        final int mMonth = c.get(Calendar.MONTH);
        final int mDay = c.get(Calendar.DAY_OF_MONTH);
        final int mHour = c.get(Calendar.HOUR_OF_DAY);
        final int mMinute = c.get(Calendar.MINUTE);

    xml_arrow_back.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(AddAlarmActivity.this, AlarmActivity.class);
            startActivity(intent);
        }
    });

    xml_fab_add.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String title = xml_title.getText().toString();
            String date = xml_date.getText().toString();
            String time = xml_time.getText().toString();
            String repeat = xml_repeat.getText().toString();

            if ((xml_title.getText().toString().equals("")) || (xml_date.getText().toString().equals("")) || (xml_time.getText().toString().equals(""))) {
                Toast.makeText(getApplicationContext(), "Fields Must Not Be Empty", Toast.LENGTH_SHORT).show();
            } else {
                databaseHelperAlarm.insertData(title, date, time, repeat);
                Toast.makeText(getApplicationContext(), "Reminder Made", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(AddAlarmActivity.this, AlarmActivity.class);
                startActivity(intent);
            }
        }
    });

   xml_set_date.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            InputMethodManager input = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            input.hideSoftInputFromWindow(xml_set_date.getWindowToken(), 0);
            xml_title.clearFocus();

            datePickerDialog = new DatePickerDialog(AddAlarmActivity.this,
                    new DatePickerDialog.OnDateSetListener() {
                        @Override
                        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                            Calendar calendar = Calendar.getInstance();
                            calendar.set(year, monthOfYear, dayOfMonth);
                            SimpleDateFormat format = new SimpleDateFormat("EEE, MMM dd, yyyy");
                            String dateString = format.format(calendar.getTime());
                            xml_date.setText(dateString);
                        }
                    }, mYear, mMonth, mDay);
            datePickerDialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
            if(!datePickerDialog.isShowing()){
                datePickerDialog.show();
            }
        }
    });

    xml_set_time.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            InputMethodManager input = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            input.hideSoftInputFromWindow(xml_set_time.getWindowToken(), 0);
            xml_title.clearFocus();

            timePickerDialog = new TimePickerDialog(AddAlarmActivity.this,
                    new TimePickerDialog.OnTimeSetListener() {
                        @Override
                        public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {

                            String chosenHour = "";
                            String chosenMinute = "";
                            String chosenTimeZone = "";
                            if(selectedHour > 12){
                                chosenTimeZone = "PM";
                                selectedHour = selectedHour - 12;
                                if(selectedHour < 10){
                                    chosenHour = "0"+selectedHour;
                                }else{
                                    chosenHour = ""+selectedHour;
                                }
                            }else{
                                chosenTimeZone = "AM";
                                if(selectedHour < 10){
                                    chosenHour = "0"+selectedHour;
                                }else{
                                    chosenHour = ""+selectedHour;
                                }
                            }

                            if(selectedMinute < 10){
                                chosenMinute = "0"+selectedMinute;
                            }else{
                                chosenMinute= ""+selectedMinute;
                            }

                            xml_time.setText(chosenHour + ":" + chosenMinute +" "+chosenTimeZone);
                        }
                    }, mHour, mMinute, false);
            timePickerDialog.show();
        }
    });}

}

My guess is that I need to make another Curser or something, but I have no idea where to start. Here is part of the code from my database though.

public void  insertData (String a_title, String a_date, String a_time, String a_repeat){
        ContentValues contentValues = new ContentValues();
        contentValues.put(A_TITLE, a_title);
        contentValues.put(A_DATE, a_date);
        contentValues.put(A_TIME, a_time);
        contentValues.put(A_REPEAT, a_repeat);

        SQLiteDatabase sqLiteDB = this.getWritableDatabase();
        sqLiteDB.insert(TABLE_NAME, null, contentValues);
        sqLiteDB.close();
    }

    public ArrayList<AlarmInfo> getMainInfo() {
        ArrayList<AlarmInfo> list = new ArrayList<>();
        String SQL = "SELECT * FROM " + TABLE_NAME;
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(SQL, null);
        if (cursor.moveToFirst()) {
            do {
                AlarmInfo ai = new AlarmInfo();
                ai.setiD(cursor.getInt(0) + "");
                ai.setTitle(cursor.getString(1));
                ai.setDate(cursor.getString(2));
                ai.setTime(cursor.getString(3));
                list.add(ai);
            } while (cursor.moveToNext());
        }
        return list;
    }

    public Cursor getAllData(int getId) {
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor res = db.rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE " +
                A_ID + "=?", new String[] {Integer.toString(getId)});
        return res;
    }

I appreciate any help. Thanks.

Upvotes: 1

Views: 1125

Answers (1)

MikeT
MikeT

Reputation: 56953

I believe, you have two relatively easy ways, perhaps used together.

You could a) delete rows when the alarm time has expired. It may be that the repeat column is used to repeat the alarm in which case an update rather than a delete would be required (this would require b)).

You could b) also be more specific in regard to the query/queries that drive the addition of the alarm to only select rows for future date/times.

So no real need for another cursor as such.


Personally I would (and have used, as below) use a single column for date and time using a timestamp, rather than trying to work with two columns.

The following is an example, akin to selection based upon date/time. (handling repeating rules that add items to a shopping list on a regular user defined basis) :-

String filter = DBRulesTableConstants.RULES_ACTON_COL +
    " <= " +
    Long.toString(getDateTimeOfAllofToday()) +
    SQLAND +
    DBRulesTableConstants.RULES_PROMPT_COL +
    " = 0 ";

(DBRulesTableConstants.RULES_????_ COL equates to column names, SQLAND is AND), getDateTimeofALlofToday, returns the timestamp 1 millisecond before midnight of the current day (i.e. in this case I want all rules before and on today (bar that 1 millisecond :))).

e.g. running this now ( about 14:20 20th Sept 2017) results in the filter being :-

ruleacton <= 1505915999999 AND ruleprompt = 0 

This being incorporated into the query's WHERE clause e.g. :-

SELECT ........ WHERE ruleacton <= 1505915999999 AND ruleprompt = 0  ;

Just in case you're interested here's getDateTimeOfAllofToday :-

private long getDateTimeOfAllofToday() {
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.DAY_OF_MONTH,1); // tomorrow
    cal.set(Calendar.MILLISECOND,0);
    cal.set(Calendar.SECOND,0);
    cal.set(Calendar.MINUTE,0);
    cal.set(Calendar.HOUR_OF_DAY,0);
    cal.add(Calendar.MILLISECOND,-1);
}

Upvotes: 1

Related Questions