Commit 85f80a85 authored by RAUSHAN RAJ's avatar RAUSHAN RAJ

resolved git conflicts

parent b567744b
TalkingReminder @ 167e7542
Subproject commit 167e7542698cedb645460263bd077d9cb54bc539
This diff is collapsed.
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.sudogeeks.talking_reminder"
minSdkVersion 16
targetSdkVersion 29
versionCode 2
versionName "1.0.1"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'com.bignerdranch.android:recyclerview-multiselect:0.2'
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
implementation 'com.google.code.gson:gson:2.8.6'
// Lombok Dependencies
compileOnly 'org.projectlombok:lombok:1.18.10'
annotationProcessor 'org.projectlombok:lombok:1.18.10'
implementation 'org.jetbrains:annotations-java5:15.0'
// add the Firebase SDK Dependencies
implementation 'com.google.firebase:firebase-analytics:17.2.0'
implementation 'com.google.firebase:firebase-database:19.2.0'
implementation 'com.google.firebase:firebase-auth:19.1.0'
implementation 'com.firebaseui:firebase-ui-auth:6.0.2'
// implementation 'com.google.firebase:firebase-appindexing:19.0.0'
// implementation 'com.google.firebase:firebase-firestore:21.2.0'
// implementation 'com.google.gms:google-services:4.3.2'
// implementation 'com.google.firebase:firebase-storage:19.1.0'
}
apply plugin: 'com.google.gms.google-services'
\ No newline at end of file
{
"project_info": {
"project_number": "101187773727",
"firebase_url": "https://talking-reminder-2.firebaseio.com",
"project_id": "talking-reminder-2",
"storage_bucket": "talking-reminder-2.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:101187773727:android:daff65310a8454ec4cbc2a",
"android_client_info": {
"package_name": "com.sudogeeks.talking_reminder"
}
},
"oauth_client": [
{
"client_id": "101187773727-343eutk6jp3258dj50dvdtl4j2lvs6ol.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyALcQqLVwx7CVr-uuj9p9_nFF3VPpPFWdc"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "101187773727-343eutk6jp3258dj50dvdtl4j2lvs6ol.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Program Files\Android SDK\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.sudogeeks.talking_reminder">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
tools:replace="android:icon,android:theme">
<activity android:name="com.sudogeeks.talking_reminder.ReadReminderTextService"></activity>
<activity android:name="com.sudogeeks.talking_reminder.ReminderReceiveActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/tprd"
android:host="*"
android:pathPattern=".*\\.tprd"
/>
</intent-filter>
</activity>
<activity
android:name="com.sudogeeks.talking_reminder.MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.sudogeeks.talking_reminder.ReminderAddActivity"
android:label="@string/activity_add_reminder_label">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
<activity
android:name="com.sudogeeks.talking_reminder.ReminderEditActivity"
android:label="@string/activity_edit_reminder_label" />
<receiver android:name="com.sudogeeks.talking_reminder.AlarmReceiver"/>
<receiver android:name="com.sudogeeks.talking_reminder.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.sudogeeks.talking_reminder.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<!-- ressource file to create -->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths">
</meta-data>
</provider>
<service
android:name="com.sudogeeks.talking_reminder.ReadReminderTextService"
android:enabled="true" />
</application>
</manifest>
package com.sudogeeks.talking_reminder;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.SystemClock;
import androidx.core.app.NotificationCompat;
import java.util.Calendar;
/**
* \brief A class implementing basic alarm functions
* This class includes very basic features for an alarm
*/
public class AlarmReceiver extends BroadcastReceiver {
AlarmManager mAlarmManager;
PendingIntent mPendingIntent;
/**
* Notifies user at the time of alarm
*
* @param context:
* @param intent
* @return void
*/
@Override
public void onReceive(Context context, Intent intent) {
int mReceivedID = Integer.parseInt(intent.getStringExtra(ReminderEditActivity.EXTRA_REMINDER_ID));
//Get notification title from ReminderDO Database
ReminderDatabase rb = new ReminderDatabase(context);
ReminderDO reminderDO = rb.getReminder(mReceivedID);
String mTitle = reminderDO.getTitle();
// Create intent to open ReminderEditActivity on notification click
Intent editIntent = new Intent(context, ReminderEditActivity.class);
editIntent.putExtra(ReminderEditActivity.EXTRA_REMINDER_ID, Integer.toString(mReceivedID));
PendingIntent mClick = PendingIntent.getActivity(context, mReceivedID, editIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationHelper notificationHelper = new NotificationHelper(context, intent);
NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
notificationHelper.getManager().notify(mReceivedID, nb.build());
// tts
// context.startService(new Intent(context, ReadReminderTextService.class));
Intent i = new Intent(context, ReadReminderTextService.class);
i.putExtra("MyTitle", mTitle);
context.startService(i);
context.startService(i);
context.startService(i);
}
/**
* Method for setting an alarm
*
* @param context
* @param calendar Calendar instance encapsulating date and time of alarm
* @param ID Id of the alarm
* @return void
*/
public void setAlarm(Context context, Calendar calendar, int ID) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Put ReminderDO ID in Intent Extra
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra(ReminderEditActivity.EXTRA_REMINDER_ID, Integer.toString(ID));
mPendingIntent = PendingIntent.getBroadcast(context, ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
// Calculate notification time
Calendar c = Calendar.getInstance();
long currentTime = c.getTimeInMillis();
long diffTime = calendar.getTimeInMillis() - currentTime;
// Start alarm using notification time
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + diffTime,
mPendingIntent);
// Restart alarm if device is rebooted
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
/**
* Method for setting repeating alarm
*
* @param context
* @param calendar Calendar instance encapsulating date and time of alarm
* @param ID Id of the alarm
* @param RepeatTime repeat time of alaram
*/
public void setRepeatAlarm(Context context, Calendar calendar, int ID, long RepeatTime) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Put ReminderDO ID in Intent Extra
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra(ReminderEditActivity.EXTRA_REMINDER_ID, Integer.toString(ID));
mPendingIntent = PendingIntent.getBroadcast(context, ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
// Calculate notification timein
Calendar c = Calendar.getInstance();
long currentTime = c.getTimeInMillis();
long diffTime = calendar.getTimeInMillis() - currentTime;
// Start alarm using initial notification time and repeat interval time
mAlarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + diffTime,
RepeatTime, mPendingIntent);
// Restart alarm if device is rebooted
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
/**
* Method for cancelling an alarm
*
* @param context
* @param ID Id of the alarm to cancel
*/
public void cancelAlarm(Context context, int ID) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Cancel Alarm using ReminderDO ID
mPendingIntent = PendingIntent.getBroadcast(context, ID, new Intent(context, AlarmReceiver.class), 0);
mAlarmManager.cancel(mPendingIntent);
// Disable alarm
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
}
\ No newline at end of file
package com.sudogeeks.talking_reminder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import java.util.Calendar;
import java.util.List;
/**
* \brief A class For handling the reboot scenarios.
* In this case this class reschedules the alarms if the device boots
*
*/
public class BootReceiver extends BroadcastReceiver {
// Constant values in milliseconds
private static final long milMinute = 60000L;
private static final long milHour = 3600000L;
private static final long milDay = 86400000L;
private static final long milWeek = 604800000L;
private static final long milMonth = 2592000000L;
private String mTitle;
private String mTime;
private String mDate;
private String mRepeatNo;
private String mRepeatType;
private String mActive;
private String mRepeat;
private String[] mDateSplit;
private String[] mTimeSplit;
private int mYear, mMonth, mHour, mMinute, mDay, mReceivedID;
private long mRepeatTime;
private Calendar mCalendar;
private AlarmReceiver mAlarmReceiver;
/**
* Overrides onReceive method of BroadcastReceiver class. Once the device boot completes, this method will schedule the alarms again
* @param context
* @param intent
*/
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
ReminderDatabase rb = new ReminderDatabase(context);
mCalendar = Calendar.getInstance();
mAlarmReceiver = new AlarmReceiver();
List<ReminderDO> reminderDOS = rb.getAllReminders();
for (ReminderDO rm : reminderDOS) {
mReceivedID = rm.getID();
mRepeat = rm.getRepeat();
mRepeatNo = rm.getRepeatNo();
mRepeatType = rm.getRepeatType();
mActive = rm.getActive();
mDate = rm.getDate();
mTime = rm.getTime();
mDateSplit = mDate.split("/");
mTimeSplit = mTime.split(":");
mDay = Integer.parseInt(mDateSplit[0]);
mMonth = Integer.parseInt(mDateSplit[1]);
mYear = Integer.parseInt(mDateSplit[2]);
mHour = Integer.parseInt(mTimeSplit[0]);
mMinute = Integer.parseInt(mTimeSplit[1]);
mCalendar.set(Calendar.MONTH, --mMonth);
mCalendar.set(Calendar.YEAR, mYear);
mCalendar.set(Calendar.DAY_OF_MONTH, mDay);
mCalendar.set(Calendar.HOUR_OF_DAY, mHour);
mCalendar.set(Calendar.MINUTE, mMinute);
mCalendar.set(Calendar.SECOND, 0);
// Cancel existing notification of the reminder by using its ID
// mAlarmReceiver.cancelAlarm(context, mReceivedID);
// Check repeat type
if (mRepeatType.equals("Minute")) {
mRepeatTime = Integer.parseInt(mRepeatNo) * milMinute;
} else if (mRepeatType.equals("Hour")) {
mRepeatTime = Integer.parseInt(mRepeatNo) * milHour;
} else if (mRepeatType.equals("Day")) {
mRepeatTime = Integer.parseInt(mRepeatNo) * milDay;
} else if (mRepeatType.equals("Week")) {
mRepeatTime = Integer.parseInt(mRepeatNo) * milWeek;
} else if (mRepeatType.equals("Month")) {
mRepeatTime = Integer.parseInt(mRepeatNo) * milMonth;
}
// Create a new notification
if (mActive.equals("true")) {
if (mRepeat.equals("true")) {
mAlarmReceiver.setRepeatAlarm(context, mCalendar, mReceivedID, mRepeatTime);
} else if (mRepeat.equals("false")) {
mAlarmReceiver.setAlarm(context, mCalendar, mReceivedID);
}
}
}
}
}
}
\ No newline at end of file
package com.sudogeeks.talking_reminder;
/**
* \brief Data Object class for creating DateTime objects to facilitate easy sorting
*
*/
public class DateTimeSorter {
private int mIndex;
private String mDateTime;
public DateTimeSorter(int index, String DateTime) {
mIndex = index;
mDateTime = DateTime;
}
public DateTimeSorter() {
}
public int getIndex() {
return mIndex;
}
public void setIndex(int index) {
mIndex = index;
}
public String getDateTime() {
return mDateTime;
}
public void setDateTime(String dateTime) {
mDateTime = dateTime;
}
}
package com.sudogeeks.talking_reminder;
import android.annotation.TargetApi;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.speech.tts.TextToSpeech;
import androidx.core.app.NotificationCompat;
/** \brief Class to implement notification
* This class is for implementing notification popup at alarm time
*/
public class NotificationHelper extends ContextWrapper {
public static final String channelID = "channelID";
public static final String channelName = "Channel Name";
String mTitle;
PendingIntent mClick;
private NotificationManager mManager;
private TextToSpeech t1;
/**
* Constructor for NotificationHelper class
* @param base
* @param intent
*/
public NotificationHelper(Context base, Intent intent) {
super(base);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createChannel();
}
int mReceivedID = Integer.parseInt(intent.getStringExtra(ReminderEditActivity.EXTRA_REMINDER_ID));
ReminderDatabase rb = new ReminderDatabase(base);
ReminderDO reminderDO = rb.getReminder(mReceivedID);
mTitle = reminderDO.getTitle();
// Create intent to open ReminderEditActivity on notification click
Intent editIntent = new Intent(base, ReminderEditActivity.class);
editIntent.putExtra(ReminderEditActivity.EXTRA_REMINDER_ID, Integer.toString(mReceivedID));
mClick = PendingIntent.getActivity(base, mReceivedID, editIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
@TargetApi(Build.VERSION_CODES.O)
private void createChannel() {
NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
getManager().createNotificationChannel(channel);
}
public NotificationManager getManager() {
if (mManager == null) {
mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mManager;
}
/**
* This method build notificationCompat having various setting of notification likeicon, content,priority,etc..
* @return NotificationCompat.Builder for the notification
*/
public NotificationCompat.Builder getChannelNotification() {
//t1.speak(mTitle, TextToSpeech.QUEUE_FLUSH, null);
// t1.synthesizeToFile(mTitle, null, "/SDCARD/speak1.wav");
//Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + getPackageName() + "/raw/sample");
return new NotificationCompat.Builder(getApplicationContext(), channelID)
.setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.mipmap.ic_launcher))
.setSmallIcon(R.drawable.ic_alarm_on_white)
.setContentTitle(getApplicationContext().getResources().getString(R.string.app_name))
.setTicker(mTitle)
.setContentText(mTitle)
//.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM))
// .setSound(Uri.fromFile(new File("SDCARD/s1.mp3")))
//.setSound(null)
.setPriority(NotificationManager.IMPORTANCE_HIGH)
.setContentIntent(mClick)
.setAutoCancel(true)
.setOnlyAlertOnce(true);
}
public TextToSpeech getTextToSpeech() {
return t1;
}
}
//function
\ No newline at end of file
package com.sudogeeks.talking_reminder;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.speech.tts.TextToSpeech;
import java.util.Locale;
/**\brief Class for Text to speech service
* This class is extending the tts module service to speak up the reminder text
*/
public class ReadReminderTextService extends Service implements TextToSpeech.OnInitListener, TextToSpeech.OnUtteranceCompletedListener {
private TextToSpeech mTts;
private String spokenText;
/**
* Overrides onCreate , this is the good place to set spokentext.
*/
@Override
public void onCreate() {
mTts = new TextToSpeech(this, this);
// This is a good place to set spokenText
// spokenText="raushan raushan raushan raushan";
}
/**
* Overrides OnStartCommand of service class , this is used to get reminder text which will be spoken.
* @param intent
* @param flags
* @param startId
* @return
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
spokenText = intent.getStringExtra("MyTitle");
return START_STICKY;
}
/**
* This method overrides onInit and this is calling TTS object to speak up the spoken text.
* @param status
*/
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = mTts.setLanguage(Locale.US);
if (result != TextToSpeech.LANG_MISSING_DATA && result != TextToSpeech.LANG_NOT_SUPPORTED) {
mTts.speak(spokenText, TextToSpeech.QUEUE_ADD, null);
}
}
}
@Override
public void onUtteranceCompleted(String uttId) {
stopSelf();
}
@Override
public void onDestroy() {
if (mTts != null) {
mTts.stop();
mTts.shutdown();
}
super.onDestroy();
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
\ No newline at end of file
package com.sudogeeks.talking_reminder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
// ReminderDO class
//@Data
@Data
/**\brief Data Object class for Reminder
* This class conatins all the attributes of reminder.
*
*/
public class ReminderDO {
private int mID;
private String mTitle;
private String mDate;
private String mTime;
private String mRepeat;
private String mRepeatNo;
private String mRepeatType;
private String mActive;
private String ownerID = null; //Email Id of the owner/creater of the reminder
private String receiverID = null; //Email Id of the receiver of the reminder;
public ReminderDO(int ID, String Title, String Date, String Time, String Repeat, String RepeatNo, String RepeatType, String Active) {
mID = ID;
mTitle = Title;
mDate = Date;
mTime = Time;
mRepeat = Repeat;
mRepeatNo = RepeatNo;
mRepeatType = RepeatType;
mActive = Active;
}
public ReminderDO(String Title, String Date, String Time, String Repeat, String RepeatNo, String RepeatType, String Active) {
mTitle = Title;
mDate = Date;
mTime = Time;
mRepeat = Repeat;
mRepeatNo = RepeatNo;
mRepeatType = RepeatType;
mActive = Active;
}
ReminderDO() {
}
public String getOwnerID() {
return ownerID;
}
public void setOwnerID(String ownerID) {
this.ownerID = ownerID;
}
public String getReceiverID() {
return receiverID;
}
public void setReceiverID(String receiverID) {
this.receiverID = receiverID;
}
public int getID() {
return mID;
}
public void setID(int ID) {
mID = ID;
}
public String getTitle() {
return mTitle;
}
public void setTitle(String title) {
mTitle = title;
}
public String getDate() {
return mDate;
}
public void setDate(String date) {
mDate = date;
}
public String getTime() {
return mTime;
}
public void setTime(String time) {
mTime = time;
}
public String getRepeatType() {
return mRepeatType;
}
public void setRepeatType(String repeatType) {
mRepeatType = repeatType;
}
public String getRepeatNo() {
return mRepeatNo;
}
public void setRepeatNo(String repeatNo) {
mRepeatNo = repeatNo;
}
public String getRepeat() {
return mRepeat;
}
public void setRepeat(String repeat) {
mRepeat = repeat;
}
public String getActive() {
return mActive;
}
public void setActive(String active) {
mActive = active;
}
}
package com.sudogeeks.talking_reminder;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
import java.util.List;
/**\brief Class to manage database
* This class is for managing the database
*/
public class ReminderDatabase extends SQLiteOpenHelper {
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "ReminderDatabase";
// Table name
private static final String TABLE_REMINDERS = "ReminderTable";
// Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_TITLE = "title";
private static final String KEY_DATE = "date";
private static final String KEY_TIME = "time";
private static final String KEY_REPEAT = "repeat";
private static final String KEY_REPEAT_NO = "repeat_no";
private static final String KEY_REPEAT_TYPE = "repeat_type";
private static final String KEY_ACTIVE = "active";
public ReminderDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/**
* Creating Tables for reminder
* @param db
*/
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_REMINDERS_TABLE = "CREATE TABLE " + TABLE_REMINDERS +
"("
+ KEY_ID + " INTEGER PRIMARY KEY,"
+ KEY_TITLE + " TEXT,"
+ KEY_DATE + " TEXT,"
+ KEY_TIME + " INTEGER,"
+ KEY_REPEAT + " BOOLEAN,"
+ KEY_REPEAT_NO + " INTEGER,"
+ KEY_REPEAT_TYPE + " TEXT,"
+ KEY_ACTIVE + " BOOLEAN" + ")";
db.execSQL(CREATE_REMINDERS_TABLE);
}
/**
* Upgrading database
* @param db
* @param oldVersion
* @param newVersion
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
if (oldVersion >= newVersion)
return;
db.execSQL("DROP TABLE IF EXISTS " + TABLE_REMINDERS);
// Create tables again
onCreate(db);
}
/**
* This method is for adding ReminderDO into the reminder table in database
* @param reminderDO
* @return
*/
public int addReminder(ReminderDO reminderDO) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TITLE, reminderDO.getTitle());
values.put(KEY_DATE, reminderDO.getDate());
values.put(KEY_TIME, reminderDO.getTime());
values.put(KEY_REPEAT, reminderDO.getRepeat());
values.put(KEY_REPEAT_NO, reminderDO.getRepeatNo());
values.put(KEY_REPEAT_TYPE, reminderDO.getRepeatType());
values.put(KEY_ACTIVE, reminderDO.getActive());
// Inserting Row
long ID = db.insert(TABLE_REMINDERS, null, values);
db.close();
return (int) ID;
}
/**
* To get single ReminderDO corresponding to the id in parameter
* @param id
* @return reminderDo
*/
public ReminderDO getReminder(int id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_REMINDERS, new String[]
{
KEY_ID,
KEY_TITLE,
KEY_DATE,
KEY_TIME,
KEY_REPEAT,
KEY_REPEAT_NO,
KEY_REPEAT_TYPE,
KEY_ACTIVE
}, KEY_ID + "=?",
new String[]{String.valueOf(id)}, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
ReminderDO reminderDO = new ReminderDO(Integer.parseInt(cursor.getString(0)), cursor.getString(1),
cursor.getString(2), cursor.getString(3), cursor.getString(4),
cursor.getString(5), cursor.getString(6), cursor.getString(7));
return reminderDO;
}
/**
* This method is for getting all reminders for a particular user
* @return List of <ReminderDo>
*/
// Getting all Reminders
public List<ReminderDO> getAllReminders() {
List<ReminderDO> reminderDOList = new ArrayList<>();
// Select all Query
String selectQuery = "SELECT * FROM " + TABLE_REMINDERS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// Looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
ReminderDO reminderDO = new ReminderDO();
reminderDO.setID(Integer.parseInt(cursor.getString(0)));
reminderDO.setTitle(cursor.getString(1));
reminderDO.setDate(cursor.getString(2));
reminderDO.setTime(cursor.getString(3));
reminderDO.setRepeat(cursor.getString(4));
reminderDO.setRepeatNo(cursor.getString(5));
reminderDO.setRepeatType(cursor.getString(6));
reminderDO.setActive(cursor.getString(7));
// Adding Reminders to list
reminderDOList.add(reminderDO);
} while (cursor.moveToNext());
}
return reminderDOList;
}
/**
* This method is for Getting Reminders Count
* @return reminder count
*/
public int getRemindersCount() {
String countQuery = "SELECT * FROM " + TABLE_REMINDERS;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
cursor.close();
return cursor.getCount();
}
/**
* This method is for updating single ReminderDO
* @param reminderDO
* @return
*/
public int updateReminder(ReminderDO reminderDO) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TITLE, reminderDO.getTitle());
values.put(KEY_DATE, reminderDO.getDate());
values.put(KEY_TIME, reminderDO.getTime());
values.put(KEY_REPEAT, reminderDO.getRepeat());
values.put(KEY_REPEAT_NO, reminderDO.getRepeatNo());
values.put(KEY_REPEAT_TYPE, reminderDO.getRepeatType());
values.put(KEY_ACTIVE, reminderDO.getActive());
// Updating row
return db.update(TABLE_REMINDERS, values, KEY_ID + "=?",
new String[]{String.valueOf(reminderDO.getID())});
}
/**
* This method is for deleting single ReminderDo
* @param reminderDO
*/
public void deleteReminder(ReminderDO reminderDO) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_REMINDERS, KEY_ID + "=?",
new String[]{String.valueOf(reminderDO.getID())});
db.close();
}
}
package com.sudogeeks.talking_reminder;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import org.json.JSONObject;
import java.io.InputStream;
import java.util.Calendar;
/**\brief Class to read and parse reminder Data after receiving
* This class parse the received reminder object and saves that in database and trigger alarm for that.
*/
public class ReminderReceiveActivity extends AppCompatActivity {
private static final long milMinute = 60000L;
private static final long milHour = 3600000L;
private static final long milDay = 86400000L;
private static final long milWeek = 604800000L;
private static final long milMonth = 2592000000L;
private Toolbar mToolbar;
private EditText mTitleText;
private TextView mDateText, mTimeText, mRepeatText, mRepeatNoText, mRepeatTypeText;
private String mRepeat;
private String mRepeatType;
private String mRepeatNo;
private Calendar mCalendar;
private int mYear, mMonth, mHour, mMinute, mDay;
private long mRepeatTime;
private String mActive;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_receive_reminder);
Context context = this;
mCalendar = Calendar.getInstance();
mHour = mCalendar.get(Calendar.HOUR_OF_DAY);
mMinute = mCalendar.get(Calendar.MINUTE);
mYear = mCalendar.get(Calendar.YEAR);
mMonth = mCalendar.get(Calendar.MONTH) + 1;
mDay = mCalendar.get(Calendar.DATE);
//by default
mActive = "true";
// Setup Toolbar
mToolbar = findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setTitle(R.string.activity_add_reminder_label);
//Get the file from intent
Intent intent = getIntent();
Uri fileUri = intent.getData();
StringBuilder reminderJson = new StringBuilder();
if (intent.getType().equals("text/" + Utility.FILE_EXTENSION)) {
try {
InputStream in = getContentResolver().openInputStream(fileUri);
int i;
while ((i = in.read()) != -1)
reminderJson.append((char) i);
//System.out.println("******************************************************************");
//System.out.println(sb.toString());
//System.out.println("******************************************************************");
} catch (Exception e) {
e.printStackTrace();
}
try {
JSONObject obj = new JSONObject(reminderJson.toString());
//ReminderDO talkingReminder=new ReminderDO();
mTitleText = findViewById(R.id.reminder_title);
mDateText = findViewById(R.id.set_date);
mTimeText = findViewById(R.id.set_time);
mRepeatText = findViewById(R.id.set_repeat);
mRepeatNoText = findViewById(R.id.set_repeat_no);
mRepeatTypeText = findViewById(R.id.set_repeat_type);
mRepeat = obj.getString("mRepeat");
mRepeatType = obj.getString("mRepeatType");
mRepeatNo = obj.getString("mRepeatNo");
mTitleText.setText(obj.getString("mTitle"));
mDateText.setText(obj.getString("mDate"));
mTimeText.setText(obj.getString("mTime"));
mRepeatText.setText("Every " + obj.getString("mRepeatNo") + " " + obj.getString("mRepeatType") + "(s)");
mRepeatNoText.setText(obj.getString("mRepeatNo"));
mRepeatTypeText.setText(obj.getString("mRepeatType"));
} catch (Throwable t) {
t.printStackTrace();
}
/*Intent senderIntent = new Intent(context, ReminderEditActivity.class);
senderIntent.putExtra("received", true);
senderIntent.putExtra("mTitle", "First Receive ReminderDO test");
startActivity(senderIntent);*/
}
}
/**
* This method populates the ui as received and then saves the reminder to database.
*/
public void saveSendReminder() {
ReminderDatabase rb = new ReminderDatabase(this);
// Creating ReminderDO
int ID = rb.addReminder(new ReminderDO(mTitleText.getText().toString(), mDateText.getText().toString(), mTimeText.getText().toString(), mRepeat, mRepeatNoText.getText().toString(), mRepeatTypeText.getText().toString(), mActive));
// Set up calender for creating the notification
mCalendar.set(Calendar.MONTH, --mMonth);
mCalendar.set(Calendar.YEAR, mYear);
mCalendar.set(Calendar.DAY_OF_MONTH, mDay);
mCalendar.set(Calendar.HOUR_OF_DAY, mHour);
mCalendar.set(Calendar.MINUTE, mMinute);
mCalendar.set(Calendar.SECOND, 0);
// Check repeat type
if (mRepeatType.equals("Minute")) {
mRepeatTime = Integer.parseInt(mRepeatNo) * milMinute;
} else if (mRepeatType.equals("Hour")) {
mRepeatTime = Integer.parseInt(mRepeatNo) * milHour;
} else if (mRepeatType.equals("Day")) {
mRepeatTime = Integer.parseInt(mRepeatNo) * milDay;
} else if (mRepeatType.equals("Week")) {
mRepeatTime = Integer.parseInt(mRepeatNo) * milWeek;
} else if (mRepeatType.equals("Month")) {
mRepeatTime = Integer.parseInt(mRepeatNo) * milMonth;
}
// Create a new notification
if (mActive.equals("true")) {
if (mRepeat.equals("true")) {
new AlarmReceiver().setRepeatAlarm(getApplicationContext(), mCalendar, ID, mRepeatTime);
} else if (mRepeat.equals("false")) {
new AlarmReceiver().setAlarm(getApplicationContext(), mCalendar, ID);
}
}
// Create toast to confirm new reminder
Toast.makeText(getApplicationContext(), "Saved",
Toast.LENGTH_SHORT).show();
onBackPressed();
}
// Creating the menu
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_receive_reminder, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// On clicking the back arrow
// Discard any changes
case android.R.id.home:
onBackPressed();
return true;
// On clicking save reminder button
// Update reminder
case R.id.save_reminder:
saveSendReminder();
default:
return super.onOptionsItemSelected(item);
}
}
}
package com.sudogeeks.talking_reminder;
public class Utility {
public static final String FILE_NAME_PREFIX = "Talking_Reminder";
public static final String FILE_EXTENSION = "tprd";
}
<vector android:height="24dp" android:tint="#646464"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM12.5,7H11v6l5.25,3.15 0.75,-1.23 -4.5,-2.67z"/>
</vector>
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M22,5.72l-4.6,-3.86 -1.29,1.53 4.6,3.86L22,5.72zM7.88,3.39L6.6,1.86 2,5.71l1.29,1.53 4.59,-3.85zM12,4c-4.97,0 -9,4.03 -9,9s4.02,9 9,9c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,20c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7zM10.54,14.53L8.41,12.4l-1.06,1.06 3.18,3.18 6,-6 -1.06,-1.06 -4.93,4.95z"/>
</vector>
<vector android:height="24dp" android:tint="#646464"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M9,11L7,11v2h2v-2zM13,11h-2v2h2v-2zM17,11h-2v2h2v-2zM19,4h-1L18,2h-2v2L8,4L8,2L6,2v2L5,4c-1.11,0 -1.99,0.9 -1.99,2L3,20c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.9,-2 -2,-2zM19,20L5,20L5,9h14v11z"/>
</vector>
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
</vector>
<vector android:height="24dp" android:tint="#646464"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,4L12,1L8,5l4,4L12,6c3.31,0 6,2.69 6,6 0,1.01 -0.25,1.97 -0.7,2.8l1.46,1.46C19.54,15.03 20,13.57 20,12c0,-4.42 -3.58,-8 -8,-8zM12,18c-3.31,0 -6,-2.69 -6,-6 0,-1.01 0.25,-1.97 0.7,-2.8L5.24,7.74C4.46,8.97 4,10.43 4,12c0,4.42 3.58,8 8,8v3l4,-4 -4,-4v3z"/>
</vector>
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M7.58,4.08L6.15,2.65C3.75,4.48 2.17,7.3 2.03,10.5h2c0.15,-2.65 1.51,-4.97 3.55,-6.42zM19.97,10.5h2c-0.15,-3.2 -1.73,-6.02 -4.12,-7.85l-1.42,1.43c2.02,1.45 3.39,3.77 3.54,6.42zM18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2v-5zM12,22c0.14,0 0.27,-0.01 0.4,-0.04 0.65,-0.14 1.18,-0.58 1.44,-1.18 0.1,-0.24 0.15,-0.5 0.15,-0.78h-4c0.01,1.1 0.9,2 2.01,2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M7.58,4.08L6.15,2.65C3.75,4.48 2.17,7.3 2.03,10.5h2c0.15,-2.65 1.51,-4.97 3.55,-6.42zM19.97,10.5h2c-0.15,-3.2 -1.73,-6.02 -4.12,-7.85l-1.42,1.43c2.02,1.45 3.39,3.77 3.54,6.42zM18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2v-5zM12,22c0.14,0 0.27,-0.01 0.4,-0.04 0.65,-0.14 1.18,-0.58 1.44,-1.18 0.1,-0.24 0.15,-0.5 0.15,-0.78h-4c0.01,1.1 0.9,2 2.01,2z"/>
</vector>
<vector android:height="24dp" android:tint="#C8C8C8"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M20,18.69L7.84,6.14 5.27,3.49 4,4.76l2.8,2.8v0.01c-0.52,0.99 -0.8,2.16 -0.8,3.42v5l-2,2v1h13.73l2,2L21,19.72l-1,-1.03zM12,22c1.11,0 2,-0.89 2,-2h-4c0,1.11 0.89,2 2,2zM18,14.68L18,11c0,-3.08 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68c-0.15,0.03 -0.29,0.08 -0.42,0.12 -0.1,0.03 -0.2,0.07 -0.3,0.11h-0.01c-0.01,0 -0.01,0 -0.02,0.01 -0.23,0.09 -0.46,0.2 -0.68,0.31 0,0 -0.01,0 -0.01,0.01L18,14.68z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,18.69L7.84,6.14 5.27,3.49 4,4.76l2.8,2.8v0.01c-0.52,0.99 -0.8,2.16 -0.8,3.42v5l-2,2v1h13.73l2,2L21,19.72l-1,-1.03zM12,22c1.11,0 2,-0.89 2,-2h-4c0,1.11 0.89,2 2,2zM18,14.68L18,11c0,-3.08 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68c-0.15,0.03 -0.29,0.08 -0.42,0.12 -0.1,0.03 -0.2,0.07 -0.3,0.11h-0.01c-0.01,0 -0.01,0 -0.02,0.01 -0.23,0.09 -0.46,0.2 -0.68,0.31 0,0 -0.01,0 -0.01,0.01L18,14.68z"/>
</vector>
<vector android:height="24dp" android:tint="#646464"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M3,15h18v-2L3,13v2zM3,19h18v-2L3,17v2zM3,11h18L21,9L3,9v2zM3,5v2h18L21,5L3,5z"/>
</vector>
<vector android:height="24dp" android:tint="#646464"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M7,7h10v3l4,-4 -4,-4v3L5,5v6h2L7,7zM17,17L7,17v-3l-4,4 4,4v-3h12v-6h-2v4z"/>
</vector>
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M17,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,7l-4,-4zM12,19c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3 3,1.34 3,3 -1.34,3 -3,3zM15,9L5,9L5,5h10v4z"/>
</vector>
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z"/>
</vector>
<vector android:height="24dp" android:tint="#646464"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,4L12,1L8,5l4,4L12,6c3.31,0 6,2.69 6,6 0,1.01 -0.25,1.97 -0.7,2.8l1.46,1.46C19.54,15.03 20,13.57 20,12c0,-4.42 -3.58,-8 -8,-8zM12,18c-3.31,0 -6,-2.69 -6,-6 0,-1.01 0.25,-1.97 0.7,-2.8L5.24,7.74C4.46,8.97 4,10.43 4,12c0,4.42 3.58,8 8,8v3l4,-4 -4,-4v3z"/>
</vector>
<vector android:height="24dp" android:tint="#646464"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M15,1L9,1v2h6L15,1zM11,14h2L13,8h-2v6zM19.03,7.39l1.42,-1.42c-0.43,-0.51 -0.9,-0.99 -1.41,-1.41l-1.42,1.42C16.07,4.74 14.12,4 12,4c-4.97,0 -9,4.03 -9,9s4.02,9 9,9 9,-4.03 9,-9c0,-2.12 -0.74,-4.07 -1.97,-5.61zM12,20c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z"/>
</vector>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="@android:color/transparent"
android:endColor="#88333333"
android:angle="90"/>
</shape>
\ No newline at end of file
This diff is collapsed.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
app:contentInsetLeft="0dp"
app:contentInsetStart="16dp"
android:theme="@style/AppTheme.NoActionBar"
android:background="?attr/colorPrimary" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/reminder_list"
android:layout_below="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/no_reminder_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:padding="16dp"
android:gravity="center"
android:visibility="gone"
android:text="@string/no_reminders"/>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_below="@+id/toolbar"
android:background="@drawable/toolbar_dropshadow" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_reminder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:clickable="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:src="@drawable/ic_add"/>
</RelativeLayout>
This diff is collapsed.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="?android:attr/selectableItemBackground"
android:layout_height="86dp">
<ImageView android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_centerVertical="true"
android:id="@+id/thumbnail_image"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:layout_toRightOf="@id/thumbnail_image"
android:layout_toLeftOf="@+id/active_image"
android:orientation="vertical">
<TextView
android:id="@+id/recycle_title"
android:layout_width="match_parent"
android:ellipsize="end"
android:maxLines="2"
android:layout_height="wrap_content"
android:textColor="@color/abc_primary_text_material_dark"
tools:text="Title"
android:textSize="16dp"/>
<TextView
android:id="@+id/recycle_date_time"
android:layout_width="match_parent"
android:ellipsize="marquee"
android:singleLine="true"
android:layout_height="wrap_content"
android:textSize="13dp"
android:textColor="@color/abc_secondary_text_material_dark"
tools:text="Date and Time"/>
<TextView
android:id="@+id/recycle_repeat_info"
android:layout_width="match_parent"
android:ellipsize="marquee"
android:singleLine="true"
android:layout_height="wrap_content"
android:textSize="13dp"
android:textColor="@color/abc_secondary_text_material_dark"
tools:text="Repeat No and Type"/>
</LinearLayout>
<ImageView android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:src="@drawable/ic_notifications_off"
android:layout_centerVertical="true"
android:id="@+id/active_image"/>
</RelativeLayout>
\ No newline at end of file
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.sudogeeks.talking_reminder.MainActivity">
<item
android:id="@+id/sign_out"
android:orderInCategory="100"
android:title="@string/sign_out"
app:showAsAction="never" />
</menu>
\ No newline at end of file
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/discard_reminder"
android:icon="@drawable/ic_delete_white"
android:title="@string/action_discard_reminder"
app:showAsAction="ifRoom" />
<item android:id="@+id/send_reminder"
android:icon="@drawable/ic_send"
android:title="@string/action_discard_reminder"
app:showAsAction="ifRoom" />
<item android:id="@+id/save_reminder"
android:icon="@drawable/ic_save_white"
android:title="@string/action_save_reminder"
app:showAsAction="ifRoom" />
</menu>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/save_reminder"
android:icon="@drawable/ic_save_white"
android:title="@string/action_save_reminder"
app:showAsAction="ifRoom" />
</menu>
\ No newline at end of file
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<item name="windowActionModeOverlay">true</item>
<item name="android:actionModeBackground">@color/primary</item>
</style>
</resources>
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/primary_dark</item>
<item name="android:actionBarPopupTheme">@style/ThemeOverlay.AppCompat</item>
<item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
<item name="android:windowSharedElementExitTransition">@android:transition/move</item>
<item name="windowActionModeOverlay">true</item>
<item name="android:actionModeBackground">@color/primary</item>
</style>
</resources>
<resources>
<color name="primary">#008577</color>
<color name="primary_dark">#00574B</color>
<color name="accent">#D81B60</color>
<color name="textheader">#ffffff</color>
<color name="textbody">#000000</color>
</resources>
\ No newline at end of file
<resources>
<string name="app_name">Talking Reminder</string>
<string name="activity_add_reminder_label">Add Reminder</string>
<string name="activity_edit_reminder_label">Edit Reminder</string>
<string name="add_reminder">Reminder</string>
<string name="details">Details</string>
<string name="date">Date</string>
<string name="time">Time</string>
<string name="repeat">Repeat</string>
<string name="repeat_off">Off</string>
<string name="repeat_no">Repetition Interval </string>
<string name="repeat_type">Type of Repetitions</string>
<string name="action_discard_reminder">Discard Reminder</string>
<string name="action_save_reminder">Save Reminder</string>
<string name="no_reminders">Click on the plus button below to begin creating your reminderDOS!</string>
<string name="sign_out">sign_out</string>
</resources>
<resources>
<!-- Base application theme. -->
<!-- <style name="AppTheme" parent="AppTheme.Base"/>-->
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.Base" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="colorAccent">@color/accent</item>
<item name="actionModeBackground">@color/primary</item>
<item name="actionBarPopupTheme">@style/ThemeOverlay.AppCompat</item>
<item name="android:windowNoTitle">true</item>
<item name="windowActionModeOverlay">true</item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<root-path
name="root"
path="." />
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<cache-path
name="cache"
path="." />
<external-cache-path
name="external_cache"
path="." />
<files-path
name="files"
path="." />
</paths>
\ No newline at end of file
## Compiled JavaScript files
**/*.js
**/*.js.map
# Typescript v1 declaration files
typings/
node_modules/
\ No newline at end of file
This diff is collapsed.
{
"name": "functions",
"scripts": {
"lint": "tslint --project tsconfig.json",
"build": "tsc",
"serve": "npm run build && firebase serve --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^8.6.0",
"firebase-functions": "^3.3.0"
},
"devDependencies": {
"tslint": "^5.12.0",
"typescript": "^3.2.2",
"firebase-functions-test": "^0.1.6"
},
"private": true
}
import * as functions from 'firebase-functions';
// // Start writing Firebase Functions
// // https://firebase.google.com/docs/functions/typescript
//
// export const helloWorld = functions.https.onRequest((request, response) => {
// response.send("Hello from Firebase!");
// });
export const onMessageCreate = function.database
.ref('/rooms/{roomid}/message/{messageid}')
.onCreate((snapshot,context)=>{
const roomId=context.params.roomId
const messageId=context.params.messageId
const messageData=snapshot.val()
const text=addpizzazz(messageData.text)
return snapshot.ref.update({text: text})
})
function addpizzazz(text : string): string{
return text.replace()
}
export const onMessageUpdate = function.database
.ref('/rooms/{roomid}/message/{messageid}')
.onUpdate((change,context)=>{
const before=change.before.val()
const after=change.after.val()
if (before.text===after.text){
return null
}
const text=addpizzazz(after.text)
const timeedited=Date.now()
return chnage.after.ref.update({text: text})
})
function addpizzazz(text : string): string{
return text.replace()
}
/////////////////////////////////////////////////////////////////////
export const onMessageCreate = function.database
.ref('/rooms/{roomid}/message/{messageid}')
.onCreate(async (snapshot,context)=>{
const roomId=context.params.roomId
const messageId=context.params.messageId
const messageData=snapshot.val()
const text=addpizzazz(messageData.text)
await snapshot.ref.update({text: text})
const countRef=snapshot.ref.parent.parent.child('messageCount')
return countRef.transaction(count=>{
return count+1
})
})
export const onMessageDelete = function.database
.ref('/rooms/{roomid}/message/{messageid}')
.onDelete(async (snapshot,context)=>{
const countRef=snapshot.ref.parent.parent.child('messageCount')
return countRef.transaction(count=>{
return count-1
})
})
{
"compilerOptions": {
"module": "commonjs",
"noImplicitReturns": true,
"noUnusedLocals": true,
"outDir": "lib",
"sourceMap": true,
"strict": true,
"target": "es2017"
},
"compileOnSave": true,
"include": [
"src"
]
}
{
"rules": {
// -- Strict errors --
// These lint rules are likely always a good idea.
// Force function overloads to be declared together. This ensures readers understand APIs.
"adjacent-overload-signatures": true,
// Do not allow the subtle/obscure comma operator.
"ban-comma-operator": true,
// Do not allow internal modules or namespaces . These are deprecated in favor of ES6 modules.
"no-namespace": true,
// Do not allow parameters to be reassigned. To avoid bugs, developers should instead assign new values to new vars.
"no-parameter-reassignment": true,
// Force the use of ES6-style imports instead of /// <reference path=> imports.
"no-reference": true,
// Do not allow type assertions that do nothing. This is a big warning that the developer may not understand the
// code currently being edited (they may be incorrectly handling a different type case that does not exist).
"no-unnecessary-type-assertion": true,
// Disallow nonsensical label usage.
"label-position": true,
// Disallows the (often typo) syntax if (var1 = var2). Replace with if (var2) { var1 = var2 }.
"no-conditional-assignment": true,
// Disallows constructors for primitive types (e.g. new Number('123'), though Number('123') is still allowed).
"no-construct": true,
// Do not allow super() to be called twice in a constructor.
"no-duplicate-super": true,
// Do not allow the same case to appear more than once in a switch block.
"no-duplicate-switch-case": true,
// Do not allow a variable to be declared more than once in the same block. Consider function parameters in this
// rule.
"no-duplicate-variable": [true, "check-parameters"],
// Disallows a variable definition in an inner scope from shadowing a variable in an outer scope. Developers should
// instead use a separate variable name.
"no-shadowed-variable": true,
// Empty blocks are almost never needed. Allow the one general exception: empty catch blocks.
"no-empty": [true, "allow-empty-catch"],
// Functions must either be handled directly (e.g. with a catch() handler) or returned to another function.
// This is a major source of errors in Cloud Functions and the team strongly recommends leaving this rule on.
"no-floating-promises": true,
// Do not allow any imports for modules that are not in package.json. These will almost certainly fail when
// deployed.
"no-implicit-dependencies": true,
// The 'this' keyword can only be used inside of classes.
"no-invalid-this": true,
// Do not allow strings to be thrown because they will not include stack traces. Throw Errors instead.
"no-string-throw": true,
// Disallow control flow statements, such as return, continue, break, and throw in finally blocks.
"no-unsafe-finally": true,
// Expressions must always return a value. Avoids common errors like const myValue = functionReturningVoid();
"no-void-expression": [true, "ignore-arrow-function-shorthand"],
// Disallow duplicate imports in the same file.
"no-duplicate-imports": true,
// -- Strong Warnings --
// These rules should almost never be needed, but may be included due to legacy code.
// They are left as a warning to avoid frustration with blocked deploys when the developer
// understand the warning and wants to deploy anyway.
// Warn when an empty interface is defined. These are generally not useful.
"no-empty-interface": {"severity": "warning"},
// Warn when an import will have side effects.
"no-import-side-effect": {"severity": "warning"},
// Warn when variables are defined with var. Var has subtle meaning that can lead to bugs. Strongly prefer const for
// most values and let for values that will change.
"no-var-keyword": {"severity": "warning"},
// Prefer === and !== over == and !=. The latter operators support overloads that are often accidental.
"triple-equals": {"severity": "warning"},
// Warn when using deprecated APIs.
"deprecation": {"severity": "warning"},
// -- Light Warnings --
// These rules are intended to help developers use better style. Simpler code has fewer bugs. These would be "info"
// if TSLint supported such a level.
// prefer for( ... of ... ) to an index loop when the index is only used to fetch an object from an array.
// (Even better: check out utils like .map if transforming an array!)
"prefer-for-of": {"severity": "warning"},
// Warns if function overloads could be unified into a single function with optional or rest parameters.
"unified-signatures": {"severity": "warning"},
// Prefer const for values that will not change. This better documents code.
"prefer-const": {"severity": "warning"},
// Multi-line object literals and function calls should have a trailing comma. This helps avoid merge conflicts.
"trailing-comma": {"severity": "warning"}
},
"defaultSeverity": "error"
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment