diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 4f40844bf..bdc5c011c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -60,6 +60,8 @@
android:resource="@xml/widget_info"/>
+
+
diff --git a/app/src/main/java/com/simplemobiletools/calendar/CalendarImpl.java b/app/src/main/java/com/simplemobiletools/calendar/CalendarImpl.java
index 20422dc36..889c59813 100644
--- a/app/src/main/java/com/simplemobiletools/calendar/CalendarImpl.java
+++ b/app/src/main/java/com/simplemobiletools/calendar/CalendarImpl.java
@@ -107,12 +107,12 @@ public class CalendarImpl implements DBHelper.DBOperationsListener {
}
@Override
- public void eventInserted() {
+ public void eventInserted(Event event) {
}
@Override
- public void eventUpdated() {
+ public void eventUpdated(Event event) {
}
diff --git a/app/src/main/java/com/simplemobiletools/calendar/DBHelper.java b/app/src/main/java/com/simplemobiletools/calendar/DBHelper.java
index ff819e58d..2c6964be0 100644
--- a/app/src/main/java/com/simplemobiletools/calendar/DBHelper.java
+++ b/app/src/main/java/com/simplemobiletools/calendar/DBHelper.java
@@ -16,7 +16,7 @@ public class DBHelper extends SQLiteOpenHelper {
private static DBOperationsListener mCallback;
private static final String DB_NAME = "events.db";
- private static final int DB_VERSION = 1;
+ private static final int DB_VERSION = 2;
private static final String TABLE_NAME = "events";
private static final String COL_ID = "id";
@@ -24,6 +24,7 @@ public class DBHelper extends SQLiteOpenHelper {
private static final String COL_END_TS = "end_ts";
private static final String COL_TITLE = "title";
private static final String COL_DESCRIPTION = "description";
+ private static final String COL_REMINDER_MINUTES = "reminder_minutes";
public static DBHelper newInstance(Context context, DBOperationsListener callback) {
mCallback = callback;
@@ -42,19 +43,25 @@ public class DBHelper extends SQLiteOpenHelper {
COL_START_TS + " INTEGER," +
COL_END_TS + " INTEGER," +
COL_TITLE + " TEXT," +
- COL_DESCRIPTION + " TEXT" +
+ COL_DESCRIPTION + " TEXT," +
+ COL_REMINDER_MINUTES + " INTEGER" +
")");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-
+ if (oldVersion == 1) {
+ db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN " + COL_REMINDER_MINUTES + " INTEGER DEFAULT -1");
+ }
}
public void insert(Event event) {
final ContentValues values = fillContentValues(event);
- mDb.insert(TABLE_NAME, null, values);
- mCallback.eventInserted();
+ long id = mDb.insert(TABLE_NAME, null, values);
+ event.setId((int) id);
+
+ if (mCallback != null)
+ mCallback.eventInserted(event);
}
public void update(Event event) {
@@ -62,7 +69,9 @@ public class DBHelper extends SQLiteOpenHelper {
final String selection = COL_ID + " = ?";
final String[] selectionArgs = {String.valueOf(event.getId())};
mDb.update(TABLE_NAME, values, selection, selectionArgs);
- mCallback.eventUpdated();
+
+ if (mCallback != null)
+ mCallback.eventUpdated(event);
}
private ContentValues fillContentValues(Event event) {
@@ -71,24 +80,20 @@ public class DBHelper extends SQLiteOpenHelper {
values.put(COL_END_TS, event.getEndTS());
values.put(COL_TITLE, event.getTitle());
values.put(COL_DESCRIPTION, event.getDescription());
+ values.put(COL_REMINDER_MINUTES, event.getReminderMinutes());
return values;
}
- public void deleteEvent(int id) {
- final String selection = COL_ID + " = ?";
- final String[] selectionArgs = {String.valueOf(id)};
- mDb.delete(TABLE_NAME, selection, selectionArgs);
- mCallback.eventsDeleted(1);
- }
-
public void deleteEvents(String[] ids) {
final String selection = COL_ID + " IN (?)";
mDb.delete(TABLE_NAME, selection, ids);
- mCallback.eventsDeleted(ids.length);
+
+ if (mCallback != null)
+ mCallback.eventsDeleted(ids.length);
}
public void getEvents(int fromTS, int toTS) {
- final String[] projection = {COL_ID, COL_START_TS, COL_END_TS, COL_TITLE, COL_DESCRIPTION};
+ final String[] projection = {COL_ID, COL_START_TS, COL_END_TS, COL_TITLE, COL_DESCRIPTION, COL_REMINDER_MINUTES};
List events = new ArrayList<>();
final String selection = COL_START_TS + " <= ? AND " + COL_END_TS + " >= ?";
final String[] selectionArgs = {String.valueOf(toTS), String.valueOf(fromTS)};
@@ -101,18 +106,40 @@ public class DBHelper extends SQLiteOpenHelper {
final int endTS = cursor.getInt(cursor.getColumnIndex(COL_END_TS));
final String title = cursor.getString(cursor.getColumnIndex(COL_TITLE));
final String description = cursor.getString(cursor.getColumnIndex(COL_DESCRIPTION));
- events.add(new Event(id, startTS, endTS, title, description));
+ final int reminderMinutes = cursor.getInt(cursor.getColumnIndex(COL_REMINDER_MINUTES));
+ events.add(new Event(id, startTS, endTS, title, description, reminderMinutes));
} while (cursor.moveToNext());
}
cursor.close();
}
- mCallback.gotEvents(events);
+
+ if (mCallback != null)
+ mCallback.gotEvents(events);
+ }
+
+ public Event getEvent(int id) {
+ final String[] projection = {COL_START_TS, COL_END_TS, COL_TITLE, COL_DESCRIPTION, COL_REMINDER_MINUTES};
+ final String selection = COL_ID + " = ?";
+ final String[] selectionArgs = {String.valueOf(id)};
+ final Cursor cursor = mDb.query(TABLE_NAME, projection, selection, selectionArgs, null, null, null);
+ if (cursor != null) {
+ if (cursor.moveToFirst()) {
+ final int startTS = cursor.getInt(cursor.getColumnIndex(COL_START_TS));
+ final int endTS = cursor.getInt(cursor.getColumnIndex(COL_END_TS));
+ final String title = cursor.getString(cursor.getColumnIndex(COL_TITLE));
+ final String description = cursor.getString(cursor.getColumnIndex(COL_DESCRIPTION));
+ final int reminderMinutes = cursor.getInt(cursor.getColumnIndex(COL_REMINDER_MINUTES));
+ cursor.close();
+ return new Event(id, startTS, endTS, title, description, reminderMinutes);
+ }
+ }
+ return null;
}
public interface DBOperationsListener {
- void eventInserted();
+ void eventInserted(Event event);
- void eventUpdated();
+ void eventUpdated(Event event);
void eventsDeleted(int cnt);
diff --git a/app/src/main/java/com/simplemobiletools/calendar/NotificationPublisher.java b/app/src/main/java/com/simplemobiletools/calendar/NotificationPublisher.java
new file mode 100644
index 000000000..5478a3f3a
--- /dev/null
+++ b/app/src/main/java/com/simplemobiletools/calendar/NotificationPublisher.java
@@ -0,0 +1,49 @@
+package com.simplemobiletools.calendar;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import com.simplemobiletools.calendar.activities.EventActivity;
+import com.simplemobiletools.calendar.models.Event;
+
+public class NotificationPublisher extends BroadcastReceiver {
+ public static String EVENT_ID = "event_id";
+
+ public void onReceive(Context context, Intent intent) {
+ final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ int id = intent.getIntExtra(EVENT_ID, -1);
+ if (id == -1)
+ return;
+
+ final Event event = DBHelper.newInstance(context, null).getEvent(id);
+ if (event == null || event.getReminderMinutes() == -1)
+ return;
+
+ final PendingIntent pendingIntent = getPendingIntent(context, event);
+ final String startTime = Formatter.getTime(event.getStartTS());
+ final String endTime = Formatter.getTime(event.getEndTS());
+ final String title = event.getTitle();
+ final Notification notification = getNotification(context, pendingIntent, startTime + " - " + endTime + " " + title);
+ notificationManager.notify(id, notification);
+ }
+
+ private PendingIntent getPendingIntent(Context context, Event event) {
+ final Intent intent = new Intent(context, EventActivity.class);
+ intent.putExtra(Constants.EVENT, event);
+ return PendingIntent.getActivity(context, 0, intent, 0);
+ }
+
+ private Notification getNotification(Context context, PendingIntent pendingIntent, String content) {
+ final Notification.Builder builder = new Notification.Builder(context);
+ builder.setContentTitle(context.getResources().getString(R.string.app_name));
+ builder.setContentText(content);
+ builder.setSmallIcon(R.mipmap.calendar);
+ builder.setContentIntent(pendingIntent);
+ builder.setAutoCancel(true);
+ return builder.build();
+ }
+}
diff --git a/app/src/main/java/com/simplemobiletools/calendar/activities/DayActivity.java b/app/src/main/java/com/simplemobiletools/calendar/activities/DayActivity.java
index 114628f11..ecbdc0f5f 100644
--- a/app/src/main/java/com/simplemobiletools/calendar/activities/DayActivity.java
+++ b/app/src/main/java/com/simplemobiletools/calendar/activities/DayActivity.java
@@ -189,12 +189,12 @@ public class DayActivity extends AppCompatActivity
}
@Override
- public void eventInserted() {
+ public void eventInserted(Event event) {
}
@Override
- public void eventUpdated() {
+ public void eventUpdated(Event event) {
}
diff --git a/app/src/main/java/com/simplemobiletools/calendar/activities/EventActivity.java b/app/src/main/java/com/simplemobiletools/calendar/activities/EventActivity.java
index c969a9a8d..21401e610 100644
--- a/app/src/main/java/com/simplemobiletools/calendar/activities/EventActivity.java
+++ b/app/src/main/java/com/simplemobiletools/calendar/activities/EventActivity.java
@@ -1,15 +1,20 @@
package com.simplemobiletools.calendar.activities;
+import android.app.AlarmManager;
import android.app.DatePickerDialog;
+import android.app.PendingIntent;
import android.app.TimePickerDialog;
+import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
+import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatSpinner;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TextView;
@@ -18,6 +23,7 @@ import android.widget.TimePicker;
import com.simplemobiletools.calendar.Constants;
import com.simplemobiletools.calendar.DBHelper;
import com.simplemobiletools.calendar.Formatter;
+import com.simplemobiletools.calendar.NotificationPublisher;
import com.simplemobiletools.calendar.R;
import com.simplemobiletools.calendar.Utils;
import com.simplemobiletools.calendar.models.Event;
@@ -39,11 +45,13 @@ public class EventActivity extends AppCompatActivity implements DBHelper.DBOpera
@BindView(R.id.event_end_time) TextView mEndTime;
@BindView(R.id.event_title) EditText mTitleET;
@BindView(R.id.event_description) EditText mDescriptionET;
+ @BindView(R.id.event_reminder_other) EditText mReminderOtherET;
@BindView(R.id.event_reminder) AppCompatSpinner mReminder;
private static DateTime mEventStartDateTime;
private static DateTime mEventEndDateTime;
private static Event mEvent;
+ private static boolean mWasReminderInit;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -55,6 +63,7 @@ public class EventActivity extends AppCompatActivity implements DBHelper.DBOpera
if (intent == null)
return;
+ mWasReminderInit = false;
final Event event = (Event) intent.getSerializableExtra(Constants.EVENT);
if (event != null) {
mEvent = event;
@@ -72,6 +81,7 @@ public class EventActivity extends AppCompatActivity implements DBHelper.DBOpera
updateStartTime();
updateEndDate();
updateEndTime();
+ setupReminder();
}
private void setupEditEvent() {
@@ -93,9 +103,42 @@ public class EventActivity extends AppCompatActivity implements DBHelper.DBOpera
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
}
+ private void showKeyboard(EditText et) {
+ InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showSoftInput(et, InputMethodManager.SHOW_IMPLICIT);
+ }
+
+ private void setupReminder() {
+ switch (mEvent.getReminderMinutes()) {
+ case -1:
+ mReminder.setSelection(0);
+ break;
+ case 0:
+ mReminder.setSelection(1);
+ break;
+ default:
+ mReminder.setSelection(2);
+ mReminderOtherET.setVisibility(View.VISIBLE);
+ mReminderOtherET.setText(String.valueOf(mEvent.getReminderMinutes()));
+ break;
+ }
+ }
+
@OnItemSelected(R.id.event_reminder)
public void handleReminder() {
+ if (!mWasReminderInit) {
+ mWasReminderInit = true;
+ return;
+ }
+ if (mReminder.getSelectedItemPosition() == mReminder.getCount() - 1) {
+ mReminderOtherET.setVisibility(View.VISIBLE);
+ mReminderOtherET.requestFocus();
+ showKeyboard(mReminderOtherET);
+ } else {
+ mReminderOtherET.setVisibility(View.GONE);
+ hideKeyboard();
+ }
}
@Override
@@ -147,10 +190,12 @@ public class EventActivity extends AppCompatActivity implements DBHelper.DBOpera
final DBHelper dbHelper = DBHelper.newInstance(getApplicationContext(), this);
final String description = mDescriptionET.getText().toString().trim();
+ final int reminderMinutes = getReminderMinutes();
mEvent.setStartTS(startTS);
mEvent.setEndTS(endTS);
mEvent.setTitle(title);
mEvent.setDescription(description);
+ mEvent.setReminderMinutes(reminderMinutes);
if (mEvent.getId() == 0) {
dbHelper.insert(mEvent);
} else {
@@ -158,6 +203,21 @@ public class EventActivity extends AppCompatActivity implements DBHelper.DBOpera
}
}
+ private int getReminderMinutes() {
+ switch (mReminder.getSelectedItemPosition()) {
+ case 0:
+ return -1;
+ case 1:
+ return 0;
+ default:
+ final String value = mReminderOtherET.getText().toString().trim();
+ if (value.isEmpty())
+ return 0;
+
+ return Integer.valueOf(value);
+ }
+ }
+
private void updateStartDate() {
mStartDate.setText(Formatter.getEventDate(mEventStartDateTime));
}
@@ -245,14 +305,34 @@ public class EventActivity extends AppCompatActivity implements DBHelper.DBOpera
}
}
+ private void handleNotification(Event event) {
+ if (event.getReminderMinutes() == -1) {
+ return;
+ }
+
+ final long delayFromNow = (long) event.getStartTS() * 1000 - event.getReminderMinutes() * 60000 - System.currentTimeMillis();
+ if (delayFromNow < 0) {
+ return;
+ }
+
+ final long notifInMs = SystemClock.elapsedRealtime() + delayFromNow;
+ final Intent intent = new Intent(this, NotificationPublisher.class);
+ intent.putExtra(NotificationPublisher.EVENT_ID, event.getId());
+ final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, event.getId(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
+ alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, notifInMs, pendingIntent);
+ }
+
@Override
- public void eventInserted() {
+ public void eventInserted(Event event) {
+ handleNotification(event);
Utils.showToast(getApplicationContext(), R.string.event_added);
finish();
}
@Override
- public void eventUpdated() {
+ public void eventUpdated(Event event) {
+ handleNotification(event);
Utils.showToast(getApplicationContext(), R.string.event_updated);
finish();
}
diff --git a/app/src/main/java/com/simplemobiletools/calendar/activities/MainActivity.java b/app/src/main/java/com/simplemobiletools/calendar/activities/MainActivity.java
index 36db9568c..cdeeb9228 100644
--- a/app/src/main/java/com/simplemobiletools/calendar/activities/MainActivity.java
+++ b/app/src/main/java/com/simplemobiletools/calendar/activities/MainActivity.java
@@ -213,8 +213,10 @@ public class MainActivity extends AppCompatActivity implements Calendar {
private void setupLabels() {
for (int i = 0; i < 7; i++) {
final TextView dayTV = (TextView) findViewById(mRes.getIdentifier("label_" + i, "id", mPackageName));
- dayTV.setTextSize(mDayTextSize);
- dayTV.setTextColor(mWeakTextColor);
+ if (dayTV != null) {
+ dayTV.setTextSize(mDayTextSize);
+ dayTV.setTextColor(mWeakTextColor);
+ }
}
}
}
diff --git a/app/src/main/java/com/simplemobiletools/calendar/models/Event.java b/app/src/main/java/com/simplemobiletools/calendar/models/Event.java
index e326501de..4d0dd344a 100644
--- a/app/src/main/java/com/simplemobiletools/calendar/models/Event.java
+++ b/app/src/main/java/com/simplemobiletools/calendar/models/Event.java
@@ -4,11 +4,12 @@ import java.io.Serializable;
public class Event implements Serializable {
private static final long serialVersionUID = -32456795132354616L;
- private final int mId;
+ private int mId;
private int mStartTS;
private int mEndTS;
private String mTitle;
private String mDescription;
+ private int mReminderMinutes;
public Event() {
mId = 0;
@@ -16,20 +17,26 @@ public class Event implements Serializable {
mEndTS = 0;
mTitle = "";
mDescription = "";
+ mReminderMinutes = -1;
}
- public Event(int id, int startTS, int endTS, String title, String description) {
+ public Event(int id, int startTS, int endTS, String title, String description, int reminerMinutes) {
mId = id;
mStartTS = startTS;
mEndTS = endTS;
mTitle = title;
mDescription = description;
+ mReminderMinutes = reminerMinutes;
}
public int getId() {
return mId;
}
+ public void setId(int id) {
+ mId = id;
+ }
+
public int getStartTS() {
return mStartTS;
}
@@ -62,6 +69,14 @@ public class Event implements Serializable {
mDescription = description;
}
+ public int getReminderMinutes() {
+ return mReminderMinutes;
+ }
+
+ public void setReminderMinutes(int reminderMinutes) {
+ mReminderMinutes = reminderMinutes;
+ }
+
@Override
public String toString() {
return "Event {" +
@@ -70,6 +85,7 @@ public class Event implements Serializable {
", endTS=" + getEndTS() +
", title=" + getTitle() +
", description=" + getDescription() +
+ ", reminderMinutes=" + getReminderMinutes() +
"}";
}
}
diff --git a/app/src/main/res/layout/activity_event.xml b/app/src/main/res/layout/activity_event.xml
index ff78f1898..aee71c1b4 100644
--- a/app/src/main/res/layout/activity_event.xml
+++ b/app/src/main/res/layout/activity_event.xml
@@ -121,5 +121,17 @@
android:entries="@array/reminders"
android:padding="@dimen/activity_margin"/>
+
+
diff --git a/app/src/main/res/mipmap-hdpi/calendar.png b/app/src/main/res/mipmap-hdpi/calendar.png
new file mode 100644
index 000000000..fd7bdc0a5
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/calendar.png differ
diff --git a/app/src/main/res/mipmap-mdpi/calendar.png b/app/src/main/res/mipmap-mdpi/calendar.png
new file mode 100644
index 000000000..4ddb16ee0
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/calendar.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/calendar.png b/app/src/main/res/mipmap-xhdpi/calendar.png
new file mode 100644
index 000000000..2e3cd13c4
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/calendar.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/calendar.png b/app/src/main/res/mipmap-xxhdpi/calendar.png
new file mode 100644
index 000000000..0e3a7cf03
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/calendar.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/calendar.png b/app/src/main/res/mipmap-xxxhdpi/calendar.png
new file mode 100644
index 000000000..47247db25
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/calendar.png differ
diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml
index 17910c220..72a9e4262 100644
--- a/app/src/main/res/values/array.xml
+++ b/app/src/main/res/values/array.xml
@@ -3,7 +3,6 @@
- @string/off
- @string/at_start
- - @string/ten_mins
- - @string/thirty_mins
+ - @string/minutes_before
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 91798c74d..cac09c7d9 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -15,8 +15,7 @@
Reminder
Off
At start
- 10 mins before
- 30 mins before
+ Minutes before
Details
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index f39355514..99abf955b 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -50,6 +50,8 @@
- 20sp
+
+