Talking Reminder
this project is intenfed for people who are not tech savvy
ReminderAddActivity.java
1 package com.sudogeeks.talking_reminder;
2 
3 import android.Manifest;
4 import android.app.AlertDialog;
5 import android.app.DatePickerDialog;
6 import android.app.TimePickerDialog;
7 import android.content.Context;
8 import android.content.DialogInterface;
9 import android.content.Intent;
10 import android.content.pm.PackageManager;
11 import android.net.Uri;
12 import android.os.Bundle;
13 import android.os.Environment;
14 import android.text.Editable;
15 import android.text.InputType;
16 import android.text.TextWatcher;
17 import android.view.Menu;
18 import android.view.MenuItem;
19 import android.view.View;
20 import android.widget.DatePicker;
21 import android.widget.EditText;
22 import android.widget.Switch;
23 import android.widget.TextView;
24 import android.widget.TimePicker;
25 import android.widget.Toast;
26 
27 import androidx.appcompat.app.AppCompatActivity;
28 import androidx.appcompat.widget.Toolbar;
29 import androidx.core.app.ActivityCompat;
30 import androidx.core.content.ContextCompat;
31 import androidx.core.content.FileProvider;
32 
33 import com.google.android.material.floatingactionbutton.FloatingActionButton;
34 import com.google.firebase.auth.FirebaseAuth;
35 import com.google.firebase.auth.FirebaseUser;
36 import com.google.firebase.database.DatabaseReference;
37 import com.google.firebase.database.FirebaseDatabase;
38 import com.google.gson.Gson;
39 import com.google.gson.GsonBuilder;
40 
41 import java.io.File;
42 import java.io.FileOutputStream;
43 import java.util.Calendar;
44 
48 public class ReminderAddActivity extends AppCompatActivity {
49 
50  // Values for orientation change
51  private static final String KEY_TITLE = "title_key";
52  private static final String KEY_TIME = "time_key";
53  private static final String KEY_DATE = "date_key";
54  private static final String KEY_REPEAT = "repeat_key";
55  private static final String KEY_REPEAT_NO = "repeat_no_key";
56  private static final String KEY_REPEAT_TYPE = "repeat_type_key";
57  private static final String KEY_ACTIVE = "active_key";
58  // Constant values in milliseconds
59  private static final long milMinute = 60000L;
60  private static final long milHour = 3600000L;
61  private static final long milDay = 86400000L;
62  private static final long milWeek = 604800000L;
63  private static final long milMonth = 2592000000L;
64  private static final int MY_PERMISSIONS_REQUEST_WRITE_CONTACTS = 1;
65  private Toolbar mToolbar;
66  private EditText mTitleText;
67  private TextView mDateText, mTimeText, mRepeatText, mRepeatNoText, mRepeatTypeText;
68  private FloatingActionButton mFAB1;
69  private FloatingActionButton mFAB2;
70  private Calendar mCalendar;
71  private int mYear, mMonth, mHour, mMinute, mDay;
72  private long mRepeatTime;
73  private String mTitle;
74  private String mTime;
75  private String mDate;
76  private String mRepeat;
77  private String mRepeatNo;
78  private String mRepeatType;
79  private String mActive;
80 
81  private FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
82  private FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
83  private DatabaseReference dbReference = firebaseDatabase.getReference().child("reminders");
84 
89  @Override
90  protected void onCreate(Bundle savedInstanceState) {
91  super.onCreate(savedInstanceState);
92  setContentView(R.layout.activity_add_reminder);
93 
94  // Initialize Views
95  mToolbar = findViewById(R.id.toolbar);
96  mTitleText = findViewById(R.id.reminder_title);
97  mDateText = findViewById(R.id.set_date);
98  mTimeText = findViewById(R.id.set_time);
99  mRepeatText = findViewById(R.id.set_repeat);
100  mRepeatNoText = findViewById(R.id.set_repeat_no);
101  mRepeatTypeText = findViewById(R.id.set_repeat_type);
102  mFAB1 = findViewById(R.id.starred1);
103  mFAB2 = findViewById(R.id.starred2);
104 
105  // Setup Toolbar
106  setSupportActionBar(mToolbar);
107  getSupportActionBar().setTitle(R.string.activity_add_reminder_label);
108  getSupportActionBar().setDisplayHomeAsUpEnabled(true);
109  getSupportActionBar().setHomeButtonEnabled(true);
110 
111  // Initialize default values
112  mActive = "true";
113  mRepeat = "true";
114  mRepeatNo = Integer.toString(1);
115  mRepeatType = "Hour";
116 
117  mCalendar = Calendar.getInstance();
118  mHour = mCalendar.get(Calendar.HOUR_OF_DAY);
119  mMinute = mCalendar.get(Calendar.MINUTE);
120  mYear = mCalendar.get(Calendar.YEAR);
121  mMonth = mCalendar.get(Calendar.MONTH) + 1;
122  mDay = mCalendar.get(Calendar.DATE);
123 
124  mDate = mDay + "/" + mMonth + "/" + mYear;
125  mTime = mHour + ":" + mMinute;
126 
127  // Setup ReminderDO Title EditText
128  mTitleText.addTextChangedListener(new TextWatcher() {
129 
130  @Override
131  public void beforeTextChanged(CharSequence s, int start, int count, int after) {
132  }
133 
134  @Override
135  public void onTextChanged(CharSequence s, int start, int before, int count) {
136  mTitle = s.toString().trim();
137  mTitleText.setError(null);
138  }
139 
140  @Override
141  public void afterTextChanged(Editable s) {
142  }
143  });
144 
145  // Setup TextViews using reminder values
146  mDateText.setText(mDate);
147  mTimeText.setText(mTime);
148  mRepeatNoText.setText(mRepeatNo);
149  mRepeatTypeText.setText(mRepeatType);
150  mRepeatText.setText("Every " + mRepeatNo + " " + mRepeatType + "(s)");
151 
152  // To save state on device rotation
153  if (savedInstanceState != null) {
154  String savedTitle = savedInstanceState.getString(KEY_TITLE);
155  mTitleText.setText(savedTitle);
156  mTitle = savedTitle;
157 
158  String savedTime = savedInstanceState.getString(KEY_TIME);
159  mTimeText.setText(savedTime);
160  mTime = savedTime;
161 
162  String savedDate = savedInstanceState.getString(KEY_DATE);
163  mDateText.setText(savedDate);
164  mDate = savedDate;
165 
166  String saveRepeat = savedInstanceState.getString(KEY_REPEAT);
167  mRepeatText.setText(saveRepeat);
168  mRepeat = saveRepeat;
169 
170  String savedRepeatNo = savedInstanceState.getString(KEY_REPEAT_NO);
171  mRepeatNoText.setText(savedRepeatNo);
172  mRepeatNo = savedRepeatNo;
173 
174  String savedRepeatType = savedInstanceState.getString(KEY_REPEAT_TYPE);
175  mRepeatTypeText.setText(savedRepeatType);
176  mRepeatType = savedRepeatType;
177 
178  mActive = savedInstanceState.getString(KEY_ACTIVE);
179  }
180 
181  // Setup up active buttons
182  if (mActive.equals("false")) {
183  mFAB1.show();
184  mFAB2.hide();
185 
186  } else if (mActive.equals("true")) {
187  mFAB1.hide();
188  mFAB2.show();
189  }
190  }
191 
192  // To save state on device rotation
193  @Override
194  protected void onSaveInstanceState(Bundle outState) {
195  super.onSaveInstanceState(outState);
196 
197  outState.putCharSequence(KEY_TITLE, mTitleText.getText());
198  outState.putCharSequence(KEY_TIME, mTimeText.getText());
199  outState.putCharSequence(KEY_DATE, mDateText.getText());
200  outState.putCharSequence(KEY_REPEAT, mRepeatText.getText());
201  outState.putCharSequence(KEY_REPEAT_NO, mRepeatNoText.getText());
202  outState.putCharSequence(KEY_REPEAT_TYPE, mRepeatTypeText.getText());
203  outState.putCharSequence(KEY_ACTIVE, mActive);
204  }
205 
211  public void setTime(View v) {
212  Calendar now = Calendar.getInstance();
213  TimePickerDialog timePickerDialog = new TimePickerDialog(this,
214  new TimePickerDialog.OnTimeSetListener() {
215 
216  @Override
217  public void onTimeSet(TimePicker timePicker, int hourOfDay,
218  int minute) {
219 
220  mHour = hourOfDay;
221  mMinute = minute;
222  if (minute < 10) {
223  mTime = hourOfDay + ":" + "0" + minute;
224  } else {
225  mTime = hourOfDay + ":" + minute;
226  }
227  mTimeText.setText(mTime);
228  }
229  }, mHour, mMinute, false);
230  timePickerDialog.show();
231  }
232 
238  public void setDate(View v) {
239  Calendar now = Calendar.getInstance();
240  DatePickerDialog datePickerDialog = new DatePickerDialog(this,
241  new DatePickerDialog.OnDateSetListener() {
242 
243  @Override
244  public void onDateSet(DatePicker datePicker, int year,
245  int monthOfYear, int dayOfMonth) {
246 
247  mDay = dayOfMonth;
248  mMonth = monthOfYear + 1;
249  mYear = year;
250  mDate = mDay + "/" + mMonth + "/" + mYear;
251  mDateText.setText(mDate);
252  //mMonth = monthOfYear+1;
253  }
254  }, mYear, mMonth, mDay);
255  datePickerDialog.show();
256  }
257 
258 
259 
260 
261  public void selectFab1(View v) {
262  mFAB1 = findViewById(R.id.starred1);
263  mFAB1.hide();
264  mFAB2 = findViewById(R.id.starred2);
265  mFAB2.show();
266  mActive = "true";
267  }
268 
269  // On clicking the inactive button
270  public void selectFab2(View v) {
271  mFAB2 = findViewById(R.id.starred2);
272  mFAB2.hide();
273  mFAB1 = findViewById(R.id.starred1);
274  mFAB1.show();
275  mActive = "false";
276  }
277 
278 
284  public void onSwitchRepeat(View view) {
285  boolean on = ((Switch) view).isChecked();
286  if (on) {
287  mRepeat = "true";
288  mRepeatText.setText("Every " + mRepeatNo + " " + mRepeatType + "(s)");
289  } else {
290  mRepeat = "false";
291  mRepeatText.setText(R.string.repeat_off);
292  }
293  }
299  public void selectRepeatType(View v) {
300  final String[] items = new String[5];
301 
302  items[0] = "Minute";
303  items[1] = "Hour";
304  items[2] = "Day";
305  items[3] = "Week";
306  items[4] = "Month";
307 
308  // Create List Dialog
309  AlertDialog.Builder builder = new AlertDialog.Builder(this);
310  builder.setTitle("Select Type");
311  builder.setItems(items, new DialogInterface.OnClickListener() {
312 
313  public void onClick(DialogInterface dialog, int item) {
314 
315  mRepeatType = items[item];
316  mRepeatTypeText.setText(mRepeatType);
317  mRepeatText.setText("Every " + mRepeatNo + " " + mRepeatType + "(s)");
318  }
319  });
320  AlertDialog alert = builder.create();
321  alert.show();
322  }
323 
329  public void setRepeatNo(View v) {
330  AlertDialog.Builder alert = new AlertDialog.Builder(this);
331  alert.setTitle("Enter Number");
332 
333  // Create EditText box to input repeat number
334  final EditText input = new EditText(this);
335  input.setInputType(InputType.TYPE_CLASS_NUMBER);
336  alert.setView(input);
337  alert.setPositiveButton("Ok",
338  new DialogInterface.OnClickListener() {
339  public void onClick(DialogInterface dialog, int whichButton) {
340 
341  if (input.getText().toString().length() == 0) {
342  mRepeatNo = Integer.toString(1);
343  mRepeatNoText.setText(mRepeatNo);
344  mRepeatText.setText("Every " + mRepeatNo + " " + mRepeatType + "(s)");
345  } else {
346  mRepeatNo = input.getText().toString().trim();
347  mRepeatNoText.setText(mRepeatNo);
348  mRepeatText.setText("Every " + mRepeatNo + " " + mRepeatType + "(s)");
349  }
350  }
351  });
352  alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
353  public void onClick(DialogInterface dialog, int whichButton) {
354  // do nothing
355  }
356  });
357  alert.show();
358  }
359 
360  public boolean isExternalStorageWritable() {
361  String state = Environment.getExternalStorageState();
362  return Environment.MEDIA_MOUNTED.equals(state);
363  }
364 
370  public void saveReminderToTempStorage(String filename) {
371 
372  ReminderDO talkingReminderDO = new ReminderDO();
373  talkingReminderDO.setTitle(mTitle);
374  talkingReminderDO.setDate(mDate);
375  talkingReminderDO.setTime(mTime);
376  talkingReminderDO.setRepeat(mRepeat);
377  talkingReminderDO.setRepeatNo(mRepeatNo);
378  talkingReminderDO.setRepeatType(mRepeatType);
379 
380  Gson gson = new GsonBuilder().setPrettyPrinting().create();
381  //String fileName=Environment.getExternalStorageDirectory()+"talkingReminderDO.json";
382 
383  //First write the data to a temporary file
384  FileOutputStream outputStream;
385  if (ContextCompat.checkSelfPermission(ReminderAddActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
386  // Permission is not granted
387  if (ActivityCompat.shouldShowRequestPermissionRationale(ReminderAddActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
388 
389  } else {
390  // No explanation needed; request the permission
391  ActivityCompat.requestPermissions(ReminderAddActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_WRITE_CONTACTS);
392  }
393  }
394 
395  try {
396  String fileContents = gson.toJson(talkingReminderDO);
397  outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
398  outputStream.write(fileContents.getBytes());
399  outputStream.close();
400 // FileWriter fw = new FileWriter(filename);
401 // BufferedWriter bw = new BufferedWriter(fw);
402 // bw.write(content);
403 // bw.close();
404  } catch (Exception e) {
405  e.printStackTrace();
406  }
407 
408 
409  }
410 
414  public void saveReminder() {
415  ReminderDatabase rb = new ReminderDatabase(this);
416 
417  // Creating ReminderDO
418  int ID = rb.addReminder(new ReminderDO(mTitle, mDate, mTime, mRepeat, mRepeatNo, mRepeatType, mActive));
419 
420  //Storing Reminders in firebase database
421  ReminderDO reminderDO = new ReminderDO(mTitle, mDate, mTime, mRepeat, mRepeatNo, mRepeatType, mActive);
422  FirebaseUser user = firebaseAuth.getCurrentUser();
423  reminderDO.setOwnerID(user.getEmail());
424  reminderDO.setReceiverID("null");
425  dbReference.child(user.getUid()).push().setValue(reminderDO);
426 
427 
428  // Set up calender for creating the notification
429  mCalendar.set(Calendar.MONTH, --mMonth);
430  mCalendar.set(Calendar.YEAR, mYear);
431  mCalendar.set(Calendar.DAY_OF_MONTH, mDay);
432  mCalendar.set(Calendar.HOUR_OF_DAY, mHour);
433  mCalendar.set(Calendar.MINUTE, mMinute);
434  mCalendar.set(Calendar.SECOND, 0);
435 
436  // Check repeat type
437  if (mRepeatType.equals("Minute")) {
438  mRepeatTime = Integer.parseInt(mRepeatNo) * milMinute;
439  } else if (mRepeatType.equals("Hour")) {
440  mRepeatTime = Integer.parseInt(mRepeatNo) * milHour;
441  } else if (mRepeatType.equals("Day")) {
442  mRepeatTime = Integer.parseInt(mRepeatNo) * milDay;
443  } else if (mRepeatType.equals("Week")) {
444  mRepeatTime = Integer.parseInt(mRepeatNo) * milWeek;
445  } else if (mRepeatType.equals("Month")) {
446  mRepeatTime = Integer.parseInt(mRepeatNo) * milMonth;
447  }
448 
449  // Create a new notification
450  if (mActive.equals("true")) {
451  if (mRepeat.equals("true")) {
452  new AlarmReceiver().setRepeatAlarm(getApplicationContext(), mCalendar, ID, mRepeatTime);
453  } else if (mRepeat.equals("false")) {
454  new AlarmReceiver().setAlarm(getApplicationContext(), mCalendar, ID);
455  }
456  }
457 
458  // Create toast to confirm new reminder
459  Toast.makeText(getApplicationContext(), "Saved",
460  Toast.LENGTH_SHORT).show();
461 
462  onBackPressed();
463  }
464 
469  @Override
470  public void onBackPressed() {
471  super.onBackPressed();
472  }
473 
480  @Override
481  public boolean onCreateOptionsMenu(Menu menu) {
482  getMenuInflater().inflate(R.menu.menu_add_reminder, menu);
483  return true;
484  }
485 
492  @Override
493  public boolean onOptionsItemSelected(MenuItem item) {
494  switch (item.getItemId()) {
495 
496  // On clicking the back arrow
497  // Discard any changes
498  case android.R.id.home:
499  onBackPressed();
500  return true;
501 
502  // On clicking save reminder button
503  // Update reminder
504  case R.id.save_reminder:
505  mTitleText.setText(mTitle);
506 
507  if (mTitleText.getText().toString().trim().length() == 0)
508  mTitleText.setError("ReminderDO Title cannot be blank!");
509 
510  else {
511  saveReminder();
512  }
513  return true;
514 
515  // On clicking discard reminder button
516  // Discard any changes
517  case R.id.discard_reminder:
518  Toast.makeText(getApplicationContext(), "Discarded",
519  Toast.LENGTH_SHORT).show();
520 
521  onBackPressed();
522  return true;
523 
524  // On clicking send reminder button
525  // Initiate sender routine
526  case R.id.send_reminder:
527 
528  Context context = this;
529 
530  String filename = Utility.FILE_NAME_PREFIX + "." + Utility.FILE_EXTENSION; //TODO Consecutive filenames should be unique
531  saveReminderToTempStorage(filename);
532 
533  //Check the if the file was written correctly.. Should be printed on console
534 // FileInputStream fi = null;
535 // try {
536 // fi = context.openFileInput(filename);
537 // int i;
538 // StringBuilder sb = new StringBuilder();
539 // while ((i=fi.read()) != -1)
540 // sb.append((char)i);
541 // System.out.println("******************************************************************");
542 // System.out.println(sb.toString());
543 // System.out.println("******************************************************************");
544 // } catch (Exception e) {
545 // e.printStackTrace();
546 // }
547 
548  //Pick the written file and send
549  File filePath = context.getFilesDir();
550  File fileToSend = new File(filePath, filename);
551  Uri fileUri = FileProvider.getUriForFile(context,
552  "com.sudogeeks.talking_reminder.fileprovider", fileToSend); //TODO remove hardcoded dependencies
553  Intent share = new Intent();
554  share.setAction(Intent.ACTION_SEND);
555  share.putExtra(Intent.EXTRA_STREAM, fileUri);
556  share.setType("text/" + Utility.FILE_EXTENSION);
557  //share.setDataAndType( fileUri, getContentResolver().getType(fileUri));
558  share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
559  //share.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
560  //share.putExtra(MediaStore.)
561 
562  Intent shareIntent = Intent.createChooser(share, null);
563  startActivity(shareIntent);
564 
565  //TODO delete the file once job is done
566 
567 
568  default:
569  return super.onOptionsItemSelected(item);
570  }
571  }
572 
573 }
com.sudogeeks.talking_reminder.AlarmReceiver.setAlarm
void setAlarm(Context context, Calendar calendar, int ID)
Definition: AlarmReceiver.java:73
com.sudogeeks.talking_reminder.ReminderAddActivity.onCreateOptionsMenu
boolean onCreateOptionsMenu(Menu menu)
Definition: ReminderAddActivity.java:481
com.sudogeeks.talking_reminder.ReminderAddActivity.setDate
void setDate(View v)
Definition: ReminderAddActivity.java:238
com.sudogeeks.talking_reminder.ReminderAddActivity.selectRepeatType
void selectRepeatType(View v)
Definition: ReminderAddActivity.java:299
com.sudogeeks.talking_reminder.ReminderDO
Data Object class for Reminder This class conatins all the attributes of reminder.
Definition: ReminderDO.java:15
com.sudogeeks.talking_reminder.ReminderAddActivity.setTime
void setTime(View v)
Definition: ReminderAddActivity.java:211
com.sudogeeks.talking_reminder.ReminderDatabase
Class to manage database This class is for managing the database.
Definition: ReminderDatabase.java:15
com.sudogeeks.talking_reminder.Utility
Definition: Utility.java:3
com.sudogeeks.talking_reminder.AlarmReceiver
A class implementing basic alarm functions This class includes very basic features for an alarm.
Definition: AlarmReceiver.java:21
com.sudogeeks.talking_reminder.ReminderAddActivity.saveReminder
void saveReminder()
Definition: ReminderAddActivity.java:414
com.sudogeeks.talking_reminder.ReminderAddActivity.onCreate
void onCreate(Bundle savedInstanceState)
Definition: ReminderAddActivity.java:90
com.sudogeeks.talking_reminder.ReminderAddActivity.onBackPressed
void onBackPressed()
Definition: ReminderAddActivity.java:470
com.sudogeeks.talking_reminder.ReminderAddActivity.setRepeatNo
void setRepeatNo(View v)
Definition: ReminderAddActivity.java:329
com.sudogeeks.talking_reminder.ReminderAddActivity.onOptionsItemSelected
boolean onOptionsItemSelected(MenuItem item)
Definition: ReminderAddActivity.java:493
com.sudogeeks.talking_reminder.ReminderAddActivity.onSwitchRepeat
void onSwitchRepeat(View view)
Definition: ReminderAddActivity.java:284
com.sudogeeks.talking_reminder.ReminderDatabase.addReminder
int addReminder(ReminderDO reminderDO)
Definition: ReminderDatabase.java:83
com.sudogeeks.talking_reminder.AlarmReceiver.setRepeatAlarm
void setRepeatAlarm(Context context, Calendar calendar, int ID, long RepeatTime)
Definition: AlarmReceiver.java:107
com.sudogeeks.talking_reminder.ReminderAddActivity
Java class for handling UI component of Add reminder layout.
Definition: ReminderAddActivity.java:48
com.sudogeeks.talking_reminder.ReminderAddActivity.saveReminderToTempStorage
void saveReminderToTempStorage(String filename)
Definition: ReminderAddActivity.java:370