├── TaskReminderApp.apk
├── res
├── drawable-hdpi
│ └── icon.png
├── drawable-ldpi
│ └── icon.png
├── drawable-mdpi
│ └── icon.png
├── menu
│ ├── list_menu_item_longpress.xml
│ └── list_menu.xml
├── layout
│ ├── reminder_row.xml
│ ├── reminder_list.xml
│ └── reminder_edit.xml
├── xml
│ └── task_preferences.xml
└── values
│ └── strings.xml
├── assets
└── fontawesome-webfont.ttf
├── gen
└── com
│ └── TechSect
│ └── TaskReminderApp
│ ├── R.java
│ ├── Manifest.java
│ └── BuildConfig.java
├── local.properties
├── project.properties
├── ant.properties
├── src
└── com
│ └── TechSect
│ └── TaskReminderApp
│ ├── TaskPreferences.java
│ ├── OnAlarmReceiver.java
│ ├── ReminderManager.java
│ ├── WakeReminderIntentService.java
│ ├── ReminderService.java
│ ├── OnBootReceiver.java
│ ├── ReminderListActivity.java
│ ├── RemindersDbAdapter.java
│ └── ReminderEditActivity.java
├── proguard-project.txt
├── LICENSE
├── README.md
└── AndroidManifest.xml
/TaskReminderApp.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hitenpratap/Task-Reminder-App/HEAD/TaskReminderApp.apk
--------------------------------------------------------------------------------
/res/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hitenpratap/Task-Reminder-App/HEAD/res/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/res/drawable-ldpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hitenpratap/Task-Reminder-App/HEAD/res/drawable-ldpi/icon.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hitenpratap/Task-Reminder-App/HEAD/res/drawable-mdpi/icon.png
--------------------------------------------------------------------------------
/assets/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hitenpratap/Task-Reminder-App/HEAD/assets/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/gen/com/TechSect/TaskReminderApp/R.java:
--------------------------------------------------------------------------------
1 | /*___Generated_by_IDEA___*/
2 |
3 | package com.TechSect.TaskReminderApp;
4 |
5 | /* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
6 | public final class R {
7 | }
--------------------------------------------------------------------------------
/gen/com/TechSect/TaskReminderApp/Manifest.java:
--------------------------------------------------------------------------------
1 | /*___Generated_by_IDEA___*/
2 |
3 | package com.TechSect.TaskReminderApp;
4 |
5 | /* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
6 | public final class Manifest {
7 | }
--------------------------------------------------------------------------------
/gen/com/TechSect/TaskReminderApp/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /*___Generated_by_IDEA___*/
2 |
3 | package com.TechSect.TaskReminderApp;
4 |
5 | /* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
6 | public final class BuildConfig {
7 | public final static boolean DEBUG = Boolean.parseBoolean(null);
8 | }
--------------------------------------------------------------------------------
/res/menu/list_menu_item_longpress.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
--------------------------------------------------------------------------------
/res/layout/reminder_row.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 |
7 | # location of the SDK. This is only used by Ant
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=/home/hitenpratap/android-sdk-linux
11 |
--------------------------------------------------------------------------------
/res/menu/list_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-14
15 | android.library.reference.1=../../Downloads/Android-Bootstrap-master/AndroidBootstrap
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ant.properties:
--------------------------------------------------------------------------------
1 | # This file is used to override default values used by the Ant build system.
2 | #
3 | # This file must be checked into Version Control Systems, as it is
4 | # integral to the build system of your project.
5 |
6 | # This file is only used by the Ant script.
7 |
8 | # You can use this to override default values such as
9 | # 'source.dir' for the location of your java source folder and
10 | # 'out.dir' for the location of your output folder.
11 |
12 | # You can also use it define how the release builds are signed by declaring
13 | # the following properties:
14 | # 'key.store' for the location of your keystore and
15 | # 'key.alias' for the name of the key to use.
16 | # The password will be asked during the build when you use the 'release' target.
17 |
18 |
--------------------------------------------------------------------------------
/res/layout/reminder_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
16 |
17 |
--------------------------------------------------------------------------------
/src/com/TechSect/TaskReminderApp/TaskPreferences.java:
--------------------------------------------------------------------------------
1 | package com.TechSect.TaskReminderApp;
2 |
3 | import android.os.Bundle;
4 | import android.preference.EditTextPreference;
5 | import android.preference.PreferenceActivity;
6 | import android.text.method.DigitsKeyListener;
7 |
8 | public class TaskPreferences extends PreferenceActivity {
9 | @Override
10 | protected void onCreate(Bundle savedInstanceState) {
11 | super.onCreate(savedInstanceState);
12 | addPreferencesFromResource(R.xml.task_preferences);
13 |
14 | // Set the time default to a numeric number only
15 | EditTextPreference timeDefault = (EditTextPreference) findPreference(getString(R.string.pref_default_time_from_now_key));
16 | timeDefault.getEditText().setKeyListener(DigitsKeyListener.getInstance());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/src/com/TechSect/TaskReminderApp/OnAlarmReceiver.java:
--------------------------------------------------------------------------------
1 | package com.TechSect.TaskReminderApp;
2 |
3 |
4 | import android.content.BroadcastReceiver;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.pm.ComponentInfo;
8 | import android.util.Log;
9 |
10 | public class OnAlarmReceiver extends BroadcastReceiver {
11 |
12 | private static final String TAG = ComponentInfo.class.getCanonicalName();
13 |
14 |
15 | @Override
16 | public void onReceive(Context context, Intent intent) {
17 | Log.d(TAG, "Received wake up from alarm manager.");
18 |
19 | long rowid = intent.getExtras().getLong(RemindersDbAdapter.KEY_ROWID);
20 |
21 | WakeReminderIntentService.acquireStaticLock(context);
22 |
23 | Intent i = new Intent(context, ReminderService.class);
24 | i.putExtra(RemindersDbAdapter.KEY_ROWID, rowid);
25 | context.startService(i);
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/com/TechSect/TaskReminderApp/ReminderManager.java:
--------------------------------------------------------------------------------
1 | package com.TechSect.TaskReminderApp;
2 |
3 | import java.util.Calendar;
4 |
5 | import android.app.AlarmManager;
6 | import android.app.PendingIntent;
7 | import android.content.Context;
8 | import android.content.Intent;
9 |
10 | public class ReminderManager {
11 |
12 | private Context mContext;
13 | private AlarmManager mAlarmManager;
14 |
15 | public ReminderManager(Context context) {
16 | mContext = context;
17 | mAlarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
18 | }
19 |
20 | public void setReminder(Long taskId, Calendar when) {
21 |
22 | Intent i = new Intent(mContext, OnAlarmReceiver.class);
23 | i.putExtra(RemindersDbAdapter.KEY_ROWID, (long)taskId);
24 |
25 | PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_ONE_SHOT);
26 |
27 | mAlarmManager.set(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), pi);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Hiten Pratap Singh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/src/com/TechSect/TaskReminderApp/WakeReminderIntentService.java:
--------------------------------------------------------------------------------
1 | package com.TechSect.TaskReminderApp;
2 |
3 | import android.app.IntentService;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.PowerManager;
7 |
8 | public abstract class WakeReminderIntentService extends IntentService {
9 | abstract void doReminderWork(Intent intent);
10 |
11 | public static final String LOCK_NAME_STATIC="com.dummies.android.taskreminder.Static";
12 | private static PowerManager.WakeLock lockStatic=null;
13 |
14 | public static void acquireStaticLock(Context context) {
15 | getLock(context).acquire();
16 | }
17 |
18 | synchronized private static PowerManager.WakeLock getLock(Context context) {
19 | if (lockStatic==null) {
20 | PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
21 | lockStatic=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
22 | LOCK_NAME_STATIC);
23 | lockStatic.setReferenceCounted(true);
24 | }
25 | return(lockStatic);
26 | }
27 |
28 | public WakeReminderIntentService(String name) {
29 | super(name);
30 | }
31 |
32 | @Override
33 | final protected void onHandleIntent(Intent intent) {
34 | try {
35 | doReminderWork(intent);
36 | }
37 | finally {
38 | getLock(this).release();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/res/xml/task_preferences.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
16 |
17 |
18 |
21 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Task Reminder Application for Android
2 | =========
3 |
4 | It's a Task reminder android application with many features like reminder about tasks etc.
5 |
6 |
7 | > Actually it's very unique and special for me bacuse it's my first Android application and i used many new things with it like:
8 |
9 | - Twitter Bootstrap Elements like EditText and Button etc.
10 | - Minimal duplicacy like same code for Add/Update task
11 | - and many more....
12 |
13 | I have full code for this app along with Twitter Bootsrap module in this repo. All you have to do is check it out.
14 |
15 | Version
16 | ----
17 |
18 | 1.0.0
19 |
20 | Tech
21 | -----------
22 |
23 | This App uses a number of Tools to work properly:
24 |
25 | * [IntelliJ Idea](http://www.jetbrains.com/idea/download/) - Best Java IDE for Java beased techs
26 | * [ANdroid SDK](https://developer.android.com/sdk/index.html?hl=i) - Android SDK
27 | * [Twitter Bootstrap](http://getbootstrap.com/) - For Android Element like EditText and Button etc
28 | * [Java](https://java.com/en/download/index.jsp) - Java SE 1.7
29 | * [Git](http://git-scm.com/) - Best S/W versioning tool
30 |
31 | Installation
32 | --------------
33 | * [Task Reminder APK](https://github.com/hitenpratap/Task-Reminder-App/blob/master/TaskReminderApp.apk?raw=true) - Just download it from here and enjoy.
34 |
35 | ```
36 | Just download the app from repo and install it on your android device.
37 | ```
38 |
39 | **Open Source Software, Hell Yeah!**
40 |
--------------------------------------------------------------------------------
/src/com/TechSect/TaskReminderApp/ReminderService.java:
--------------------------------------------------------------------------------
1 | package com.TechSect.TaskReminderApp;
2 |
3 | import android.app.Notification;
4 | import android.app.NotificationManager;
5 | import android.app.PendingIntent;
6 | import android.content.Intent;
7 | import android.util.Log;
8 |
9 | public class ReminderService extends WakeReminderIntentService {
10 |
11 | public ReminderService() {
12 | super("ReminderService");
13 | }
14 |
15 | @Override
16 | void doReminderWork(Intent intent) {
17 | Log.d("ReminderService", "Doing work.");
18 | Long rowId = intent.getExtras().getLong(RemindersDbAdapter.KEY_ROWID);
19 |
20 | NotificationManager mgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
21 |
22 | Intent notificationIntent = new Intent(this, ReminderEditActivity.class);
23 | notificationIntent.putExtra(RemindersDbAdapter.KEY_ROWID, rowId);
24 |
25 | PendingIntent pi = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT);
26 |
27 | Notification note=new Notification(android.R.drawable.stat_sys_warning, getString(R.string.notify_new_task_message), System.currentTimeMillis());
28 | note.setLatestEventInfo(this, getString(R.string.notify_new_task_title), getString(R.string.notify_new_task_message), pi);
29 | note.defaults |= Notification.DEFAULT_SOUND;
30 | note.flags |= Notification.FLAG_AUTO_CANCEL;
31 |
32 | // An issue could occur if user ever enters over 2,147,483,647 tasks. (Max int value).
33 | // I highly doubt this will ever happen. But is good to note.
34 | int id = (int)((long)rowId);
35 | mgr.notify(id, note);
36 |
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
9 |
10 |
11 |
12 |
13 |
14 |
16 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/com/TechSect/TaskReminderApp/OnBootReceiver.java:
--------------------------------------------------------------------------------
1 | package com.TechSect.TaskReminderApp;
2 |
3 | import java.text.SimpleDateFormat;
4 | import java.util.Calendar;
5 |
6 | import android.content.BroadcastReceiver;
7 | import android.content.Context;
8 | import android.content.Intent;
9 | import android.content.pm.ComponentInfo;
10 | import android.database.Cursor;
11 | import android.util.Log;
12 |
13 | public class OnBootReceiver extends BroadcastReceiver {
14 |
15 | private static final String TAG = ComponentInfo.class.getCanonicalName();
16 |
17 | @Override
18 | public void onReceive(Context context, Intent intent) {
19 |
20 | ReminderManager reminderMgr = new ReminderManager(context);
21 |
22 | RemindersDbAdapter dbHelper = new RemindersDbAdapter(context);
23 | dbHelper.open();
24 |
25 | Cursor cursor = dbHelper.fetchAllReminders();
26 |
27 | if(cursor != null) {
28 | cursor.moveToFirst();
29 |
30 | int rowIdColumnIndex = cursor.getColumnIndex(RemindersDbAdapter.KEY_ROWID);
31 | int dateTimeColumnIndex = cursor.getColumnIndex(RemindersDbAdapter.KEY_DATE_TIME);
32 |
33 | while(cursor.isAfterLast() == false) {
34 |
35 | Log.d(TAG, "Adding alarm from boot.");
36 | Log.d(TAG, "Row Id Column Index - " + rowIdColumnIndex);
37 | Log.d(TAG, "Date Time Column Index - " + dateTimeColumnIndex);
38 |
39 | Long rowId = cursor.getLong(rowIdColumnIndex);
40 | String dateTime = cursor.getString(dateTimeColumnIndex);
41 |
42 | Calendar cal = Calendar.getInstance();
43 | SimpleDateFormat format = new SimpleDateFormat(ReminderEditActivity.DATE_TIME_FORMAT);
44 |
45 | try {
46 | java.util.Date date = format.parse(dateTime);
47 | cal.setTime(date);
48 |
49 | reminderMgr.setReminder(rowId, cal);
50 | } catch (java.text.ParseException e) {
51 | Log.e("OnBootReceiver", e.getMessage(), e);
52 | }
53 |
54 | cursor.moveToNext();
55 | }
56 | cursor.close() ;
57 | }
58 |
59 | dbHelper.close();
60 | }
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Task Reminder
4 | Task Reminder - Edit
5 | No Reminders Yet
6 | Add Reminder
7 | Delete Reminder
8 | Settings
9 | Title
10 | Body
11 | Save
12 | Edit Reminder
13 | Reminder Date
14 | Reminder Time
15 |
16 |
17 | Task has been saved
18 |
19 |
20 | A task needs to be reviewed!
21 | Task Reminder!
22 |
23 |
24 | task_default_category
25 | Task Title Default
26 | default_reminder_title
27 | Default Reminder Title
28 | The default title for a reminder.
29 | Default title for reminders.
30 | Default Reminder Title
31 |
32 | date_time_default_category
33 | Date Time Defaults
34 | time_from_now_default
35 | Time From Now
36 | The default time from now that a new reminder should be set to.
37 | Sets the default time for a reminder.
38 | Default Reminder Time
39 |
40 |
41 |
--------------------------------------------------------------------------------
/res/layout/reminder_edit.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
12 |
15 |
16 |
17 |
18 |
19 |
29 |
32 |
33 |
34 |
35 |
36 |
37 |
48 |
51 |
56 |
59 |
64 |
65 |
66 |
67 |
68 |
69 |
79 |
80 |
--------------------------------------------------------------------------------
/src/com/TechSect/TaskReminderApp/ReminderListActivity.java:
--------------------------------------------------------------------------------
1 |
2 | package com.TechSect.TaskReminderApp;
3 |
4 |
5 | import android.app.ListActivity;
6 | import android.content.Intent;
7 | import android.database.Cursor;
8 | import android.os.Bundle;
9 | import android.view.ContextMenu;
10 | import android.view.Menu;
11 | import android.view.MenuInflater;
12 | import android.view.MenuItem;
13 | import android.view.View;
14 | import android.view.ContextMenu.ContextMenuInfo;
15 | import android.widget.ListView;
16 | import android.widget.SimpleCursorAdapter;
17 | import android.widget.AdapterView.AdapterContextMenuInfo;
18 |
19 | public class ReminderListActivity extends ListActivity {
20 | private static final int ACTIVITY_CREATE=0;
21 | private static final int ACTIVITY_EDIT=1;
22 |
23 | private RemindersDbAdapter mDbHelper;
24 |
25 | /** Called when the activity is first created. */
26 | @Override
27 | public void onCreate(Bundle savedInstanceState) {
28 | super.onCreate(savedInstanceState);
29 | setContentView(R.layout.reminder_list);
30 | mDbHelper = new RemindersDbAdapter(this);
31 | mDbHelper.open();
32 | fillData();
33 | registerForContextMenu(getListView());
34 |
35 | }
36 |
37 |
38 | private void fillData() {
39 | Cursor remindersCursor = mDbHelper.fetchAllReminders();
40 | startManagingCursor(remindersCursor);
41 |
42 | // Create an array to specify the fields we want to display in the list (only TITLE)
43 | String[] from = new String[]{RemindersDbAdapter.KEY_TITLE};
44 |
45 | // and an array of the fields we want to bind those fields to (in this case just text1)
46 | int[] to = new int[]{R.id.text1};
47 |
48 | // Now create a simple cursor adapter and set it to display
49 | SimpleCursorAdapter reminders =
50 | new SimpleCursorAdapter(this, R.layout.reminder_row, remindersCursor, from, to);
51 | setListAdapter(reminders);
52 | }
53 |
54 | @Override
55 | public boolean onCreateOptionsMenu(Menu menu) {
56 | super.onCreateOptionsMenu(menu);
57 | MenuInflater mi = getMenuInflater();
58 | mi.inflate(R.menu.list_menu, menu);
59 | return true;
60 | }
61 |
62 | @Override
63 | public boolean onMenuItemSelected(int featureId, MenuItem item) {
64 | switch(item.getItemId()) {
65 | case R.id.menu_insert:
66 | createReminder();
67 | return true;
68 | case R.id.menu_settings:
69 | Intent i = new Intent(this, TaskPreferences.class);
70 | startActivity(i);
71 | return true;
72 | }
73 |
74 | return super.onMenuItemSelected(featureId, item);
75 | }
76 |
77 | @Override
78 | public void onCreateContextMenu(ContextMenu menu, View v,
79 | ContextMenuInfo menuInfo) {
80 | super.onCreateContextMenu(menu, v, menuInfo);
81 | MenuInflater mi = getMenuInflater();
82 | mi.inflate(R.menu.list_menu_item_longpress, menu);
83 | }
84 |
85 | @Override
86 | public boolean onContextItemSelected(MenuItem item) {
87 | switch(item.getItemId()) {
88 | case R.id.menu_delete:
89 | AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
90 | mDbHelper.deleteReminder(info.id);
91 | fillData();
92 | return true;
93 | }
94 | return super.onContextItemSelected(item);
95 | }
96 |
97 | private void createReminder() {
98 | Intent i = new Intent(this, ReminderEditActivity.class);
99 | startActivityForResult(i, ACTIVITY_CREATE);
100 | }
101 |
102 | @Override
103 | protected void onListItemClick(ListView l, View v, int position, long id) {
104 | super.onListItemClick(l, v, position, id);
105 | Intent i = new Intent(this, ReminderEditActivity.class);
106 | i.putExtra(RemindersDbAdapter.KEY_ROWID, id);
107 | startActivityForResult(i, ACTIVITY_EDIT);
108 | }
109 |
110 | @Override
111 | protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
112 | super.onActivityResult(requestCode, resultCode, intent);
113 | fillData();
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/com/TechSect/TaskReminderApp/RemindersDbAdapter.java:
--------------------------------------------------------------------------------
1 |
2 | package com.TechSect.TaskReminderApp;
3 |
4 | import android.content.ContentValues;
5 | import android.content.Context;
6 | import android.database.Cursor;
7 | import android.database.SQLException;
8 | import android.database.sqlite.SQLiteDatabase;
9 | import android.database.sqlite.SQLiteOpenHelper;
10 | import android.util.Log;
11 |
12 | /**
13 | * Simple reminder database access helper class.
14 | * Defines the basic CRUD operations (Create, Read, Update, Delete)
15 | * for the example, and gives the ability to list all reminders as well as
16 | * retrieve or modify a specific reminder.
17 | *
18 | */
19 | public class RemindersDbAdapter {
20 |
21 | //
22 | // Databsae Related Constants
23 | //
24 | private static final String DATABASE_NAME = "data";
25 | private static final String DATABASE_TABLE = "reminders";
26 | private static final int DATABASE_VERSION = 3;
27 |
28 | public static final String KEY_TITLE = "title";
29 | public static final String KEY_BODY = "body";
30 | public static final String KEY_DATE_TIME = "reminder_date_time";
31 | public static final String KEY_ROWID = "_id";
32 |
33 |
34 | private static final String TAG = "ReminderDbAdapter";
35 | private DatabaseHelper mDbHelper;
36 | private SQLiteDatabase mDb;
37 |
38 | /**
39 | * Database creation SQL statement
40 | */
41 | private static final String DATABASE_CREATE =
42 | "create table " + DATABASE_TABLE + " ("
43 | + KEY_ROWID + " integer primary key autoincrement, "
44 | + KEY_TITLE + " text not null, "
45 | + KEY_BODY + " text not null, "
46 | + KEY_DATE_TIME + " text not null);";
47 |
48 |
49 |
50 | private final Context mCtx;
51 |
52 | private static class DatabaseHelper extends SQLiteOpenHelper {
53 |
54 | DatabaseHelper(Context context) {
55 | super(context, DATABASE_NAME, null, DATABASE_VERSION);
56 | }
57 |
58 | @Override
59 | public void onCreate(SQLiteDatabase db) {
60 |
61 | db.execSQL(DATABASE_CREATE);
62 | }
63 |
64 | @Override
65 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
66 | Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
67 | + newVersion + ", which will destroy all old data");
68 | db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
69 | onCreate(db);
70 | }
71 | }
72 |
73 | /**
74 | * Constructor - takes the context to allow the database to be
75 | * opened/created
76 | *
77 | * @param ctx the Context within which to work
78 | */
79 | public RemindersDbAdapter(Context ctx) {
80 | this.mCtx = ctx;
81 | }
82 |
83 | /**
84 | * Open the database. If it cannot be opened, try to create a new
85 | * instance of the database. If it cannot be created, throw an exception to
86 | * signal the failure
87 | *
88 | * @return this (self reference, allowing this to be chained in an
89 | * initialization call)
90 | * @throws SQLException if the database could be neither opened or created
91 | */
92 | public RemindersDbAdapter open() throws SQLException {
93 | mDbHelper = new DatabaseHelper(mCtx);
94 | mDb = mDbHelper.getWritableDatabase();
95 | return this;
96 | }
97 |
98 | public void close() {
99 | mDbHelper.close();
100 | }
101 |
102 |
103 | /**
104 | * Create a new reminder using the title, body and reminder date time provided.
105 | * If the reminder is successfully created return the new rowId
106 | * for that reminder, otherwise return a -1 to indicate failure.
107 | *
108 | * @param title the title of the reminder
109 | * @param body the body of the reminder
110 | * @param reminderDateTime the date and time the reminder should remind the user
111 | * @return rowId or -1 if failed
112 | */
113 | public long createReminder(String title, String body, String reminderDateTime) {
114 | ContentValues initialValues = new ContentValues();
115 | initialValues.put(KEY_TITLE, title);
116 | initialValues.put(KEY_BODY, body);
117 | initialValues.put(KEY_DATE_TIME, reminderDateTime);
118 |
119 | return mDb.insert(DATABASE_TABLE, null, initialValues);
120 | }
121 |
122 | /**
123 | * Delete the reminder with the given rowId
124 | *
125 | * @param rowId id of reminder to delete
126 | * @return true if deleted, false otherwise
127 | */
128 | public boolean deleteReminder(long rowId) {
129 |
130 | return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
131 | }
132 |
133 | /**
134 | * Return a Cursor over the list of all reminders in the database
135 | *
136 | * @return Cursor over all reminders
137 | */
138 | public Cursor fetchAllReminders() {
139 |
140 | return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TITLE,
141 | KEY_BODY, KEY_DATE_TIME}, null, null, null, null, null);
142 | }
143 |
144 | /**
145 | * Return a Cursor positioned at the reminder that matches the given rowId
146 | *
147 | * @param rowId id of reminder to retrieve
148 | * @return Cursor positioned to matching reminder, if found
149 | * @throws SQLException if reminder could not be found/retrieved
150 | */
151 | public Cursor fetchReminder(long rowId) throws SQLException {
152 |
153 | Cursor mCursor =
154 |
155 | mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
156 | KEY_TITLE, KEY_BODY, KEY_DATE_TIME}, KEY_ROWID + "=" + rowId, null,
157 | null, null, null, null);
158 | if (mCursor != null) {
159 | mCursor.moveToFirst();
160 | }
161 | return mCursor;
162 |
163 | }
164 |
165 | /**
166 | * Update the reminder using the details provided. The reminder to be updated is
167 | * specified using the rowId, and it is altered to use the title, body and reminder date time
168 | * values passed in
169 | *
170 | * @param rowId id of reminder to update
171 | * @param title value to set reminder title to
172 | * @param body value to set reminder body to
173 | * @param reminderDateTime value to set the reminder time.
174 | * @return true if the reminder was successfully updated, false otherwise
175 | */
176 | public boolean updateReminder(long rowId, String title, String body, String reminderDateTime) {
177 | ContentValues args = new ContentValues();
178 | args.put(KEY_TITLE, title);
179 | args.put(KEY_BODY, body);
180 | args.put(KEY_DATE_TIME, reminderDateTime);
181 |
182 | return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/src/com/TechSect/TaskReminderApp/ReminderEditActivity.java:
--------------------------------------------------------------------------------
1 |
2 | package com.TechSect.TaskReminderApp;
3 |
4 | import java.text.ParseException;
5 | import java.text.SimpleDateFormat;
6 | import java.util.Calendar;
7 | import java.util.Date;
8 |
9 | import android.app.Activity;
10 | import android.app.DatePickerDialog;
11 | import android.app.Dialog;
12 | import android.app.TimePickerDialog;
13 | import android.content.SharedPreferences;
14 | import android.database.Cursor;
15 | import android.os.Bundle;
16 | import android.preference.PreferenceManager;
17 | import android.util.Log;
18 | import android.view.View;
19 | import android.widget.Button;
20 | import android.widget.DatePicker;
21 | import android.widget.EditText;
22 | import android.widget.TimePicker;
23 | import android.widget.Toast;
24 | import com.beardedhen.androidbootstrap.BootstrapButton;
25 | import com.beardedhen.androidbootstrap.BootstrapEditText;
26 |
27 | public class ReminderEditActivity extends Activity {
28 |
29 | //
30 | // Dialog Constants
31 | //
32 | private static final int DATE_PICKER_DIALOG = 0;
33 | private static final int TIME_PICKER_DIALOG = 1;
34 |
35 | //
36 | // Date Format
37 | //
38 | private static final String DATE_FORMAT = "yyyy-MM-dd";
39 | private static final String TIME_FORMAT = "kk:mm";
40 | public static final String DATE_TIME_FORMAT = "yyyy-MM-dd kk:mm:ss";
41 |
42 | private BootstrapEditText mTitleText;
43 | private BootstrapEditText mBodyText;
44 | private Button mDateButton;
45 | private Button mTimeButton;
46 | private BootstrapButton mConfirmButton;
47 | private Long mRowId;
48 | private RemindersDbAdapter mDbHelper;
49 | private Calendar mCalendar;
50 |
51 | @Override
52 | protected void onCreate(Bundle savedInstanceState) {
53 | super.onCreate(savedInstanceState);
54 |
55 | mDbHelper = new RemindersDbAdapter(this);
56 |
57 | setContentView(R.layout.reminder_edit);
58 |
59 | mCalendar = Calendar.getInstance();
60 | mTitleText = (BootstrapEditText) findViewById(R.id.title);
61 | mBodyText = (BootstrapEditText) findViewById(R.id.body);
62 | mDateButton = (Button) findViewById(R.id.reminder_date);
63 | mTimeButton = (Button) findViewById(R.id.reminder_time);
64 |
65 | mConfirmButton = (BootstrapButton) findViewById(R.id.confirm);
66 |
67 | mRowId = savedInstanceState != null ? savedInstanceState.getLong(RemindersDbAdapter.KEY_ROWID)
68 | : null;
69 |
70 | registerButtonListenersAndSetDefaultText();
71 | }
72 |
73 | private void setRowIdFromIntent() {
74 | if (mRowId == null) {
75 | Bundle extras = getIntent().getExtras();
76 | mRowId = extras != null ? extras.getLong(RemindersDbAdapter.KEY_ROWID)
77 | : null;
78 |
79 | }
80 | }
81 |
82 | @Override
83 | protected void onPause() {
84 | super.onPause();
85 | mDbHelper.close();
86 | }
87 |
88 | @Override
89 | protected void onResume() {
90 | super.onResume();
91 | mDbHelper.open();
92 | setRowIdFromIntent();
93 | populateFields();
94 | }
95 |
96 | @Override
97 | protected Dialog onCreateDialog(int id) {
98 | switch(id) {
99 | case DATE_PICKER_DIALOG:
100 | return showDatePicker();
101 | case TIME_PICKER_DIALOG:
102 | return showTimePicker();
103 | }
104 | return super.onCreateDialog(id);
105 | }
106 |
107 | private DatePickerDialog showDatePicker() {
108 |
109 |
110 | DatePickerDialog datePicker = new DatePickerDialog(ReminderEditActivity.this, new DatePickerDialog.OnDateSetListener() {
111 |
112 | @Override
113 | public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
114 | mCalendar.set(Calendar.YEAR, year);
115 | mCalendar.set(Calendar.MONTH, monthOfYear);
116 | mCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
117 | updateDateButtonText();
118 | }
119 | }, mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH));
120 | return datePicker;
121 | }
122 |
123 | private TimePickerDialog showTimePicker() {
124 |
125 | TimePickerDialog timePicker = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
126 |
127 | @Override
128 | public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
129 | mCalendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
130 | mCalendar.set(Calendar.MINUTE, minute);
131 | updateTimeButtonText();
132 | }
133 | }, mCalendar.get(Calendar.HOUR_OF_DAY), mCalendar.get(Calendar.MINUTE), true);
134 |
135 | return timePicker;
136 | }
137 |
138 | private void registerButtonListenersAndSetDefaultText() {
139 |
140 | mDateButton.setOnClickListener(new View.OnClickListener() {
141 |
142 | @Override
143 | public void onClick(View v) {
144 | showDialog(DATE_PICKER_DIALOG);
145 | }
146 | });
147 |
148 |
149 | mTimeButton.setOnClickListener(new View.OnClickListener() {
150 |
151 | @Override
152 | public void onClick(View v) {
153 | showDialog(TIME_PICKER_DIALOG);
154 | }
155 | });
156 |
157 | mConfirmButton.setOnClickListener(new View.OnClickListener() {
158 | public void onClick(View view) {
159 | saveState();
160 | setResult(RESULT_OK);
161 | Toast.makeText(ReminderEditActivity.this, getString(R.string.task_saved_message), Toast.LENGTH_SHORT).show();
162 | finish();
163 | }
164 |
165 | });
166 |
167 | updateDateButtonText();
168 | updateTimeButtonText();
169 | }
170 |
171 | private void populateFields() {
172 |
173 |
174 |
175 | // Only populate the text boxes and change the calendar date
176 | // if the row is not null from the database.
177 | if (mRowId != null) {
178 | Cursor reminder = mDbHelper.fetchReminder(mRowId);
179 | startManagingCursor(reminder);
180 | mTitleText.setText(reminder.getString(
181 | reminder.getColumnIndexOrThrow(RemindersDbAdapter.KEY_TITLE)));
182 | mBodyText.setText(reminder.getString(
183 | reminder.getColumnIndexOrThrow(RemindersDbAdapter.KEY_BODY)));
184 |
185 |
186 | // Get the date from the database and format it for our use.
187 | SimpleDateFormat dateTimeFormat = new SimpleDateFormat(DATE_TIME_FORMAT);
188 | Date date = null;
189 | try {
190 | String dateString = reminder.getString(reminder.getColumnIndexOrThrow(RemindersDbAdapter.KEY_DATE_TIME));
191 | date = dateTimeFormat.parse(dateString);
192 | mCalendar.setTime(date);
193 | } catch (ParseException e) {
194 | Log.e("ReminderEditActivity", e.getMessage(), e);
195 | }
196 | } else {
197 | // This is a new task - add defaults from preferences if set.
198 | SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
199 | String defaultTitleKey = getString(R.string.pref_task_title_key);
200 | String defaultTimeKey = getString(R.string.pref_default_time_from_now_key);
201 |
202 | String defaultTitle = prefs.getString(defaultTitleKey, null);
203 | String defaultTime = prefs.getString(defaultTimeKey, null);
204 |
205 | if(defaultTitle != null)
206 | mTitleText.setText(defaultTitle);
207 |
208 | if(defaultTime != null)
209 | mCalendar.add(Calendar.MINUTE, Integer.parseInt(defaultTime));
210 |
211 | }
212 |
213 | updateDateButtonText();
214 | updateTimeButtonText();
215 |
216 | }
217 |
218 | private void updateTimeButtonText() {
219 | // Set the time button text based upon the value from the database
220 | SimpleDateFormat timeFormat = new SimpleDateFormat(TIME_FORMAT);
221 | String timeForButton = timeFormat.format(mCalendar.getTime());
222 | mTimeButton.setText(timeForButton);
223 | }
224 |
225 | private void updateDateButtonText() {
226 | // Set the date button text based upon the value from the database
227 | SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
228 | String dateForButton = dateFormat.format(mCalendar.getTime());
229 | mDateButton.setText(dateForButton);
230 | }
231 |
232 | @Override
233 | protected void onSaveInstanceState(Bundle outState) {
234 | super.onSaveInstanceState(outState);
235 | outState.putLong(RemindersDbAdapter.KEY_ROWID, mRowId);
236 | }
237 |
238 |
239 |
240 | private void saveState() {
241 | String title = mTitleText.getText().toString();
242 | String body = mBodyText.getText().toString();
243 |
244 | SimpleDateFormat dateTimeFormat = new SimpleDateFormat(DATE_TIME_FORMAT);
245 | String reminderDateTime = dateTimeFormat.format(mCalendar.getTime());
246 |
247 | if (mRowId == null) {
248 |
249 | long id = mDbHelper.createReminder(title, body, reminderDateTime);
250 | if (id > 0) {
251 | mRowId = id;
252 | }
253 | } else {
254 | mDbHelper.updateReminder(mRowId, title, body, reminderDateTime);
255 | }
256 |
257 | new ReminderManager(this).setReminder(mRowId, mCalendar);
258 | }
259 |
260 | }
261 |
--------------------------------------------------------------------------------