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 @@ + + + + + + + + + + +