diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..603b140
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..986feec
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,64 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.3"
+
+ defaultConfig {
+ applicationId "com.javinator9889.handwashingreminder"
+ minSdkVersion 14
+ targetSdkVersion 29
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ debug {
+ ext.enableCrashliytics = false
+ applicationIdSuffix ".debug"
+ debuggable true
+ }
+ release {
+ minifyEnabled true
+ shrinkResources true
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ dexOptions {
+ preDexLibraries true
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation 'androidx.core:core-ktx:1.2.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'
+
+ // https://github.com/Javinator9889/LocaleManager
+ implementation 'com.github.javinator9889:localemanager:1.1X'
+ // https://material.io/develop/android/docs/getting-started/
+ implementation 'com.google.android.material:material:1.1.0'
+ // https://developers.google.com/android/guides/setup
+ implementation 'com.google.android.gms:play-services-location:17.0.0'
+ // https://developer.android.com/jetpack/androidx/releases/annotation
+ implementation 'androidx.annotation:annotation:1.1.0'
+ // https://github.com/AppIntro/AppIntro
+ implementation 'com.github.AppIntro:AppIntro:5.1.0'
+ // https://github.com/andkulikov/Transitions-Everywhere
+ implementation "com.andkulikov:transitionseverywhere:2.1.0"
+ // https://developer.android.com/jetpack/androidx/releases/cardview
+ implementation "androidx.cardview:cardview:1.0.0"
+ // https://developer.android.com/jetpack/androidx/releases/recyclerview
+ implementation "androidx.recyclerview:recyclerview:1.1.0"
+ // https://developer.android.com/studio/build/multidex
+ implementation 'androidx.multidex:multidex:2.0.1'
+}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# 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 *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/androidTest/java/com/javinator9889/handwashingreminder/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/javinator9889/handwashingreminder/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..b95b032
--- /dev/null
+++ b/app/src/androidTest/java/com/javinator9889/handwashingreminder/ExampleInstrumentedTest.kt
@@ -0,0 +1,26 @@
+package com.javinator9889.handwashingreminder
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext =
+ InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals(
+ "com.javinator9889.handwashingreminder",
+ appContext.packageName
+ )
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..24cfe58
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/ic_handwashing_icon.zip b/app/src/main/ic_handwashing_icon.zip
new file mode 100644
index 0000000..8225edc
Binary files /dev/null and b/app/src/main/ic_handwashing_icon.zip differ
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
new file mode 100644
index 0000000..792fe43
Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/application/HandwashingApplication.kt b/app/src/main/java/com/javinator9889/handwashingreminder/application/HandwashingApplication.kt
new file mode 100644
index 0000000..19b06f2
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/application/HandwashingApplication.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 15/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.application
+
+import android.content.Context
+import android.content.SharedPreferences
+import androidx.multidex.MultiDex
+import javinator9889.localemanager.application.BaseApplication
+import javinator9889.localemanager.utils.languagesupport.LanguagesSupport.Language
+
+
+class HandwashingApplication : BaseApplication() {
+ private lateinit var sharedPreferences: SharedPreferences
+
+ companion object {
+ private lateinit var instance: HandwashingApplication
+
+ fun getInstance(): HandwashingApplication {
+ return this.instance
+ }
+ }
+
+ override fun attachBaseContext(base: Context?) {
+ super.attachBaseContext(base)
+ MultiDex.install(this)
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ override fun onCreate() {
+ super.onCreate()
+ instance = this
+ sharedPreferences = getCustomSharedPreferences(this)!!
+ }
+
+ /**
+ * Obtains the initialized shared preferences.
+ */
+ fun getSharedPreferences(): SharedPreferences {
+ return sharedPreferences
+ }
+
+ /**
+ * Updates the application language
+ * @param language a valid language code.
+ * @see Language
+ */
+ fun setNewLocale(@Language language: String) {
+ localeManager.setNewLocale(this, language)
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ override fun getCustomSharedPreferences(base: Context): SharedPreferences? {
+ return base.getSharedPreferences(
+ "handwasingreminder.prefs",
+ Context.MODE_PRIVATE
+ )
+ }
+}
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/gms/activity/ActivityHandler.kt b/app/src/main/java/com/javinator9889/handwashingreminder/gms/activity/ActivityHandler.kt
new file mode 100644
index 0000000..8ee5252
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/gms/activity/ActivityHandler.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 15/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.gms.activity
+
+import android.app.PendingIntent
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.util.Log
+import com.google.android.gms.location.*
+import com.google.android.gms.tasks.Task
+import com.javinator9889.handwashingreminder.R
+import com.javinator9889.handwashingreminder.notifications.NotificationsHandler
+import com.javinator9889.handwashingreminder.utils.ACTIVITY_CHANNEL_ID
+
+class ActivityHandler(private val context: Context) : BroadcastReceiver() {
+ private val requestCode = 51824210
+ private val tag = "ActivityHandler"
+ private val transitions: MutableList = mutableListOf()
+ private var task: Task
+ private val pendingIntent: PendingIntent
+ private var activityRegistered = false
+
+ init {
+ val activitiesSet = setOf(
+ DetectedActivity.IN_VEHICLE,
+ DetectedActivity.ON_BICYCLE,
+ DetectedActivity.RUNNING,
+ DetectedActivity.WALKING
+ )
+ addTransitions(activitiesSet, transitions)
+
+ val intent = Intent(context, this::class.java)
+ pendingIntent = PendingIntent.getBroadcast(
+ context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT
+ )
+ val request = ActivityTransitionRequest(transitions)
+ task = ActivityRecognition.getClient(context)
+ .requestActivityTransitionUpdates(request, pendingIntent)
+ task.addOnSuccessListener { activityRegistered = true }
+ task.addOnFailureListener { activityRegistered = false }
+ }
+
+ private fun addTransitions(
+ activitiesSet: Set,
+ transitions: MutableList,
+ activityTransition: Int = ActivityTransition.ACTIVITY_TRANSITION_EXIT
+ ) {
+ for (activity in activitiesSet) {
+ transitions += ActivityTransition.Builder()
+ .setActivityType(activity)
+ .setActivityTransition(activityTransition)
+ .build()
+ }
+ }
+
+ fun disableActivityTracker() {
+ task = ActivityRecognition.getClient(context)
+ .removeActivityTransitionUpdates(pendingIntent)
+ task.addOnSuccessListener { pendingIntent.cancel() }
+ task.addOnFailureListener { e: Exception -> Log.e(tag, e.message, e) }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ override fun onReceive(context: Context?, intent: Intent?) {
+ if (ActivityTransitionResult.hasResult(intent)) {
+ val result = ActivityTransitionResult.extractResult(intent)!!
+ for (event in result.transitionEvents) {
+ if (event.transitionType !=
+ ActivityTransition.ACTIVITY_TRANSITION_EXIT ||
+ event.activityType == DetectedActivity.UNKNOWN
+ )
+ continue
+ val notificationHandler = NotificationsHandler(
+ this.context,
+ ACTIVITY_CHANNEL_ID,
+ this.context.getString(
+ R.string
+ .activity_notification_channel_name
+ ),
+ this.context.getString(
+ R.string
+ .activity_notification_channel_desc
+ )
+ )
+ notificationHandler.createNotification(
+ R.drawable.ic_handwashing_icon,
+ R.drawable.handwashing_app_logo,
+ R.string.test_notification,
+ R.string.test_content
+ )
+ break
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/notifications/NotificationsHandler.kt b/app/src/main/java/com/javinator9889/handwashingreminder/notifications/NotificationsHandler.kt
new file mode 100644
index 0000000..987e79a
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/notifications/NotificationsHandler.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 15/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.notifications
+
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Context
+import android.content.SharedPreferences
+import android.graphics.BitmapFactory
+import android.graphics.ImageDecoder
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import com.javinator9889.handwashingreminder.application.HandwashingApplication
+import com.javinator9889.handwashingreminder.utils.AndroidVersion
+import com.javinator9889.handwashingreminder.utils.Preferences
+import com.javinator9889.handwashingreminder.utils.isAtLeast
+
+class NotificationsHandler(
+ private val context: Context,
+ private val channelId: String,
+ private val channelName: String = "",
+ private val channelDesc: String = ""
+) {
+ private val preferences: SharedPreferences =
+ HandwashingApplication.getInstance().getSharedPreferences()
+ private val notificationId = 1
+
+ init {
+ if (isNotificationChannelCreated() || createChannelRequired()) {
+ createNotificationChannel()
+ val editor = preferences.edit()
+ editor.putBoolean(Preferences.CREATE_CHANNEL_KEY, false)
+ editor.apply()
+ }
+ }
+
+ fun createNotification(
+ @DrawableRes iconDrawable: Int,
+ @DrawableRes largeIcon: Int,
+ @StringRes title: Int,
+ @StringRes content: Int,
+ priority: Int = NotificationCompat.PRIORITY_DEFAULT,
+ @StringRes longContent: Int = -1
+ ) {
+ val bitmapIcon = if (isAtLeast(AndroidVersion.JELLY_BEAN_MR2)) {
+ if (isAtLeast(AndroidVersion.P)) {
+ val source =
+ ImageDecoder.createSource(context.resources, largeIcon)
+ ImageDecoder.decodeBitmap(source)
+ } else {
+ BitmapFactory.decodeResource(
+ context.resources,
+ largeIcon
+ )
+ }
+ } else {
+ null
+ }
+ val builder = NotificationCompat.Builder(context, channelId)
+ .setSmallIcon(iconDrawable)
+ .setLargeIcon(bitmapIcon)
+ .setContentTitle(context.getText(title))
+ .setContentText(context.getText(content))
+ .setPriority(priority)
+ if (longContent != -1) {
+ builder.setStyle(
+ NotificationCompat.BigTextStyle()
+ .bigText(context.getText(longContent))
+ )
+ }
+
+ with(NotificationManagerCompat.from(context)) {
+ notify(notificationId, builder.build())
+ }
+ }
+
+ private fun createNotificationChannel() {
+ if (isAtLeast(AndroidVersion.O)) {
+ val importance = NotificationManager.IMPORTANCE_DEFAULT
+ val channel =
+ NotificationChannel(channelId, channelName, importance)
+ .apply { description = channelDesc }
+ val notificationManager: NotificationManager =
+ context.getSystemService(Context.NOTIFICATION_SERVICE) as
+ NotificationManager
+ notificationManager.createNotificationChannel(channel)
+ }
+ }
+
+ private fun isNotificationChannelCreated(): Boolean {
+ if (isAtLeast(AndroidVersion.O)) {
+ val manager = context
+ .getSystemService(Context.NOTIFICATION_SERVICE) as
+ NotificationManager
+ val channel = manager.getNotificationChannel(channelId)
+ channel?.let {
+ return it.importance != NotificationManager.IMPORTANCE_NONE
+ } ?: return false
+ } else {
+ return NotificationManagerCompat.from(context)
+ .areNotificationsEnabled()
+ }
+ }
+
+ private fun createChannelRequired(): Boolean {
+ return preferences.getBoolean(Preferences.CREATE_CHANNEL_KEY, true)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/utils/AndroidVersion.kt b/app/src/main/java/com/javinator9889/handwashingreminder/utils/AndroidVersion.kt
new file mode 100644
index 0000000..58446a9
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/utils/AndroidVersion.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 16/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.utils
+
+enum class AndroidVersion(val code: Int) {
+ BASE(1),
+ BASE_1_1(2),
+ CUPCAKE(3),
+ DONUT(4),
+ ECLAIR(5),
+ ECLAIR_0_1(6),
+ ECLAIR_MR1(7),
+ FROYO(8),
+ GINGERBREAD(9),
+ GINGERBREAD_MR1(10),
+ HONEYCOMB(11),
+ HONEYCOMB_MR1(12),
+ HONEYCOMB_MR2(13),
+ ICE_CREAM_SANDWICH(14),
+ ICE_CREAM_SANDWICH_MR1(15),
+ JELLY_BEAN(16),
+ JELLY_BEAN_MR1(17),
+ JELLY_BEAN_MR2(18),
+ KITKAT(19),
+ KITKAT_WATCH(20),
+ L(21),
+ LOLLIPOP(21),
+ LOLLIPOP_MR1(22),
+ M(23),
+ N(24),
+ N_MR1(25),
+ O(26),
+ O_MR1(27),
+ P(28),
+ Q(29)
+}
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/utils/Constants.kt b/app/src/main/java/com/javinator9889/handwashingreminder/utils/Constants.kt
new file mode 100644
index 0000000..2d06929
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/utils/Constants.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 15/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.utils
+
+import android.os.Build
+import com.javinator9889.handwashingreminder.application.HandwashingApplication
+
+const val TIME_CHANNEL_ID = "timeNotificationsChannel"
+const val ACTIVITY_CHANNEL_ID = "activityNotificationsChannel"
+
+class Preferences {
+ companion object {
+ const val CREATE_CHANNEL_KEY = "create_channel_req"
+ }
+}
+
+fun isAtLeast(version: AndroidVersion): Boolean {
+ return Build.VERSION.SDK_INT >= version.code
+}
+
+/**
+ * This method converts dp unit to equivalent pixels, depending on device density.
+ *
+ * @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
+ * @return A float value to represent px equivalent to dp depending on device density
+ */
+fun dpToPx(dp: Float): Float {
+ val context = HandwashingApplication.getInstance().applicationContext
+ return dp * context.resources.displayMetrics.density
+}
+
+/**
+ * This method converts device specific pixels to density independent pixels.
+ *
+ * @param px A value in px (pixels) unit. Which we need to convert into db
+ * @return A float value to represent dp equivalent to px value
+ */
+fun pxToDp(px: Float): Float {
+ val context = HandwashingApplication.getInstance().applicationContext
+ return px / context.resources.displayMetrics.density
+}
+
+class TimeConfig {
+ companion object {
+ const val BREAKFAST_ID = 0L
+ const val LUNCH_ID = 1L
+ const val DINNER_ID = 2L
+ }
+}
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/MainActivity.kt b/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/MainActivity.kt
new file mode 100644
index 0000000..c98c989
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/MainActivity.kt
@@ -0,0 +1,212 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 15/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.views.activities
+
+import android.annotation.SuppressLint
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Context
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.widget.ProgressBar
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.javinator9889.handwashingreminder.R
+import com.javinator9889.handwashingreminder.application.HandwashingApplication
+import com.javinator9889.handwashingreminder.utils.AndroidVersion
+import com.javinator9889.handwashingreminder.utils.isAtLeast
+import com.javinator9889.handwashingreminder.views.custom.TimeConfigAdapter
+import com.javinator9889.handwashingreminder.views.custom.TimeConfigContent
+import javinator9889.localemanager.activity.BaseAppCompatActivity
+import kotlin.concurrent.thread
+
+class MainActivity : BaseAppCompatActivity() {
+ private lateinit var app: HandwashingApplication
+
+ // private lateinit var button: Button
+ private lateinit var progressBar: ProgressBar
+ private lateinit var pgThread: Thread
+
+ /*private lateinit var fusedLocationProviderClient:
+ FusedLocationProviderClient
+ private lateinit var hours: EditText
+ private lateinit var minutes: EditText
+ private lateinit var container: ConstraintLayout*/
+ private lateinit var recyclerView: RecyclerView
+ private lateinit var viewAdapter: RecyclerView.Adapter<*>
+ private lateinit var viewManager: RecyclerView.LayoutManager
+
+ @SuppressLint("ClickableViewAccessibility")
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.time_config)
+ app = HandwashingApplication.getInstance()
+
+// val dataset = arrayOf("Desayuno", "Comida", "Cena")
+ val dataset = arrayOf(
+ TimeConfigContent("Desayuno", 0L),
+ TimeConfigContent("Comida", 1L), TimeConfigContent("Cena", 2L)
+ )
+ val display = windowManager.defaultDisplay
+ val size = Point()
+ display.getSize(size)
+ viewManager = LinearLayoutManager(this)
+ viewAdapter = TimeConfigAdapter(
+ dataset,
+ null,
+ size.y - (actionBar?.height ?: 0)
+ )
+
+ recyclerView = findViewById(R.id.cardsView).apply {
+ setHasFixedSize(true)
+ layoutManager = viewManager
+ adapter = viewAdapter
+ }
+// hours = findViewById(R.id.hours)
+// minutes = findViewById(R.id.minutes)
+// container = findViewById(R.id.timeCtr)
+//
+// hours.setOnClickListener(this)
+// minutes.setOnClickListener(this)
+// container.setOnClickListener(this)
+ /*button = findViewById(R.id.button)
+ progressBar = findViewById(R.id.progressBar)
+ button.setOnTouchListener(this)
+ fusedLocationProviderClient = LocationServices
+ .getFusedLocationProviderClient(this)
+ val permissionCheck = PermissionChecker
+ .checkCallingOrSelfPermission(
+ this,
+ Manifest.permission.ACCESS_FINE_LOCATION
+ ) or PermissionChecker.checkCallingOrSelfPermission(
+ this,
+ Manifest.permission.ACCESS_COARSE_LOCATION
+ )
+ if (permissionCheck != PERMISSION_GRANTED &&
+ isAtLeast(AndroidVersion.M)
+ ) {
+ requestPermissions(
+ arrayOf(
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION
+ ), 1000
+ )
+ }
+ val loc = LocationService()
+ loc.lat
+ loc.lon*/
+// button.setOnClickListener(this)
+ }
+
+ private fun runProgressBar() {
+ pgThread = thread(name = "pgthread") {
+ try {
+ for (i in progressBar.progress until 100) {
+ this@MainActivity.runOnUiThread {
+ progressBar.incrementProgressBy(1)
+ }
+ Thread.sleep(1000L)
+ }
+ } catch (_: InterruptedException) {
+ Log.i("Main", "Interrupted")
+ }
+ }
+ Log.i("Main", "${pgThread.isInterrupted} - ${pgThread.isAlive}")
+ if (pgThread.isInterrupted || !pgThread.isAlive) {
+ pgThread.start()
+ } else {
+ pgThread.interrupt()
+ }
+ }
+
+ /*override fun onTouch(view: View?, event: MotionEvent?): Boolean {
+ when (view) {
+ button -> {
+ when (event?.action) {
+ MotionEvent.ACTION_DOWN -> {
+ Log.i("Main", "Button clicked")
+ runProgressBar()
+ }
+ MotionEvent.ACTION_UP -> {
+ Log.i("Main", "Creating notification")
+ view.performClick()
+ val notificationHandler = NotificationsHandler(
+ this,
+ ACTIVITY_CHANNEL_ID,
+ getString(
+ R.string
+ .activity_notification_channel_name
+ ),
+ getString(
+ R.string
+ .activity_notification_channel_desc
+ )
+ )
+ notificationHandler.createNotification(
+ R.drawable.ic_handwashing_icon,
+ R.drawable.handwashing_app_logo,
+ R.string.test_notification,
+ R.string.test_content
+ )
+ }
+ }
+ }
+ else -> Log.e("Main", "Unexpected click: $view")
+ }
+ return view?.onTouchEvent(event) ?: true
+ }*/
+
+ private fun createNotificationChannel() {
+ if (isAtLeast(AndroidVersion.O)) {
+ val name = "Test notifications"
+ val descriptionText = "Channel for test notifications"
+ val importance = NotificationManager.IMPORTANCE_DEFAULT
+ val channel = NotificationChannel("tch", name, importance)
+ .apply { description = descriptionText }
+ val notificationManager: NotificationManager =
+ getSystemService(Context.NOTIFICATION_SERVICE) as
+ NotificationManager
+ notificationManager.createNotificationChannel(channel)
+ }
+ }
+
+ /*override fun onClick(v: View?) {
+ when (v) {
+ hours, minutes, container -> {
+ Log.i("Main", "Changing hours / minutes")
+ val cTime = Calendar.getInstance()
+ val cHour = cTime.get(Calendar.HOUR_OF_DAY)
+ val cMinute = cTime.get(Calendar.MINUTE)
+ val timePicker = TimePickerDialog(this, this, cHour, cMinute,
+ true)
+ timePicker.setTitle("Select an hour")
+ timePicker.show()
+ }
+ else -> {
+ Log.e("Main", "Unexpected view $v")
+ }
+ }
+ }*/
+
+ /*override fun onTimeSet(view: TimePicker?, hourOfDay: Int, minute: Int) {
+ hours.setText(hourOfDay.toString())
+ minutes.setText(minute.toString())
+ }*/
+}
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/config/TimeConfigActivity.kt b/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/config/TimeConfigActivity.kt
new file mode 100644
index 0000000..b4ae252
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/config/TimeConfigActivity.kt
@@ -0,0 +1,143 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 19/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.views.activities.config
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import android.widget.Button
+import android.widget.TextView
+import android.widget.TimePicker
+import com.javinator9889.handwashingreminder.R
+import com.javinator9889.handwashingreminder.utils.AndroidVersion
+import com.javinator9889.handwashingreminder.utils.isAtLeast
+import com.javinator9889.handwashingreminder.views.activities.support.ActionBarBase
+import java.util.*
+
+class TimeConfigActivity :
+ ActionBarBase(),
+ View.OnClickListener {
+ companion object {
+ const val VIEW_TITLE_NAME = "detail:header:title"
+ }
+
+ private lateinit var button: Button
+ private lateinit var title: TextView
+ private lateinit var timePicker: TimePicker
+
+ data class Time(val hour: Int, val minute: Int)
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+// setContentView(R.layout.time_card_view_expanded)
+
+ title = findViewById(R.id.title)
+ button = findViewById(R.id.doneButton)
+ timePicker = findViewById(R.id.timePicker)
+
+ timePicker.setIs24HourView(true)
+ button.setOnClickListener(this)
+ if (isAtLeast(AndroidVersion.LOLLIPOP))
+ title.transitionName = VIEW_TITLE_NAME
+// ViewCompat.setTransitionName(title, VIEW_TITLE_NAME)
+
+ if (savedInstanceState != null || intent.extras != null) {
+ val data = savedInstanceState ?: intent.extras
+ val sHours = data!!.getCharSequence("hours")
+ val sMinutes = data.getCharSequence("minutes")
+ title.text = data.getCharSequence("title")
+ setTimePickerHour(sHours.toString(), sMinutes.toString())
+ val id = data.getLong("id").toInt()
+ if (isAtLeast(AndroidVersion.LOLLIPOP)) {
+ val transitions = resources.getStringArray(R.array.transitions)
+ val transitionName = transitions[id]
+ title.transitionName = transitionName
+ }
+ }
+ }
+
+ override fun getLayoutId(): Int = R.layout.time_card_view_expanded
+
+ private fun setTimePickerHour(hours: String, minutes: String) {
+ val tpHour: Int
+ val tpMinute: Int
+ if (hours == "" || minutes == "") {
+ val date = Calendar.getInstance()
+ tpHour = date.get(Calendar.HOUR_OF_DAY)
+ tpMinute = date.get(Calendar.MINUTE)
+ } else {
+ tpHour = Integer.parseInt(hours)
+ tpMinute = Integer.parseInt(minutes)
+ }
+ if (isAtLeast(AndroidVersion.M)) {
+ timePicker.hour = tpHour
+ timePicker.minute = tpMinute
+ } else {
+ timePicker.currentHour = tpHour
+ timePicker.currentMinute = tpMinute
+ }
+ }
+
+ private fun getTimePickerHour(): Time {
+ val tpHour: Int
+ val tpMinute: Int
+ if (isAtLeast(AndroidVersion.M)) {
+ tpHour = timePicker.hour
+ tpMinute = timePicker.minute
+ } else {
+ tpHour = timePicker.currentHour
+ tpMinute = timePicker.currentMinute
+ }
+ return Time(tpHour, tpMinute)
+ }
+
+ private fun formatTime(time: Int): String {
+ return if (time < 10) "0$time" else time.toString()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ val tpTime = getTimePickerHour()
+ val hour = formatTime(tpTime.hour)
+ val minute = formatTime(tpTime.minute)
+ outState.putCharSequence("hours", hour)
+ outState.putCharSequence("minutes", minute)
+ outState.putCharSequence("title", title.text)
+ }
+
+ override fun onBackPressed() {
+ val intent = Intent()
+ val tpTime = getTimePickerHour()
+ intent.putExtra("hours", formatTime(tpTime.hour))
+ intent.putExtra("minutes", formatTime(tpTime.minute))
+ setResult(Activity.RESULT_OK, intent)
+ if (isAtLeast(AndroidVersion.LOLLIPOP))
+ finishAfterTransition()
+ else
+ finish()
+ super.onBackPressed()
+ }
+
+ override fun onClick(v: View?) {
+ when (v) {
+ button -> this.onBackPressed()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/intro/IntroActivity.kt b/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/intro/IntroActivity.kt
new file mode 100644
index 0000000..68d4e70
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/intro/IntroActivity.kt
@@ -0,0 +1,184 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 16/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.views.activities.intro
+
+import android.content.Intent
+import android.graphics.Color
+import android.graphics.Point
+import android.os.Bundle
+import android.util.Log
+import android.view.View
+import android.widget.AdapterView
+import android.widget.TextView
+import androidx.core.app.ActivityCompat
+import androidx.core.app.ActivityOptionsCompat
+import androidx.core.util.Pair
+import androidx.fragment.app.Fragment
+import com.github.paolorotolo.appintro.AppIntro2
+import com.github.paolorotolo.appintro.AppIntro2Fragment
+import com.github.paolorotolo.appintro.model.SliderPage
+import com.javinator9889.handwashingreminder.R
+import com.javinator9889.handwashingreminder.utils.AndroidVersion
+import com.javinator9889.handwashingreminder.utils.TimeConfig
+import com.javinator9889.handwashingreminder.utils.isAtLeast
+import com.javinator9889.handwashingreminder.views.activities.MainActivity
+import com.javinator9889.handwashingreminder.views.activities.config.TimeConfigActivity
+
+class IntroActivity : AppIntro2(), AdapterView.OnItemClickListener {
+ private val views = HashMap(3)
+ private lateinit var transitions: Array
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+// supportActionBar?.hide()
+ transitions = resources.getStringArray(R.array.transitions)
+// setSwipeLock(false)
+
+ val sliderPage = SliderPage()
+ sliderPage.title = "First page"
+ sliderPage.description = "First page description"
+ sliderPage.imageDrawable = R.drawable.handwashing_app_logo
+ sliderPage.bgColor = Color.WHITE
+ sliderPage.titleColor = Color.DKGRAY
+ sliderPage.descColor = Color.DKGRAY
+ addSlide(AppIntro2Fragment.newInstance(sliderPage))
+
+ val sliderPage2 = SliderPage()
+ sliderPage2.title = "Second page"
+ sliderPage2.description = "Second page description"
+ sliderPage2.imageDrawable = R.drawable.handwashing_app_logo
+ sliderPage2.bgColor = Color.WHITE
+ sliderPage2.titleColor = Color.DKGRAY
+ sliderPage2.descColor = Color.DKGRAY
+ addSlide(AppIntro2Fragment.newInstance(sliderPage2))
+
+ val sliderPage3 = SliderPage()
+ sliderPage3.title = "Third page"
+ sliderPage3.description = "Third page description"
+ sliderPage3.imageDrawable = R.drawable.ic_handwashing_icon
+ sliderPage3.bgColor = Color.WHITE
+ sliderPage3.titleColor = Color.DKGRAY
+ sliderPage3.descColor = Color.DKGRAY
+ addSlide(AppIntro2Fragment.newInstance(sliderPage3))
+
+ val sliderPage4 = TimeConfigIntroActivity()
+ val display = windowManager.defaultDisplay
+ val size = Point()
+ display.getSize(size)
+ sliderPage4.height = size.y - 80
+ sliderPage4.bgColor = Color.WHITE
+ sliderPage4.listener = this
+ sliderPage4.fromActivity = this
+ addSlide(sliderPage4)
+
+ showSkipButton(false)
+ showStatusBar(true)
+ backButtonVisibilityWithDone = true;
+ setIndicatorColor(Color.DKGRAY, Color.GRAY);
+// setNavBarColor("#2196F3")
+// setBarColor(getColor(R.color.colorPrimary));
+// setNavBarColor(R.color.white)
+// val stackTransformer = StackTransformer()
+// setCustomTransformer(stackTransformer)
+
+// askForPermissions(arrayOf(Manifest.permission.ACTIVITY_RECOGNITION), 3)
+// setDepthAnimation()
+ }
+
+ override fun onDonePressed(currentFragment: Fragment?) {
+ super.onDonePressed(currentFragment)
+ val intent = Intent(this, MainActivity::class.java)
+ startActivity(intent)
+ this.finish()
+ }
+
+ override fun onItemClick(
+ parent: AdapterView<*>?,
+ view: View?,
+ position: Int,
+ id: Long
+ ) {
+ if (view == null)
+ return
+ Log.d("Intro", view.toString())
+ views[id.toInt()] = view
+ val intent = Intent(this, TimeConfigActivity::class.java)
+ val title = view.findViewById(R.id.title)
+ Log.d("Intro", title.toString())
+ Log.d("Intro", title.text.toString())
+ val options = if (isAtLeast(AndroidVersion.LOLLIPOP)) {
+// title.transitionName = TimeConfigActivity.VIEW_TITLE_NAME
+// ActivityOptionsCompat.makeSceneTransitionAnimation(
+// this, title, TimeConfigActivity.VIEW_TITLE_NAME
+// )
+ ActivityOptionsCompat.makeSceneTransitionAnimation(
+ this,
+ Pair.create(title, TimeConfigActivity.VIEW_TITLE_NAME)
+ )
+ /*ActivityOptionsCompat
+ .makeSceneTransitionAnimation(
+ this, Pair(
+ title,
+ TimeConfigActivity.VIEW_TITLE_NAME
+ )
+ )*/
+ } else {
+ null
+ }
+ intent.putExtra(
+ "title", view.findViewById(R.id.title).text
+ )
+ intent.putExtra(
+ "hours", view.findViewById(R.id.hours).text
+ )
+ intent.putExtra(
+ "minutes", view.findViewById(R.id.minutes).text
+ )
+ intent.putExtra("id", id)
+ ActivityCompat.startActivityForResult(
+ this, intent, id.toInt(), options?.toBundle()
+ )
+ }
+
+ override fun onActivityResult(
+ requestCode: Int,
+ resultCode: Int,
+ data: Intent?
+ ) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if (data == null)
+ return
+ val view = when (requestCode.toLong()) {
+ TimeConfig.BREAKFAST_ID -> {
+ views[TimeConfig.BREAKFAST_ID.toInt()]
+ }
+ TimeConfig.LUNCH_ID -> {
+ views[TimeConfig.LUNCH_ID.toInt()]
+ }
+ TimeConfig.DINNER_ID -> {
+ views[TimeConfig.DINNER_ID.toInt()]
+ }
+ else -> null
+ }
+ view?.findViewById(R.id.hours)?.text =
+ data.getStringExtra("hours")
+ view?.findViewById(R.id.minutes)?.text =
+ data.getStringExtra("minutes")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/intro/TimeConfigIntroActivity.kt b/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/intro/TimeConfigIntroActivity.kt
new file mode 100644
index 0000000..eb1eab0
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/intro/TimeConfigIntroActivity.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 19/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.views.activities.intro
+
+import android.graphics.Color
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.AdapterView
+import androidx.appcompat.app.AppCompatActivity
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.github.paolorotolo.appintro.AppIntroBaseFragment
+import com.javinator9889.handwashingreminder.R
+import com.javinator9889.handwashingreminder.utils.TimeConfig
+import com.javinator9889.handwashingreminder.views.custom.TimeConfigAdapter
+import com.javinator9889.handwashingreminder.views.custom.TimeConfigContent
+
+class TimeConfigIntroActivity : AppIntroBaseFragment() {
+ private lateinit var recyclerView: RecyclerView
+ private lateinit var rvAdapter: TimeConfigAdapter
+ private lateinit var rvItems: Array
+ lateinit var fromActivity: AppCompatActivity
+ var bgColor: Int = Color.WHITE
+ var listener: AdapterView.OnItemClickListener? = null
+ var height: Int = 0
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val breakfast = getString(R.string.breakfast)
+ val lunch = getString(R.string.lunch)
+ val dinner = getString(R.string.dinner)
+ rvItems = arrayOf(
+ TimeConfigContent(
+ getString(R.string.time_config_title_tpl, breakfast),
+ TimeConfig.BREAKFAST_ID
+ ), TimeConfigContent(
+ getString(R.string.time_config_title_tpl, lunch),
+ TimeConfig.LUNCH_ID
+ ), TimeConfigContent(
+ getString(R.string.time_config_title_tpl, dinner),
+ TimeConfig.DINNER_ID
+ )
+ )
+ rvAdapter = TimeConfigAdapter(rvItems, listener, height)
+ }
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ savedInstanceState?.let {
+ rvItems = it.getParcelableArray("rvItems")
+ as Array
+ }
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ outState.putParcelableArray("rvItems", rvItems)
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ val view = inflater.inflate(layoutId, container, false)
+ val rvManager = LinearLayoutManager(context)
+ fromActivity.setSupportActionBar(view.findViewById(R.id.toolbar))
+ recyclerView =
+ view.findViewById(R.id.cardsView).apply {
+ setHasFixedSize(true)
+ layoutManager = rvManager
+ adapter = rvAdapter
+ }
+ recyclerView.setBackgroundColor(bgColor)
+
+ return view
+ }
+
+ override fun getLayoutId(): Int = R.layout.time_config
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/support/ActionBarBase.kt b/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/support/ActionBarBase.kt
new file mode 100644
index 0000000..e03b259
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/views/activities/support/ActionBarBase.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 20/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.views.activities.support
+
+import android.os.Bundle
+import com.javinator9889.handwashingreminder.R
+import javinator9889.localemanager.activity.BaseAppCompatActivity
+
+abstract class ActionBarBase : BaseAppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(getLayoutId())
+ setSupportActionBar(findViewById(R.id.toolbar))
+ }
+
+ abstract fun getLayoutId(): Int
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/views/custom/TimeConfigAdapter.kt b/app/src/main/java/com/javinator9889/handwashingreminder/views/custom/TimeConfigAdapter.kt
new file mode 100644
index 0000000..391efeb
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/views/custom/TimeConfigAdapter.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 18/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.views.custom
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import android.widget.AdapterView
+import androidx.recyclerview.widget.RecyclerView
+import com.javinator9889.handwashingreminder.R
+
+class TimeConfigAdapter(
+ private val dataset: Array,
+ private val listener: AdapterView.OnItemClickListener?,
+ private val height: Int?
+) :
+ RecyclerView.Adapter() {
+ private lateinit var context: Context
+ private val items: ArrayList = ArrayList(3)
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): TimeConfigViewHolder {
+ context = parent.context
+ val timeConfig = LayoutInflater.from(parent.context)
+ .inflate(R.layout.time_card_view, parent, false)
+ val viewHolder = TimeConfigViewHolder(timeConfig)
+ if (!items.contains(viewHolder))
+ items.add(viewHolder)
+ return viewHolder
+ }
+
+ override fun onBindViewHolder(holder: TimeConfigViewHolder, position: Int) {
+ holder.bind(
+ dataset[position].title,
+ dataset[position].id,
+ listener,
+ height
+ )
+ }
+
+ override fun getItemCount(): Int = dataset.size
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/views/custom/TimeConfigContent.kt b/app/src/main/java/com/javinator9889/handwashingreminder/views/custom/TimeConfigContent.kt
new file mode 100644
index 0000000..2c8494c
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/views/custom/TimeConfigContent.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 18/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.views.custom
+
+import android.os.Parcel
+import android.os.Parcelable
+
+class TimeConfigContent(val title: String, val id: Long) : Parcelable {
+ constructor(parcel: Parcel) : this(
+ parcel.readString()!!, parcel.readLong()
+ )
+
+ override fun writeToParcel(parcel: Parcel, flags: Int) {
+ parcel.writeString(title)
+ parcel.writeLong(id)
+ }
+
+ override fun describeContents(): Int {
+ return 0
+ }
+
+ companion object CREATOR : Parcelable.Creator {
+ override fun createFromParcel(parcel: Parcel): TimeConfigContent {
+ return TimeConfigContent(parcel)
+ }
+
+ override fun newArray(size: Int): Array {
+ return arrayOfNulls(size)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/views/custom/TimeConfigViewHolder.kt b/app/src/main/java/com/javinator9889/handwashingreminder/views/custom/TimeConfigViewHolder.kt
new file mode 100644
index 0000000..542f4f2
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/views/custom/TimeConfigViewHolder.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 18/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.views.custom
+
+import android.view.View
+import android.widget.AdapterView
+import android.widget.TextView
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.recyclerview.widget.RecyclerView
+import com.google.android.material.card.MaterialCardView
+import com.javinator9889.handwashingreminder.R
+
+
+class TimeConfigViewHolder(val view: View) :
+ RecyclerView.ViewHolder(view),
+ View.OnClickListener {
+ val title: TextView = view.findViewById(R.id.title)
+ val hours: TextView = view.findViewById(R.id.hours)
+ val minutes: TextView = view.findViewById(R.id.minutes)
+ private val card = view.findViewById(R.id.timeCard)
+ private val container = view.findViewById(R.id.cardCtr)
+ private var listener: AdapterView.OnItemClickListener? = null
+ private var height: Int? = null
+ var id = 0L
+
+ init {
+ card.setOnClickListener(this)
+ title.setOnClickListener(this)
+ hours.setOnClickListener(this)
+ minutes.setOnClickListener(this)
+ }
+
+ override fun onClick(v: View?) {
+ when (v) {
+ card, title, hours, minutes -> this.listener?.onItemClick(
+ null,
+ card,
+ adapterPosition,
+ id
+ )
+ }
+ }
+
+ fun bind(
+ title: CharSequence,
+ id: Long,
+ listener: AdapterView.OnItemClickListener?,
+ height: Int?
+ ) {
+ this.id = id
+ this.title.text = title
+ this.listener = listener
+ this.height = height
+ adaptCardHeight()
+ }
+
+ private fun adaptCardHeight() {
+ if (height == null)
+ return
+ card.minimumHeight = height!! / 3
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/views/transforms/BaseTransform.kt b/app/src/main/java/com/javinator9889/handwashingreminder/views/transforms/BaseTransform.kt
new file mode 100644
index 0000000..c4a70bb
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/views/transforms/BaseTransform.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 16/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.views.transforms
+
+import android.view.View
+import androidx.viewpager.widget.ViewPager
+
+
+abstract class BaseTransform : ViewPager.PageTransformer {
+ /**
+ * Called each [.transformPage].
+ *
+ * @param view
+ * @param position
+ */
+ protected abstract fun onTransform(
+ view: View?,
+ position: Float
+ )
+
+ override fun transformPage(
+ view: View,
+ position: Float
+ ) {
+ onPreTransform(view, position)
+ onTransform(view, position)
+ }
+
+ /**
+ * If the position offset of a fragment is less than negative one or greater
+ * than one, returning true will set the
+ * visibility of the fragment to [android.view.View.GONE]. Returning false
+ * will force the fragment to [android.view.View.VISIBLE].
+ *
+ * @return
+ */
+ protected fun hideOffscreenPages(): Boolean {
+ return true
+ }
+
+ /**
+ * Indicates if the default animations of the view pager should be used.
+ *
+ * @return
+ */
+ protected val isPagingEnabled: Boolean
+ get() = false
+
+ /**
+ * Called each [.transformPage] before {[.onTransform] is called.
+ *
+ * @param view
+ * @param position
+ */
+ protected fun onPreTransform(
+ view: View,
+ position: Float
+ ) {
+ val width = view.width.toFloat()
+ view.rotationX = 0f
+ view.rotationY = 0f
+ view.rotation = 0f
+ view.scaleX = 1f
+ view.scaleY = 1f
+ view.pivotX = 0f
+ view.pivotY = 0f
+ view.translationY = 0f
+ view.translationX = if (isPagingEnabled) 0f else -width * position
+ if (hideOffscreenPages()) {
+ view.alpha = if (position <= -1f || position >= 1f) 0f else 1f
+ } else {
+ view.alpha = 1f
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/javinator9889/handwashingreminder/views/transforms/StackTransform.kt b/app/src/main/java/com/javinator9889/handwashingreminder/views/transforms/StackTransform.kt
new file mode 100644
index 0000000..c9ac14c
--- /dev/null
+++ b/app/src/main/java/com/javinator9889/handwashingreminder/views/transforms/StackTransform.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright © 2020 - present | Handwashing reminder by Javinator9889
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ *
+ * Created by Javinator9889 on 16/03/20 - Handwashing reminder.
+ */
+package com.javinator9889.handwashingreminder.views.transforms
+
+import android.view.View
+
+
+open class StackTransformer : BaseTransform() {
+ override fun onTransform(view: View?, position: Float) {
+ view?.let {
+ it.translationX = if (position < 0) 0F else -view.width * position
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/anim/zoom_in.xml b/app/src/main/res/anim/zoom_in.xml
new file mode 100644
index 0000000..2890539
--- /dev/null
+++ b/app/src/main/res/anim/zoom_in.xml
@@ -0,0 +1,11 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-hdpi/ic_handwashing_icon.png b/app/src/main/res/drawable-hdpi/ic_handwashing_icon.png
new file mode 100644
index 0000000..130e26f
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_handwashing_icon.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_handwashing_icon.png b/app/src/main/res/drawable-mdpi/ic_handwashing_icon.png
new file mode 100644
index 0000000..b62f695
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_handwashing_icon.png differ
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..83356a1
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,163 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable-xhdpi/ic_handwashing_icon.png b/app/src/main/res/drawable-xhdpi/ic_handwashing_icon.png
new file mode 100644
index 0000000..f5fdef7
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_handwashing_icon.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_handwashing_icon.png b/app/src/main/res/drawable-xxhdpi/ic_handwashing_icon.png
new file mode 100644
index 0000000..7ecb756
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_handwashing_icon.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_handwashing_icon.png b/app/src/main/res/drawable-xxxhdpi/ic_handwashing_icon.png
new file mode 100644
index 0000000..cac5996
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_handwashing_icon.png differ
diff --git a/app/src/main/res/drawable/handwashing_app_logo.webp b/app/src/main/res/drawable/handwashing_app_logo.webp
new file mode 100644
index 0000000..73c89e6
Binary files /dev/null and b/app/src/main/res/drawable/handwashing_app_logo.webp differ
diff --git a/app/src/main/res/drawable/ic_icon.xml b/app/src/main/res/drawable/ic_icon.xml
new file mode 100644
index 0000000..5719041
--- /dev/null
+++ b/app/src/main/res/drawable/ic_icon.xml
@@ -0,0 +1,163 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..f5c2386
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2734010
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_notification_icon.xml b/app/src/main/res/drawable/ic_notification_icon.xml
new file mode 100644
index 0000000..9603c0e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_notification_icon.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/app/src/main/res/font/raleway_bold.xml b/app/src/main/res/font/raleway_bold.xml
new file mode 100644
index 0000000..26fd613
--- /dev/null
+++ b/app/src/main/res/font/raleway_bold.xml
@@ -0,0 +1,6 @@
+
+
diff --git a/app/src/main/res/font/raleway_medium.xml b/app/src/main/res/font/raleway_medium.xml
new file mode 100644
index 0000000..f8dbb6e
--- /dev/null
+++ b/app/src/main/res/font/raleway_medium.xml
@@ -0,0 +1,6 @@
+
+
diff --git a/app/src/main/res/font/roboto.xml b/app/src/main/res/font/roboto.xml
new file mode 100644
index 0000000..aefe624
--- /dev/null
+++ b/app/src/main/res/font/roboto.xml
@@ -0,0 +1,6 @@
+
+
diff --git a/app/src/main/res/layout-v21/appbar_layout.xml b/app/src/main/res/layout-v21/appbar_layout.xml
new file mode 100644
index 0000000..2989c70
--- /dev/null
+++ b/app/src/main/res/layout-v21/appbar_layout.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..2a59ba0
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/appbar_layout.xml b/app/src/main/res/layout/appbar_layout.xml
new file mode 100644
index 0000000..2989c70
--- /dev/null
+++ b/app/src/main/res/layout/appbar_layout.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/time_card_view.xml b/app/src/main/res/layout/time_card_view.xml
new file mode 100644
index 0000000..e87f16d
--- /dev/null
+++ b/app/src/main/res/layout/time_card_view.xml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/time_card_view_expanded.xml b/app/src/main/res/layout/time_card_view_expanded.xml
new file mode 100644
index 0000000..b7372e3
--- /dev/null
+++ b/app/src/main/res/layout/time_card_view_expanded.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/time_config.xml b/app/src/main/res/layout/time_config.xml
new file mode 100644
index 0000000..1b37f93
--- /dev/null
+++ b/app/src/main/res/layout/time_config.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..fd63f7c
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..f79c3c5
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..830b717
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..930a0f6
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..dd99321
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..1865ec0
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..f344562
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..3933c46
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..7798cb9
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..247f5d1
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/transition/change_image_transform.xml b/app/src/main/res/transition/change_image_transform.xml
new file mode 100644
index 0000000..6897e16
--- /dev/null
+++ b/app/src/main/res/transition/change_image_transform.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-v16/styles.xml b/app/src/main/res/values-v16/styles.xml
new file mode 100644
index 0000000..78bc1e7
--- /dev/null
+++ b/app/src/main/res/values-v16/styles.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
new file mode 100644
index 0000000..f346727
--- /dev/null
+++ b/app/src/main/res/values-v21/styles.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..b08599f
--- /dev/null
+++ b/app/src/main/res/values/attrs.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..31c3f30
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,8 @@
+
+
+ #6200EE
+ #3700B3
+ #4D4DFF
+
+ #FFFFFFFF
+
diff --git a/app/src/main/res/values/font_certs.xml b/app/src/main/res/values/font_certs.xml
new file mode 100644
index 0000000..d2226ac
--- /dev/null
+++ b/app/src/main/res/values/font_certs.xml
@@ -0,0 +1,17 @@
+
+
+
+ - @array/com_google_android_gms_fonts_certs_dev
+ - @array/com_google_android_gms_fonts_certs_prod
+
+
+ -
+ MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAeFw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdGNs8/TGFy0PTP6DHThvbbR24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVyxW0qMBujb8X8ETrWy550NaFtI6t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8XW8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC69EH6kWr22ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexAcKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOjgfwwgfkwHQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0cxb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrPzgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEBahWRbqHsXclaXjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05aIskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtAWPoGChZxmQ+nBli+gwYMzM1vAkP+aayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUWEv9lKTk+jkbqxbsh8nfBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs=
+
+
+
+ -
+ MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0wODA4MjEyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JORland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRczfey5YZnTJ4VZbH0xqWVW/8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfYwXFU1+5fZKUaRKYCwkkFQVfcAs1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LWuT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0zOHKrUiGYXtqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Ylmn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r45jk14aloXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCEyj6z+a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1MvcyUTdZPErjQfTbQe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZMcUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3WfMBEmh/9iFBDAaTCK
+
+
+
diff --git a/app/src/main/res/values/preloaded_fonts.xml b/app/src/main/res/values/preloaded_fonts.xml
new file mode 100644
index 0000000..fd1ea5b
--- /dev/null
+++ b/app/src/main/res/values/preloaded_fonts.xml
@@ -0,0 +1,8 @@
+
+
+
+ - @font/raleway_bold
+ - @font/raleway_medium
+ - @font/roboto
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..3d96085
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,26 @@
+
+ Handwashing reminder
+ Activity
+ notifications
+ Get a
+ notification when you get out of a vehicle to remind you to
+ wash your hands
+ This is a test notification
+ This is the content for a test
+ notification
+ hh
+ :
+ mm
+ Choose an hour
+ When do you usually have %1$s?
+ breakfast
+ lunch
+ dinner
+ card_transition
+
+ - first_card
+ - second_card
+ - third_card
+
+ Done
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..bdfe33e
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/values/values.xml b/app/src/main/res/values/values.xml
new file mode 100644
index 0000000..f42a1ff
--- /dev/null
+++ b/app/src/main/res/values/values.xml
@@ -0,0 +1,4 @@
+
+
+ 8dp
+
diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..ca71411
--- /dev/null
+++ b/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/test/java/com/javinator9889/handwashingreminder/ExampleUnitTest.kt b/app/src/test/java/com/javinator9889/handwashingreminder/ExampleUnitTest.kt
new file mode 100644
index 0000000..9594a47
--- /dev/null
+++ b/app/src/test/java/com/javinator9889/handwashingreminder/ExampleUnitTest.kt
@@ -0,0 +1,16 @@
+package com.javinator9889.handwashingreminder
+
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..61f9853
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,29 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ ext.kotlin_version = '1.3.70'
+ repositories {
+ google()
+ jcenter()
+
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.6.1'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ maven { url 'https://jitpack.io' }
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..b402c5f
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,18 @@
+## For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+#
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx1024m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+#
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+#Mon Mar 16 13:51:53 CET 2020
+kotlin.code.style=official
+android.enableJetifier=true
+org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"
+android.useAndroidX=true
+android.enableR8.fullMode=true
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/handwashing_app_logo.png b/handwashing_app_logo.png
new file mode 100644
index 0000000..cd5ff86
Binary files /dev/null and b/handwashing_app_logo.png differ
diff --git a/handwashing_app_logo.webp b/handwashing_app_logo.webp
new file mode 100644
index 0000000..73c89e6
Binary files /dev/null and b/handwashing_app_logo.webp differ
diff --git a/handwashing_icon.png b/handwashing_icon.png
new file mode 100644
index 0000000..d5b7eaa
Binary files /dev/null and b/handwashing_icon.png differ
diff --git a/handwashing_icon.webp b/handwashing_icon.webp
new file mode 100644
index 0000000..3f5494b
Binary files /dev/null and b/handwashing_icon.webp differ
diff --git a/ic_handwashing_icon.zip b/ic_handwashing_icon.zip
new file mode 100644
index 0000000..8225edc
Binary files /dev/null and b/ic_handwashing_icon.zip differ
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..804f71c
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,2 @@
+rootProject.name='Handwashing reminder'
+include ':app'