├── .github └── workflows │ ├── main.yml │ └── pullrequest.yml ├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── compiler.xml ├── copyright │ ├── micrusa_MIT.xml │ └── profiles_settings.xml ├── discord.xml ├── gradle.xml ├── misc.xml ├── render.experimental.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── lint.xml ├── proguard-rules.pro ├── schemas │ └── me.micrusa.amaztimer.database.AmazTimerDB │ │ └── 2.json └── src │ ├── androidTest │ └── java │ │ └── me │ │ └── micrusa │ │ └── amaztimer │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-playstore.png │ ├── java │ │ └── me │ │ │ └── micrusa │ │ │ └── amaztimer │ │ │ ├── AmazTimerApplication.java │ │ │ ├── Constants.java │ │ │ ├── MainActivity.java │ │ │ ├── activities │ │ │ ├── AppInfo.java │ │ │ ├── CreateNew.java │ │ │ ├── PrepareActivity.java │ │ │ ├── SettingsActivity.java │ │ │ ├── TimerActivity.java │ │ │ ├── TimerPreview.java │ │ │ └── saved │ │ │ │ ├── Saved.java │ │ │ │ ├── SavedTimerRun.java │ │ │ │ └── TimerAdapter.java │ │ │ ├── database │ │ │ ├── AmazTimerDB.java │ │ │ ├── DBConstants.java │ │ │ ├── DBUtils.java │ │ │ ├── converters │ │ │ │ └── Converters.java │ │ │ ├── dao │ │ │ │ ├── TimerDao.java │ │ │ │ └── WorkoutDao.java │ │ │ └── objects │ │ │ │ ├── Timer.java │ │ │ │ └── Workout.java │ │ │ ├── saveworkout │ │ │ ├── SaveWorkout.java │ │ │ └── ui │ │ │ │ ├── SavedWorkoutsActivity.java │ │ │ │ ├── WorkoutAdapter.java │ │ │ │ └── WorkoutViewerActivity.java │ │ │ └── utils │ │ │ ├── PrefsUtil.java │ │ │ ├── Utils.java │ │ │ ├── button │ │ │ ├── ButtonEvent.java │ │ │ ├── ButtonInterface.java │ │ │ ├── ButtonListener.java │ │ │ └── selector │ │ │ │ ├── ButtonSelector.java │ │ │ │ └── Selector.java │ │ │ ├── devices │ │ │ ├── AmazfitUtils.java │ │ │ └── SystemProperties.java │ │ │ ├── handlers │ │ │ ├── chronoHandler.java │ │ │ ├── hrZoneHandler.java │ │ │ ├── timeHandler.java │ │ │ └── timerHandler.java │ │ │ ├── sensors │ │ │ ├── heartrate │ │ │ │ ├── hrSensor.java │ │ │ │ ├── hrUtils.java │ │ │ │ └── listeners │ │ │ │ │ ├── experimentalListener.java │ │ │ │ │ └── mainListener.java │ │ │ ├── objects │ │ │ │ └── Listener.java │ │ │ └── repsCounter │ │ │ │ ├── RepsConstants.java │ │ │ │ ├── RepsCounter.java │ │ │ │ ├── RepsListener.java │ │ │ │ ├── listeners │ │ │ │ ├── Accelerometer.java │ │ │ │ └── Gyroscope.java │ │ │ │ ├── objects │ │ │ │ └── Exercise.java │ │ │ │ ├── ui │ │ │ │ ├── ExerciseAdapter.java │ │ │ │ └── dialog │ │ │ │ │ ├── ExerciseDialog.java │ │ │ │ │ └── NewRepExerciseDialog.java │ │ │ │ └── utils │ │ │ │ ├── Filtering.java │ │ │ │ └── PeaksChecker.java │ │ │ └── tcx │ │ │ ├── SaveTCX.java │ │ │ ├── TCXConstants.java │ │ │ ├── TCXUtils.java │ │ │ └── data │ │ │ ├── Lap.java │ │ │ ├── TCXData.java │ │ │ └── Trackpoint.java │ └── res │ │ ├── drawable │ │ ├── add.xml │ │ ├── circle_button.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── remove.xml │ │ ├── round_keyboard_arrow_right_black_36dp.png │ │ ├── sadd.png │ │ ├── scircle_button.xml │ │ ├── selected_button.xml │ │ └── sremove.png │ │ ├── font │ │ ├── applemint.xml │ │ └── customfont.ttf │ │ ├── layout │ │ ├── activity_app_info.xml │ │ ├── activity_create_new.xml │ │ ├── activity_main.xml │ │ ├── activity_prepare.xml │ │ ├── activity_saved.xml │ │ ├── activity_saved_workouts.xml │ │ ├── activity_timer.xml │ │ ├── activity_timer_preview.xml │ │ ├── activity_workout_viewer.xml │ │ ├── dialog_exercise_select.xml │ │ ├── item_exercise.xml │ │ ├── item_timer.xml │ │ ├── item_workout.xml │ │ └── settings_activity.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ └── ic_launcher_round.png │ │ ├── raw │ │ └── beep.mp3 │ │ ├── values-cs │ │ └── strings.xml │ │ ├── values-es │ │ └── strings.xml │ │ ├── values-hr │ │ └── strings.xml │ │ ├── values-it │ │ └── strings.xml │ │ ├── values-iw │ │ └── strings.xml │ │ ├── values-pt-rBR │ │ └── strings.xml │ │ ├── values-ru │ │ └── strings.xml │ │ ├── values-uk │ │ └── strings.xml │ │ ├── values │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── root_preferences.xml │ └── test │ └── java │ └── me │ └── micrusa │ └── amaztimer │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── mainscreen.png ├── settings.gradle ├── settings.png ├── workingout.png └── workoutviewer.png /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | jobs: 8 | 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - name: Build AmazTimer 16 | uses: vgaidarji/android-github-actions-build@v1.0.1 17 | with: 18 | args: "./gradlew assembleRelease" 19 | 20 | - name: Give permissions to sign apk 21 | run: sudo chown -R $USER:$USER app/build/outputs/apk/release 22 | 23 | - name: Sign apk 24 | id: signapk 25 | uses: r0adkll/sign-android-release@v1 26 | with: 27 | releaseDirectory: app/build/outputs/apk/release 28 | signingKeyBase64: ${{ secrets.SIGNING_KEY }} 29 | alias: ${{ secrets.ALIAS }} 30 | keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }} 31 | keyPassword: ${{ secrets.KEY_PASSWORD }} 32 | 33 | - name: Delete edgy release 34 | uses: dev-drprasad/delete-tag-and-release@v0.1.2 35 | with: 36 | tag_name: edgy 37 | env: 38 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 39 | 40 | - name: Create edgy release 41 | uses: meeDamian/github-release@v2.0.2 42 | with: 43 | token: ${{ secrets.GITHUB_TOKEN }} 44 | tag: edgy 45 | name: Edgy 46 | body: Continuous integration build, no support will be given for this build and it might have bugs or even not work 47 | prerelease: true 48 | files: AmazTimer-EDGY.apk:${{ steps.signapk.outputs.signedReleaseFile }} 49 | gzip: false 50 | -------------------------------------------------------------------------------- /.github/workflows/pullrequest.yml: -------------------------------------------------------------------------------- 1 | name: Pull Request 2 | 3 | on: 4 | pull_request: 5 | branches: [ master ] 6 | 7 | jobs: 8 | 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - name: Build AmazTimer 16 | uses: vgaidarji/android-github-actions-build@v1.0.1 17 | with: 18 | args: "./gradlew assembleDebug" 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | /app/release/output.json 16 | /app/release/ 17 | install.bat 18 | .idea/jarRepositories.xml 19 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | xmlns:android 14 | 15 | ^$ 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | xmlns:.* 25 | 26 | ^$ 27 | 28 | 29 | BY_NAME 30 | 31 |
32 |
33 | 34 | 35 | 36 | .*:id 37 | 38 | http://schemas.android.com/apk/res/android 39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:name 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | name 59 | 60 | ^$ 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | style 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | .* 81 | 82 | ^$ 83 | 84 | 85 | BY_NAME 86 | 87 |
88 |
89 | 90 | 91 | 92 | .* 93 | 94 | http://schemas.android.com/apk/res/android 95 | 96 | 97 | ANDROID_ATTRIBUTE_ORDER 98 | 99 |
100 |
101 | 102 | 103 | 104 | .* 105 | 106 | .* 107 | 108 | 109 | BY_NAME 110 | 111 |
112 |
113 |
114 |
115 |
116 |
-------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/micrusa_MIT.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/discord.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | -------------------------------------------------------------------------------- /.idea/render.experimental.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Miguel Cruces 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AmazTimer 2 | [![Maintainability](https://api.codeclimate.com/v1/badges/9389ce1c8136678546c2/maintainability)](https://codeclimate.com/github/micrusa/AmazTimer/maintainability) [![Actions Status](https://github.com/micrusa/amaztimer/workflows/CI/badge.svg)](https://github.com/micrusa/amaztimer/actions) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/migueelcs) [![latest release](https://img.shields.io/github/release/micrusa/AmazTimer.svg?label=latest%20release&style=flat)](https://github.com/micrusa/AmazTimer/releases/latest) [![commit activity](https://img.shields.io/github/commit-activity/m/micrusa/AmazTimer)](https://github.com/micrusa/AmazTimer/commits/master) 3 | 4 | ## Description 5 | This app is an interval/reps/workout timer for amazfit devices to do trainings with HR/kcal monitoring and TCX exports, default values are tabata training's but you can use any times and sets you want 6 | 7 | ## Bugs and suggestions 8 | This app is in continuous development and I don't have every device to test, so you might find bugs, if you find any please create an issue with logcat and I'll try to fix it as fast as I can. Don't report bugs that are already reported. 9 | If you have any suggestions open an issue or answer the XDA thread 10 | 11 | ## Compatible devices 12 | Any amazfit device running android 5.1 MIPS (Pace, stratos 1/2/3, verge) 13 | 14 | ## Notes 15 | - TCX files are saved in "Internal Storage/AmazTimer", for some reason windows sometimes can't read it, so you can get them using `adb pull /sdcard/AmazTimer` or through AmazMod 16 | 17 | ## HW Buttons 18 | - Single button devices and Stratos with new key layout: Single click to end set, long click to start/stop timer. Center button on S2 19 | - Stratos with old key layout: lower button to start, center button for settings and upper button to end sets 20 | - Stratos 3: Same as stratos old key layout. Upper button = Upper button, Middle upper button = Middle button, Middle down button = Down button 21 | 22 | You can invert top/lower buttons by enabling invert keys preference 23 | 24 | ## Installation 25 | Install using `adb install AmazTimer-X.X.apk` and update using `adb install -r AmazTimer-X.X.apk` 26 | 27 | You can also use installer or install/update it through AmazMod. 28 | 29 | ## Uninstallation 30 | `adb uninstall me.micrusa.amaztimer` 31 | You can also use installer or uninstall it through AmazMod 32 | 33 | ## Screenshots 34 | 35 | 36 | 37 | ## Thanks to 38 | - [@GreatApo](https://github.com/GreatApo) for [Amazfit Calendar Widget](https://github.com/GreatApo/AmazfitPaceCalendarWidget) 39 | - [AmazMod](https://github.com/AmazMod/AmazMod) team 40 | - [@1immortal](https://github.com/1immortal) for creating app installer 41 | - All contributors 42 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 30 5 | buildToolsVersion "30.0.3" 6 | 7 | defaultConfig { 8 | applicationId "me.micrusa.amaztimer" 9 | minSdkVersion 21 10 | targetSdkVersion 30 11 | versionCode 82 12 | versionName "8.2" 13 | 14 | javaCompileOptions { 15 | annotationProcessorOptions { 16 | arguments = ["room.schemaLocation": "$projectDir/schemas".toString()] 17 | } 18 | } 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | shrinkResources false 25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | compileOptions { 29 | sourceCompatibility JavaVersion.VERSION_1_8 30 | targetCompatibility JavaVersion.VERSION_1_8 31 | } 32 | 33 | 34 | } 35 | 36 | dependencies { 37 | implementation fileTree(include: ['*.jar'], dir: 'libs') 38 | implementation 'com.google.code.gson:gson:2.8.6' 39 | implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' 40 | implementation 'com.pixplicity.easyprefs:library:1.9.0' 41 | implementation 'androidx.appcompat:appcompat:1.2.0' 42 | implementation 'androidx.core:core:1.3.2' 43 | implementation 'androidx.preference:preference:1.1.1' 44 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4' 45 | implementation 'org.tinylog:tinylog-api:2.2.1' 46 | runtimeOnly 'org.tinylog:tinylog-impl:2.2.1' 47 | implementation "androidx.room:room-runtime:2.2.6" 48 | annotationProcessor "androidx.room:room-compiler:2.2.6" 49 | } 50 | -------------------------------------------------------------------------------- /app/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | -keepnames interface org.tinylog.** 16 | -keepnames class * implements org.tinylog.** 17 | -keepclassmembers class * implements org.tinylog.** { (...); } 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/schemas/me.micrusa.amaztimer.database.AmazTimerDB/2.json: -------------------------------------------------------------------------------- 1 | { 2 | "formatVersion": 1, 3 | "database": { 4 | "version": 2, 5 | "identityHash": "0890468ecaa1ab2651a157d977a901d0", 6 | "entities": [ 7 | { 8 | "tableName": "Workout", 9 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`time` INTEGER NOT NULL, `heart_rate` TEXT, `sets` TEXT, `reps_per_set` TEXT, `kcal` INTEGER NOT NULL, `duration` INTEGER NOT NULL, PRIMARY KEY(`time`))", 10 | "fields": [ 11 | { 12 | "fieldPath": "time", 13 | "columnName": "time", 14 | "affinity": "INTEGER", 15 | "notNull": true 16 | }, 17 | { 18 | "fieldPath": "hr", 19 | "columnName": "heart_rate", 20 | "affinity": "TEXT", 21 | "notNull": false 22 | }, 23 | { 24 | "fieldPath": "sets", 25 | "columnName": "sets", 26 | "affinity": "TEXT", 27 | "notNull": false 28 | }, 29 | { 30 | "fieldPath": "setsReps", 31 | "columnName": "reps_per_set", 32 | "affinity": "TEXT", 33 | "notNull": false 34 | }, 35 | { 36 | "fieldPath": "kcal", 37 | "columnName": "kcal", 38 | "affinity": "INTEGER", 39 | "notNull": true 40 | }, 41 | { 42 | "fieldPath": "totalTime", 43 | "columnName": "duration", 44 | "affinity": "INTEGER", 45 | "notNull": true 46 | } 47 | ], 48 | "primaryKey": { 49 | "columnNames": [ 50 | "time" 51 | ], 52 | "autoGenerate": false 53 | }, 54 | "indices": [], 55 | "foreignKeys": [] 56 | }, 57 | { 58 | "tableName": "Timer", 59 | "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`timeAdded` INTEGER NOT NULL, `name` TEXT, `sets` INTEGER NOT NULL, `work` INTEGER NOT NULL, `rest` INTEGER NOT NULL, `mode` INTEGER NOT NULL, `heartrate` INTEGER NOT NULL, `gps` INTEGER NOT NULL, PRIMARY KEY(`timeAdded`))", 60 | "fields": [ 61 | { 62 | "fieldPath": "timeAdded", 63 | "columnName": "timeAdded", 64 | "affinity": "INTEGER", 65 | "notNull": true 66 | }, 67 | { 68 | "fieldPath": "name", 69 | "columnName": "name", 70 | "affinity": "TEXT", 71 | "notNull": false 72 | }, 73 | { 74 | "fieldPath": "sets", 75 | "columnName": "sets", 76 | "affinity": "INTEGER", 77 | "notNull": true 78 | }, 79 | { 80 | "fieldPath": "work", 81 | "columnName": "work", 82 | "affinity": "INTEGER", 83 | "notNull": true 84 | }, 85 | { 86 | "fieldPath": "rest", 87 | "columnName": "rest", 88 | "affinity": "INTEGER", 89 | "notNull": true 90 | }, 91 | { 92 | "fieldPath": "mode", 93 | "columnName": "mode", 94 | "affinity": "INTEGER", 95 | "notNull": true 96 | }, 97 | { 98 | "fieldPath": "heartrate", 99 | "columnName": "heartrate", 100 | "affinity": "INTEGER", 101 | "notNull": true 102 | }, 103 | { 104 | "fieldPath": "gps", 105 | "columnName": "gps", 106 | "affinity": "INTEGER", 107 | "notNull": true 108 | } 109 | ], 110 | "primaryKey": { 111 | "columnNames": [ 112 | "timeAdded" 113 | ], 114 | "autoGenerate": false 115 | }, 116 | "indices": [], 117 | "foreignKeys": [] 118 | } 119 | ], 120 | "views": [], 121 | "setupQueries": [ 122 | "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", 123 | "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '0890468ecaa1ab2651a157d977a901d0')" 124 | ] 125 | } 126 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/me/micrusa/amaztimer/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package me.micrusa.amaztimer; 2 | 3 | import android.content.Context; 4 | import androidx.test.platform.app.InstrumentationRegistry; 5 | import androidx.test.ext.junit.runners.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 23 | 24 | assertEquals("me.micrusa.amaztimer", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micrusa/AmazTimer/482ae866160b05a3e9e9c30617e5d13ddcc890aa/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/AmazTimerApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer; 26 | 27 | import android.app.Application; 28 | import android.content.Context; 29 | import android.content.ContextWrapper; 30 | 31 | import com.pixplicity.easyprefs.library.Prefs; 32 | 33 | import me.micrusa.amaztimer.utils.Utils; 34 | 35 | public class AmazTimerApplication extends Application { 36 | 37 | private static Application mApp; 38 | 39 | public void onCreate() { 40 | super.onCreate(); 41 | 42 | mApp = this; 43 | 44 | setupPrefs(this); 45 | Utils.setupLang(this); 46 | } 47 | 48 | public static Context getContext(){ 49 | return mApp.getApplicationContext(); 50 | } 51 | 52 | private static void setupPrefs(Context context){ 53 | new Prefs.Builder() 54 | .setContext(context) 55 | .setMode(ContextWrapper.MODE_PRIVATE) 56 | .setPrefsName(context.getPackageName()) 57 | .setUseDefaultSharedPreference(true) 58 | .build(); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer; 26 | 27 | import java.text.SimpleDateFormat; 28 | import java.util.Date; 29 | import java.util.Locale; 30 | 31 | public final class Constants { 32 | //Format for times 33 | public static final String timeFormat = "mm:ss"; 34 | //Default sets and times 35 | public static final int DEF_SETS = 8; 36 | public static final int DEF_WORKTIME = 20; 37 | public static final int DEF_RESTTIME = 10; 38 | //Vibration times 39 | public static final int HAPTIC_VIBRATION = 125; //0.125s 40 | public static final int SHORT_VIBRATION = 200; //0.2s 41 | public static final int LONG_VIBRATION = 700; //0.7s 42 | //Max and min values 43 | public static final int MIN_SETS = 1; 44 | public static final int MAX_SETS = 99; 45 | public static final int MIN_TIME = 1; //1s 46 | public static final int MAX_TIME = 900; //15m 47 | //Default values 48 | public static final int DEFAULT_WEIGHT = 70; 49 | public static final int DEFAULT_AGE = 20; 50 | public static final boolean DEFAULT_TCX = true; 51 | public static final boolean DEFAULT_SOUND = true; 52 | //Settings keys 53 | public static final String KEY_SETS = "sets"; 54 | public static final String KEY_WORK = "work"; 55 | public static final String KEY_REST = "rest"; 56 | public static final String KEY_HRTOGGLE = "hrOn"; 57 | public static final String KEY_LANG = "lang"; 58 | public static final String KEY_GENDER = "gender"; 59 | public static final String KEY_AGE = "age"; 60 | public static final String KEY_WEIGHT = "weight"; 61 | public static final String KEY_ENABLEPREPARE = "prepon"; 62 | public static final String KEY_REPSMODE = "repsmode"; 63 | public static final String KEY_APPINFO = "appinfo"; 64 | public static final String KEY_WORKOUT = "workoutmode"; 65 | public static final String KEY_TCX = "tcx"; 66 | public static final String KEY_SOUND = "sound"; 67 | public static final String KEY_HRZONE = "hrzone"; 68 | public static final String KEY_INVERTKEYS = "invertkeys"; 69 | public static final String KEY_HREXPERIMENT = "hrexperiment"; 70 | public static final String KEY_TCX_TIME = "tcxtime"; 71 | public static final String KEY_VIBRATION = "vibration"; 72 | public static final String KEY_REPSCOUNT = "repscounter"; 73 | //Some useful stuff 74 | public static final String VERSION_NAME = "v" + BuildConfig.VERSION_NAME; 75 | public static final int VERSION_CODE = BuildConfig.VERSION_CODE; 76 | public static final int CURRENT_YEAR = Integer.parseInt(new SimpleDateFormat("yyyy", Locale.US).format(new Date())); 77 | 78 | public static final int MODE_DEF = -1; 79 | public static final int MODE_REPS = 0; 80 | public static final int MODE_WORKOUT = 1; 81 | public static final int MODE_REPSCOUNTER = 2; 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer; 26 | 27 | import androidx.appcompat.app.AppCompatActivity; 28 | 29 | import android.content.Intent; 30 | import android.os.Bundle; 31 | import android.widget.Button; 32 | 33 | import me.micrusa.amaztimer.activities.CreateNew; 34 | import me.micrusa.amaztimer.activities.saved.Saved; 35 | import me.micrusa.amaztimer.activities.SettingsActivity; 36 | import me.micrusa.amaztimer.saveworkout.ui.SavedWorkoutsActivity; 37 | import me.micrusa.amaztimer.utils.Utils; 38 | import me.micrusa.amaztimer.utils.button.selector.ButtonSelector; 39 | 40 | public class MainActivity extends AppCompatActivity { 41 | private Button saved, createNew, settings, workouts; 42 | private ButtonSelector buttonSelector; 43 | private boolean hasLaunchedActivities = false; 44 | 45 | @Override 46 | protected void onCreate(Bundle savedInstanceState) { 47 | super.onCreate(savedInstanceState); 48 | setContentView(R.layout.activity_main); 49 | init(); 50 | buttonSelector.startListening(); 51 | } 52 | 53 | private void init(){ 54 | saved = findViewById(R.id.main_saved); 55 | createNew = findViewById(R.id.main_create_new); 56 | settings = findViewById(R.id.main_settings); 57 | workouts = findViewById(R.id.main_workouts); 58 | buttonSelector = new ButtonSelector(new Button[]{saved, createNew, workouts, settings}, this); 59 | 60 | saved.setOnClickListener(view -> launchActivity(new Intent(this, Saved.class))); 61 | createNew.setOnClickListener(view -> launchActivity(new Intent(this, CreateNew.class))); 62 | settings.setOnClickListener(view -> launchActivity(new Intent(this, SettingsActivity.class))); 63 | workouts.setOnClickListener(view -> launchActivity(new Intent(this, SavedWorkoutsActivity.class))); 64 | } 65 | 66 | private void launchActivity(Intent intent){ 67 | if(hasLaunchedActivities) return; //Avoid multiple activities launched 68 | Utils.vibrate(Constants.HAPTIC_VIBRATION, this); 69 | hasLaunchedActivities = true; 70 | buttonSelector.stopListening(); 71 | startActivity(intent); 72 | } 73 | 74 | public void onStop() { 75 | super.onStop(); 76 | buttonSelector.stopListening(); 77 | } 78 | 79 | public void onPause() { 80 | buttonSelector.stopListening(); 81 | super.onPause(); 82 | } 83 | 84 | public void onResume() { 85 | hasLaunchedActivities = false; 86 | buttonSelector.startListening(); 87 | super.onResume(); 88 | } 89 | } -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/activities/AppInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.activities; 26 | 27 | import android.annotation.SuppressLint; 28 | import android.os.Bundle; 29 | import android.widget.TextView; 30 | 31 | import androidx.appcompat.app.AppCompatActivity; 32 | 33 | import me.micrusa.amaztimer.R; 34 | import me.micrusa.amaztimer.Constants; 35 | import me.micrusa.amaztimer.utils.Utils; 36 | 37 | public class AppInfo extends AppCompatActivity { 38 | 39 | 40 | @Override 41 | protected void onCreate(Bundle savedInstanceState) { 42 | super.onCreate(savedInstanceState); 43 | Utils.setupLang(this); 44 | setContentView(R.layout.activity_app_info); 45 | this.init(); 46 | } 47 | 48 | @SuppressLint("SetTextI18n") 49 | private void init(){ 50 | TextView appText = findViewById(R.id.amaztimer); 51 | TextView appCredits = findViewById(R.id.appcredit); 52 | TextView translationCredits = findViewById(R.id.translationcredit); 53 | TextView thanksto = findViewById(R.id.thanksto); 54 | 55 | String NEWLINE = "\n- "; 56 | String FOR = getString(R.string.thanksfor); 57 | //Set texts 58 | appText.setText(appText.getText() 59 | + " " + Constants.VERSION_NAME + " (" + Constants.VERSION_CODE + ")"); 60 | appCredits.setText(getString(R.string.appcredit)); 61 | translationCredits.setText(getString(R.string.translationcredit)); 62 | thanksto.setText(getString(R.string.thanksto) 63 | + NEWLINE + "@Quinny899 " + FOR + " Springboard Plugin Example" 64 | + NEWLINE + "@GreatApo " + FOR + " Widget Calendar" 65 | + NEWLINE + "@1immortal " + FOR + " AmazTimer installer" 66 | + NEWLINE + "AmazMod team" 67 | + NEWLINE + getString(R.string.allcontributors)); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/activities/PrepareActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.activities; 26 | 27 | import android.content.Intent; 28 | import android.os.Bundle; 29 | import android.os.CountDownTimer; 30 | import android.os.Handler; 31 | import android.widget.TextView; 32 | 33 | import androidx.appcompat.app.AppCompatActivity; 34 | 35 | import me.micrusa.amaztimer.R; 36 | import me.micrusa.amaztimer.Constants; 37 | import me.micrusa.amaztimer.utils.Utils; 38 | 39 | public class PrepareActivity extends AppCompatActivity { 40 | 41 | private TextView timer; 42 | private boolean finished; 43 | 44 | @Override 45 | protected void onCreate(Bundle savedInstanceState) { 46 | super.onCreate(savedInstanceState); 47 | init(); 48 | startTimer(); 49 | } 50 | 51 | private void init(){ 52 | Utils.setupLang(this); 53 | setContentView(R.layout.activity_prepare); 54 | timer = findViewById(R.id.prepareTime); 55 | } 56 | 57 | private void startTimer(){ 58 | new CountDownTimer(6000, 1000){ 59 | @Override 60 | public void onTick(long l) { 61 | int time = (int) l / 1000; 62 | timer.setText(String.valueOf(time)); 63 | if(time < 4){ 64 | Utils.vibrate(Constants.SHORT_VIBRATION, PrepareActivity.this); 65 | if(time == 1) 66 | new Handler().postDelayed(() -> { 67 | timer.setText("0"); 68 | Utils.vibrate(Constants.LONG_VIBRATION, PrepareActivity.this); 69 | }, 950); 70 | } 71 | } 72 | @Override 73 | public void onFinish() { 74 | finished = true; 75 | startActivity(new Intent(PrepareActivity.this, TimerActivity.class)); 76 | finish(); 77 | } 78 | }.start(); 79 | } 80 | 81 | public void onResume() { 82 | super.onResume(); 83 | if(finished) 84 | finish(); 85 | } 86 | } -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/activities/TimerPreview.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.activities; 26 | 27 | import androidx.appcompat.app.AppCompatActivity; 28 | 29 | import android.annotation.SuppressLint; 30 | import android.os.Bundle; 31 | import android.widget.Button; 32 | import android.widget.TextView; 33 | 34 | import me.micrusa.amaztimer.R; 35 | import me.micrusa.amaztimer.activities.saved.SavedTimerRun; 36 | import me.micrusa.amaztimer.utils.Utils; 37 | import me.micrusa.amaztimer.utils.button.selector.ButtonSelector; 38 | 39 | public class TimerPreview extends AppCompatActivity { 40 | private TextView name, sets, work, rest, hr; 41 | private ButtonSelector buttonSelector; 42 | private Button start; 43 | 44 | @Override 45 | protected void onCreate(Bundle savedInstanceState) { 46 | super.onCreate(savedInstanceState); 47 | setContentView(R.layout.activity_timer_preview); 48 | init(SavedTimerRun.fromIntent(getIntent())); 49 | } 50 | 51 | @SuppressLint("SetTextI18n") 52 | private void init(SavedTimerRun t){ 53 | name = findViewById(R.id.timer_preview_name); 54 | sets = findViewById(R.id.timer_preview_sets); 55 | work = findViewById(R.id.timer_preview_work); 56 | rest = findViewById(R.id.timer_preview_rest); 57 | hr = findViewById(R.id.timer_preview_hr); 58 | start = findViewById(R.id.timer_preview_start); 59 | buttonSelector = new ButtonSelector(new Button[]{start}, this); 60 | buttonSelector.startListening(); 61 | 62 | name.setText(t.name); 63 | sets.setText(String.valueOf(t.sets)); 64 | work.setText(Utils.formatTime(t.work)); 65 | rest.setText(Utils.formatTime(t.rest)); 66 | hr.setText(t.heartrate ? R.string.enabled : R.string.disabled); 67 | start.setOnClickListener(view -> Utils.start(this, t)); 68 | } 69 | 70 | public void onStop() { 71 | buttonSelector.stopListening(); 72 | super.onStop(); 73 | } 74 | 75 | public void onPause() { 76 | buttonSelector.stopListening(); 77 | super.onPause(); 78 | } 79 | 80 | public void onResume() { 81 | buttonSelector.startListening(); 82 | super.onResume(); 83 | } 84 | } -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/activities/saved/SavedTimerRun.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.activities.saved; 26 | 27 | import android.content.Intent; 28 | 29 | import androidx.room.ColumnInfo; 30 | 31 | import me.micrusa.amaztimer.database.objects.Timer; 32 | 33 | public class SavedTimerRun { 34 | public String name; 35 | public int sets; 36 | public int work; 37 | public int rest; 38 | public int mode; 39 | public boolean heartrate; 40 | public boolean gps; 41 | 42 | public static SavedTimerRun fromTimer(Timer t){ 43 | SavedTimerRun r = new SavedTimerRun(); 44 | r.name = t.name; 45 | r.sets = t.sets; 46 | r.work = t.work; 47 | r.rest = t.rest; 48 | r.mode = t.mode; 49 | r.heartrate = t.heartrate; 50 | r.gps = t.gps; 51 | return r; 52 | } 53 | 54 | public static SavedTimerRun fromIntent(Intent i){ 55 | SavedTimerRun r = new SavedTimerRun(); 56 | r.name = i.getStringExtra("name"); 57 | r.sets = i.getIntExtra("sets", 8); 58 | r.work = i.getIntExtra("work", 30); 59 | r.rest = i.getIntExtra("rest", 20); 60 | r.mode = i.getIntExtra("mode", 0); 61 | r.heartrate = i.getBooleanExtra("hr", true); 62 | r.gps = i.getBooleanExtra("gps", false); 63 | return r; 64 | } 65 | 66 | public Intent toIntent(Intent i){ 67 | i.putExtra("name", name); 68 | i.putExtra("sets", sets); 69 | i.putExtra("work", work); 70 | i.putExtra("rest", rest); 71 | i.putExtra("mode", mode); 72 | i.putExtra("hr", heartrate); 73 | i.putExtra("gps", gps); 74 | return i; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/activities/saved/TimerAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.activities.saved; 26 | 27 | import android.annotation.SuppressLint; 28 | import android.content.Context; 29 | import android.view.LayoutInflater; 30 | import android.view.View; 31 | import android.view.ViewGroup; 32 | import android.widget.ArrayAdapter; 33 | import android.widget.TextView; 34 | 35 | import java.util.List; 36 | 37 | import me.micrusa.amaztimer.R; 38 | import me.micrusa.amaztimer.database.objects.Timer; 39 | 40 | public class TimerAdapter extends ArrayAdapter { 41 | public TimerAdapter(Context context, List timers){ 42 | super(context, 0, timers); 43 | } 44 | 45 | @Override 46 | public View getView(int position, View convertView, ViewGroup parent){ 47 | final Timer t = getItem(position); 48 | return getConvertedView(convertView, parent, t); 49 | } 50 | 51 | @SuppressLint("SetTextI18n") 52 | private View getConvertedView(View v, ViewGroup parent, Timer t){ 53 | if(v == null) { 54 | v = LayoutInflater.from(getContext()).inflate(R.layout.item_timer, parent, false); 55 | TextView name = v.findViewById(R.id.timer_item_name); 56 | TextView sets = v.findViewById(R.id.timer_item_sets); 57 | 58 | name.setText(t.name); 59 | sets.setText(t.sets + " " + getContext().getString(R.string.sets).toLowerCase()); 60 | } 61 | return v; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/database/AmazTimerDB.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.database; 26 | 27 | import androidx.room.Database; 28 | import androidx.room.RoomDatabase; 29 | import androidx.room.TypeConverters; 30 | 31 | import me.micrusa.amaztimer.database.converters.Converters; 32 | import me.micrusa.amaztimer.database.dao.TimerDao; 33 | import me.micrusa.amaztimer.database.dao.WorkoutDao; 34 | import me.micrusa.amaztimer.database.objects.Timer; 35 | import me.micrusa.amaztimer.database.objects.Workout; 36 | 37 | @Database(version = DBConstants.VERSION, entities = {Workout.class, Timer.class}) 38 | @TypeConverters(Converters.class) 39 | public abstract class AmazTimerDB extends RoomDatabase { 40 | public abstract WorkoutDao workoutDao(); 41 | public abstract TimerDao timerDao(); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/database/DBConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.database; 26 | 27 | public class DBConstants { 28 | 29 | public static final String DB_NAME = "amaztimer_db"; 30 | public static final int VERSION = 2; 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/database/DBUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.database; 26 | 27 | import androidx.annotation.NonNull; 28 | import androidx.room.Room; 29 | import androidx.room.migration.Migration; 30 | import androidx.sqlite.db.SupportSQLiteDatabase; 31 | 32 | import me.micrusa.amaztimer.AmazTimerApplication; 33 | 34 | public class DBUtils { 35 | public static AmazTimerDB createInstance(){ 36 | return Room.databaseBuilder(AmazTimerApplication.getContext(), 37 | AmazTimerDB.class, DBConstants.DB_NAME) 38 | .addMigrations(new SQLMigration(1, 2, new String[]{"CREATE TABLE IF NOT EXISTS `Timer` (`timeAdded` INTEGER NOT NULL, `name` TEXT, `sets` INTEGER NOT NULL, `work` INTEGER NOT NULL, `rest` INTEGER NOT NULL, `mode` INTEGER NOT NULL, `heartrate` INTEGER NOT NULL, `gps` INTEGER NOT NULL, PRIMARY KEY(`timeAdded`))"})) 39 | .build(); 40 | } 41 | 42 | public static class SQLMigration extends Migration { 43 | private String[] SQL; 44 | public SQLMigration(int start, int end, String[] SQL){ 45 | super(start, end); 46 | this.SQL = SQL; 47 | } 48 | @Override 49 | public void migrate(@NonNull SupportSQLiteDatabase database) { 50 | for(String str : SQL) database.execSQL(str); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/database/converters/Converters.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.database.converters; 26 | 27 | import androidx.room.TypeConverter; 28 | 29 | import com.google.gson.Gson; 30 | import com.google.gson.reflect.TypeToken; 31 | 32 | import java.lang.reflect.Type; 33 | import java.util.List; 34 | 35 | public class Converters { 36 | 37 | @TypeConverter 38 | public static List fromString(String value) { 39 | Type listType = new TypeToken>(){}.getType(); 40 | return new Gson().fromJson(value, listType); 41 | } 42 | 43 | @TypeConverter 44 | public static String fromArrayList(List list) { 45 | return new Gson().toJson(list); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/database/dao/TimerDao.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.database.dao; 26 | 27 | import androidx.room.Dao; 28 | import androidx.room.Delete; 29 | import androidx.room.Insert; 30 | import androidx.room.Query; 31 | 32 | import java.util.List; 33 | 34 | import me.micrusa.amaztimer.database.objects.Timer; 35 | 36 | @Dao 37 | public interface TimerDao { 38 | @Query("SELECT * FROM timer") 39 | List getAll(); 40 | 41 | @Insert 42 | void insertAll(Timer... workouts); 43 | 44 | @Delete 45 | void delete(Timer workout); 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/database/dao/WorkoutDao.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.database.dao; 26 | 27 | import androidx.room.Dao; 28 | import androidx.room.Delete; 29 | import androidx.room.Insert; 30 | import androidx.room.Query; 31 | 32 | import java.util.List; 33 | 34 | import me.micrusa.amaztimer.database.objects.Workout; 35 | 36 | @Dao 37 | public interface WorkoutDao { 38 | 39 | @Query("SELECT * FROM workout") 40 | List getAll(); 41 | 42 | @Query("SELECT * FROM workout WHERE time LIKE :time LIMIT 1") 43 | Workout findByTime(long time); 44 | 45 | @Insert 46 | void insertAll(Workout... workouts); 47 | 48 | @Delete 49 | void delete(Workout workout); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/database/objects/Timer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.database.objects; 26 | 27 | import android.content.Intent; 28 | 29 | import androidx.room.ColumnInfo; 30 | import androidx.room.Entity; 31 | import androidx.room.PrimaryKey; 32 | 33 | @Entity 34 | public class Timer { 35 | 36 | @PrimaryKey 37 | public long timeAdded; 38 | 39 | @ColumnInfo(name = "name") 40 | public String name; 41 | 42 | @ColumnInfo(name = "sets") 43 | public int sets; 44 | 45 | @ColumnInfo(name = "work") 46 | public int work; 47 | 48 | @ColumnInfo(name = "rest") 49 | public int rest; 50 | 51 | @ColumnInfo(name = "mode") 52 | public int mode; 53 | 54 | @ColumnInfo(name = "heartrate") 55 | public boolean heartrate; 56 | 57 | @ColumnInfo(name = "gps") 58 | public boolean gps; 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/database/objects/Workout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.database.objects; 26 | 27 | import androidx.room.ColumnInfo; 28 | import androidx.room.Entity; 29 | import androidx.room.PrimaryKey; 30 | 31 | import java.util.List; 32 | 33 | @Entity 34 | public class Workout { 35 | 36 | @PrimaryKey 37 | public long time; 38 | 39 | @ColumnInfo(name = "heart_rate") 40 | public List hr; 41 | 42 | @ColumnInfo(name = "sets") 43 | public List sets; 44 | 45 | @ColumnInfo(name = "reps_per_set") 46 | public List setsReps; 47 | 48 | @ColumnInfo(name = "kcal") 49 | public int kcal; 50 | 51 | @ColumnInfo(name = "duration") 52 | public int totalTime; 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/saveworkout/SaveWorkout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.saveworkout; 26 | 27 | import com.pixplicity.easyprefs.library.Prefs; 28 | 29 | import java.util.ArrayList; 30 | import java.util.Date; 31 | 32 | import me.micrusa.amaztimer.Constants; 33 | import me.micrusa.amaztimer.database.AmazTimerDB; 34 | import me.micrusa.amaztimer.database.DBUtils; 35 | import me.micrusa.amaztimer.database.objects.Workout; 36 | import me.micrusa.amaztimer.utils.sensors.heartrate.hrUtils; 37 | 38 | public class SaveWorkout { 39 | 40 | private static Workout workout; 41 | 42 | private static long setStartTime = 0; 43 | private static long startTime = 0; 44 | 45 | public static void startWorkout(){ 46 | workout = new Workout(); 47 | 48 | workout.time = new Date().getTime(); 49 | workout.hr = new ArrayList<>(); 50 | workout.sets = new ArrayList<>(); 51 | workout.setsReps = new ArrayList<>(); 52 | 53 | startTime = System.currentTimeMillis(); 54 | setStartTime = System.currentTimeMillis(); 55 | } 56 | 57 | public static void addHrValue(int hr){ 58 | workout.hr.add(hr); 59 | } 60 | 61 | public static void endSet(boolean saveSets, int reps){ 62 | int setTime = (int) (System.currentTimeMillis() - setStartTime); 63 | if(setTime >= 100) 64 | workout.sets.add(setTime / 1000); 65 | setStartTime = System.currentTimeMillis(); 66 | if(saveSets && Prefs.getBoolean(Constants.KEY_REPSCOUNT, false)) 67 | workout.setsReps.add(reps); 68 | } 69 | 70 | public static void endWorkout(){ 71 | workout.totalTime = (int) (System.currentTimeMillis() - startTime) / 1000; 72 | workout.kcal = hrUtils.calculateKcal(hrUtils.getAvg(workout.hr), workout.totalTime); 73 | 74 | //Save to DB in a second Thread to avoid an UI lock 75 | new Thread(() -> { 76 | AmazTimerDB db = DBUtils.createInstance(); 77 | 78 | db.workoutDao().insertAll(workout); 79 | 80 | db.close(); 81 | }).start(); 82 | 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/saveworkout/ui/SavedWorkoutsActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.saveworkout.ui; 26 | 27 | import android.app.AlertDialog; 28 | import android.content.Intent; 29 | import android.os.Bundle; 30 | import android.os.Handler; 31 | import android.view.View; 32 | import android.widget.AdapterView; 33 | import android.widget.ListView; 34 | 35 | import androidx.appcompat.app.AppCompatActivity; 36 | 37 | import java.util.List; 38 | 39 | import me.micrusa.amaztimer.R; 40 | import me.micrusa.amaztimer.database.AmazTimerDB; 41 | import me.micrusa.amaztimer.database.DBUtils; 42 | import me.micrusa.amaztimer.database.objects.Workout; 43 | 44 | public class SavedWorkoutsActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener { 45 | 46 | private ListView lv; 47 | 48 | @Override 49 | protected void onCreate(Bundle savedInstanceState) { 50 | super.onCreate(savedInstanceState); 51 | setContentView(R.layout.activity_saved_workouts); 52 | 53 | lv = findViewById(R.id.saved_workouts_lv); 54 | 55 | lv.setOnItemClickListener(this); 56 | lv.setOnItemLongClickListener(this); 57 | 58 | addDataToList(); 59 | } 60 | 61 | private void addDataToList(){ 62 | final Handler handler = new Handler(); 63 | new Thread(() -> { 64 | AmazTimerDB db = DBUtils.createInstance(); 65 | List workouts = db.workoutDao().getAll(); 66 | db.close(); 67 | 68 | handler.post(() -> lv.setAdapter(new WorkoutAdapter(this, workouts))); 69 | }).start(); 70 | } 71 | 72 | @Override 73 | public void onItemClick(AdapterView adapterView, View view, int i, long l) { 74 | Workout workout = (Workout) adapterView.getItemAtPosition(i); 75 | Intent intent = new Intent(this, WorkoutViewerActivity.class); 76 | intent.putExtra("id", workout.time); 77 | startActivity(intent); 78 | } 79 | 80 | @Override 81 | public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { 82 | Workout workout = (Workout) adapterView.getItemAtPosition(i); 83 | new AlertDialog.Builder(this) 84 | .setTitle(R.string.deleteworkout) 85 | .setPositiveButton("Yes", (di, i1) -> { 86 | new Thread(() -> { 87 | AmazTimerDB database = DBUtils.createInstance(); 88 | 89 | database.workoutDao().delete(workout); 90 | database.close(); 91 | }).start(); 92 | addDataToList(); 93 | }) 94 | .setNegativeButton("No", (dialogI, i1) -> dialogI.dismiss()) 95 | .create().show(); 96 | return true; 97 | } 98 | } -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/saveworkout/ui/WorkoutAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.saveworkout.ui; 26 | 27 | import android.content.Context; 28 | import android.view.LayoutInflater; 29 | import android.view.View; 30 | import android.view.ViewGroup; 31 | import android.widget.ArrayAdapter; 32 | import android.widget.TextView; 33 | 34 | import java.text.SimpleDateFormat; 35 | import java.util.Date; 36 | import java.util.List; 37 | import java.util.Locale; 38 | import java.util.TimeZone; 39 | 40 | import me.micrusa.amaztimer.R; 41 | import me.micrusa.amaztimer.database.objects.Workout; 42 | import me.micrusa.amaztimer.utils.sensors.heartrate.hrUtils; 43 | 44 | public class WorkoutAdapter extends ArrayAdapter { 45 | 46 | public WorkoutAdapter(Context context, List workouts){ 47 | super(context, 0, workouts); 48 | } 49 | 50 | @Override 51 | public View getView(int position, View convertView, ViewGroup parent){ 52 | final Workout workout = getItem(position); 53 | return getConvertedView(convertView, parent, workout); 54 | } 55 | 56 | private View getConvertedView(View convertView, ViewGroup parent, Workout workout){ 57 | if(convertView == null) { 58 | convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_workout, parent, false); 59 | 60 | TextView title = convertView.findViewById(R.id.workout_item_title); 61 | TextView duration = convertView.findViewById(R.id.workout_item_duration); 62 | TextView hr = convertView.findViewById(R.id.workout_item_hr); 63 | 64 | SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy HH:mm", Locale.US); 65 | String titleText = format.format(new Date(workout.time)); 66 | title.setText(titleText); 67 | 68 | SimpleDateFormat format1 = new SimpleDateFormat("HH:mm:ss", Locale.US); 69 | format1.setTimeZone(TimeZone.getTimeZone("GMT")); 70 | String durationText = format1.format(new Date(workout.totalTime * 1000)); 71 | duration.setText(durationText); 72 | 73 | String hrText = hrUtils.getAvg(workout.hr) + "bpm"; 74 | hr.setText(hrText); 75 | } 76 | return convertView; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/PrefsUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils; 26 | 27 | import com.pixplicity.easyprefs.library.Prefs; 28 | 29 | import me.micrusa.amaztimer.Constants; 30 | 31 | public class PrefsUtil { 32 | 33 | public static int getWeight(){ 34 | return Integer.parseInt(Prefs.getString(Constants.KEY_WEIGHT, String.valueOf(Constants.DEFAULT_WEIGHT))); 35 | } 36 | 37 | public static int getAge(){ 38 | return Constants.CURRENT_YEAR - Integer.parseInt(Prefs.getString(Constants.KEY_AGE, String.valueOf(Constants.DEFAULT_AGE))); 39 | } 40 | 41 | public static boolean isMale(){ 42 | return Boolean.parseBoolean(Prefs.getString(Constants.KEY_GENDER, "true")); 43 | } 44 | 45 | public static int getVibration(int vibration){ 46 | int multiplier = Prefs.getInt(Constants.KEY_VIBRATION, 2); 47 | 48 | //Disable multiplier on haptic vibrations 49 | if(vibration == Constants.HAPTIC_VIBRATION) return vibration; 50 | 51 | switch(multiplier){ 52 | case 1: 53 | vibration = vibration / 2; 54 | break; 55 | case 3: 56 | vibration = vibration * 2; 57 | break; 58 | default: 59 | break; 60 | } 61 | return vibration; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/button/ButtonEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.button; 26 | 27 | import com.pixplicity.easyprefs.library.Prefs; 28 | 29 | import me.micrusa.amaztimer.Constants; 30 | 31 | import static me.micrusa.amaztimer.utils.devices.AmazfitUtils.isPace; 32 | import static me.micrusa.amaztimer.utils.devices.AmazfitUtils.isStratos; 33 | import static me.micrusa.amaztimer.utils.devices.AmazfitUtils.isStratos3; 34 | import static me.micrusa.amaztimer.utils.devices.AmazfitUtils.isStratosNewKeys; 35 | import static me.micrusa.amaztimer.utils.devices.AmazfitUtils.isVerge; 36 | 37 | public class ButtonEvent { 38 | 39 | public static final int KEY_UP = 0; 40 | public static final int KEY_SELECT = 1; 41 | public static final int KEY_DOWN = 2; 42 | 43 | static final int S3_KEY_UP = 3; 44 | static final int S3_KEY_MIDDLE_UP = 4; 45 | static final int S3_KEY_MIDDLE_DOWN = 5; 46 | 47 | private boolean isLongPress; 48 | private boolean isInverted; 49 | private int key; 50 | 51 | public ButtonEvent(boolean IsLongPress, int Key){ 52 | this.isLongPress = IsLongPress; 53 | this.key = Key; 54 | this.isInverted = Prefs.getBoolean(Constants.KEY_INVERTKEYS, false); 55 | } 56 | 57 | public boolean isLongPress(){ 58 | return this.isLongPress; 59 | } 60 | 61 | public int getKey(){ 62 | int finalKey = -5; //If nothing changed return -5 to not trigger anything 63 | if(isSingleKey()){ 64 | if(isLongPress()) 65 | finalKey = KEY_UP; 66 | else 67 | finalKey = KEY_SELECT; 68 | } else if(isStratos3()) 69 | switch(key){ 70 | case S3_KEY_UP: 71 | finalKey = KEY_SELECT; 72 | break; 73 | case S3_KEY_MIDDLE_UP: 74 | finalKey = KEY_UP; 75 | break; 76 | case S3_KEY_MIDDLE_DOWN: 77 | finalKey = KEY_DOWN; 78 | break; 79 | default: 80 | break; 81 | } 82 | else if(isStratos2Old()) 83 | finalKey = key; 84 | 85 | return getInverted(finalKey); 86 | } 87 | 88 | private int getInverted(int key){ 89 | if(isSingleKey()) 90 | key = key == KEY_UP ? KEY_SELECT : KEY_UP; 91 | else if (isInverted && key != KEY_SELECT) 92 | key = key == KEY_UP ? KEY_DOWN : KEY_UP; 93 | 94 | return key; 95 | } 96 | 97 | private boolean isSingleKey(){ //Stratos new layout can just use center button 98 | return isPace() || isVerge() || (isStratosNewKeys() && key == KEY_SELECT); 99 | } 100 | 101 | private boolean isStratos2Old(){ 102 | return isStratos() && !isStratosNewKeys(); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/button/ButtonInterface.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.button; 26 | 27 | public interface ButtonInterface { 28 | void onKeyEvent(ButtonEvent buttonEvent); 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/button/selector/ButtonSelector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.button.selector; 26 | 27 | import android.content.Context; 28 | import android.widget.Button; 29 | 30 | import androidx.core.content.ContextCompat; 31 | 32 | import me.micrusa.amaztimer.R; 33 | import me.micrusa.amaztimer.utils.devices.AmazfitUtils; 34 | 35 | public class ButtonSelector extends Selector { 36 | private Button[] buttons; 37 | 38 | public ButtonSelector(Button[] buttons, Context context){ 39 | super(context); 40 | this.buttons = buttons; 41 | refreshSelectedButton(); 42 | } 43 | 44 | public void clickButton(){ 45 | Button btn = buttons[selectedButton]; 46 | btn.performClick(); 47 | } 48 | 49 | public void refreshSelectedButton(){ 50 | //Set default background for previous selected button 51 | for (Button button : buttons) { 52 | button.setBackground(ContextCompat.getDrawable(context, R.drawable.circle_button)); 53 | } 54 | 55 | //Make sure button is not under zero or over buttons length 56 | if(selectedButton < 0){ 57 | selectedButton = buttons.length - 1; 58 | } else if(selectedButton >= buttons.length){ 59 | selectedButton = 0; 60 | } 61 | 62 | //Set selected background for new selected button 63 | buttons[selectedButton].setBackground(ContextCompat.getDrawable(context, R.drawable.selected_button)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/button/selector/Selector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.button.selector; 26 | 27 | import android.content.Context; 28 | 29 | import me.micrusa.amaztimer.utils.button.ButtonEvent; 30 | import me.micrusa.amaztimer.utils.button.ButtonInterface; 31 | import me.micrusa.amaztimer.utils.button.ButtonListener; 32 | import me.micrusa.amaztimer.utils.devices.AmazfitUtils; 33 | 34 | public abstract class Selector implements ButtonInterface { 35 | protected Context context; 36 | protected int selectedButton = 0; 37 | protected ButtonListener buttonListener; 38 | 39 | public Selector(Context context){ 40 | if(!AmazfitUtils.isAmazfit()) return; 41 | buttonListener = new ButtonListener(); 42 | this.context = context; 43 | } 44 | 45 | public abstract void refreshSelectedButton(); 46 | public abstract void clickButton(); 47 | 48 | public void startListening(){ 49 | if(!AmazfitUtils.isAmazfit()) return; 50 | buttonListener.start(context, this); 51 | refreshSelectedButton(); 52 | } 53 | 54 | public void stopListening(){ 55 | if(!AmazfitUtils.isAmazfit()) return; 56 | buttonListener.stop(); 57 | } 58 | 59 | @Override 60 | public void onKeyEvent(ButtonEvent e) { 61 | switch(e.getKey()){ 62 | case ButtonEvent.KEY_UP: 63 | selectedButton--; 64 | refreshSelectedButton(); 65 | break; 66 | case ButtonEvent.KEY_DOWN: 67 | selectedButton++; 68 | refreshSelectedButton(); 69 | break; 70 | case ButtonEvent.KEY_SELECT: 71 | clickButton(); 72 | break; 73 | default: 74 | break; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/devices/AmazfitUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.devices; 26 | 27 | import java.io.File; 28 | import java.util.Arrays; 29 | 30 | public class AmazfitUtils { 31 | public static boolean isAmazfit(){ 32 | return isPace() || isStratos() || isVerge() || isStratos3(); 33 | } 34 | 35 | public static boolean isPace(){ 36 | return checkIfModel(new String[]{"A1602", "A1612"}, "Pace") || new File("/system/.pace_hybrid").exists(); 37 | } 38 | 39 | public static boolean isStratos(){ 40 | return checkIfModel(new String[]{"A1609", "A1619"}, "Stratos") && !new File("/system/.pace_hybrid").exists(); 41 | } 42 | 43 | public static boolean isVerge(){ 44 | return checkIfModel(new String[]{"A1801", "A1811"}, "Verge"); 45 | } 46 | 47 | public static boolean isStratos3(){ 48 | return checkIfModel(new String[]{"A1928", "A1929"}, "Stratos 3"); 49 | } 50 | 51 | public static boolean isStratosNewKeys(){ 52 | return isStratos() && SystemProperties.getBoolean("prop.keyfeature.five", false); 53 | } 54 | 55 | public static boolean checkIfModel(String[] targetModels, String Name){ 56 | String model = SystemProperties.getSystemProperty("ro.build.huami.model"); 57 | boolean check = Arrays.asList(targetModels).contains(model); 58 | //Logger.info("Current model (" + model + ") is " + ((check) ? "" : "NOT ") + "a " + Name); 59 | return check; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/devices/SystemProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.devices; 26 | 27 | import android.os.Build; 28 | 29 | import org.tinylog.Logger; 30 | 31 | import java.io.BufferedReader; 32 | import java.io.IOException; 33 | import java.io.InputStreamReader; 34 | 35 | public class SystemProperties { 36 | 37 | public static String getSystemProperty(String key) { 38 | String val = ""; 39 | try { 40 | Process p = new ProcessBuilder("/system/bin/getprop", key).redirectErrorStream(true).start(); 41 | BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); 42 | String line; 43 | while ((line = br.readLine()) != null) { 44 | val = line; 45 | } 46 | p.destroy(); 47 | } catch (IOException e) { 48 | e.printStackTrace(); 49 | } 50 | return val; 51 | } 52 | 53 | public static boolean getBoolean(String key, boolean def) { 54 | try { 55 | return Boolean.parseBoolean(getSystemProperty(key)); 56 | } catch (Exception e) { 57 | Logger.error(e); 58 | return def; 59 | } 60 | } 61 | 62 | public static String getDeviceName(){ 63 | String device; 64 | if(AmazfitUtils.isPace()) 65 | device = "Huami Amazfit Pace"; 66 | else if(AmazfitUtils.isStratos()) 67 | device = "Huami Amazfit Stratos"; 68 | else if(AmazfitUtils.isVerge()) 69 | device = "Huami Amazfit Verge"; 70 | else if(AmazfitUtils.isStratos3()) 71 | device = "Huami Amazfit Stratos 3"; 72 | else 73 | device = Build.MODEL; 74 | Logger.debug("getDeviceName() detected device " + device); 75 | return device; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/handlers/chronoHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.handlers; 26 | 27 | import android.os.Handler; 28 | import android.widget.TextView; 29 | 30 | import me.micrusa.amaztimer.utils.Utils; 31 | 32 | public class chronoHandler { 33 | 34 | private boolean running; 35 | private thread chronoThread; 36 | 37 | public chronoHandler(TextView chrono){ 38 | chronoThread = new thread(chrono, new Handler()); 39 | chronoThread.start(); 40 | running = true; 41 | } 42 | 43 | public void stop(){ 44 | if(running){ 45 | running = false; 46 | chronoThread.interrupt(); 47 | } 48 | } 49 | 50 | private class thread extends Thread { 51 | 52 | private TextView chrono; 53 | private int timeElapsed; 54 | private Handler handler; 55 | 56 | public thread(TextView chrono, Handler handler){ 57 | this.chrono = chrono; 58 | this.handler = handler; 59 | } 60 | 61 | public void run(){ 62 | while(!Thread.currentThread().isInterrupted()){ 63 | try { 64 | if(!running) break; 65 | handler.post(() -> chrono.setText(Utils.formatTime(timeElapsed++))); 66 | sleep(1000); 67 | } catch (InterruptedException e) { 68 | break; 69 | } 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/handlers/hrZoneHandler.java: -------------------------------------------------------------------------------- 1 | package me.micrusa.amaztimer.utils.handlers; 2 | 3 | import android.content.res.Resources; 4 | import android.graphics.drawable.Drawable; 5 | import android.view.View; 6 | 7 | import com.pixplicity.easyprefs.library.Prefs; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | import me.micrusa.amaztimer.R; 13 | import me.micrusa.amaztimer.Constants; 14 | import me.micrusa.amaztimer.utils.sensors.heartrate.hrUtils; 15 | 16 | import static java.lang.Math.abs; 17 | 18 | 19 | public class hrZoneHandler { 20 | 21 | private View hrView; 22 | private boolean enable; 23 | private static final Map HR_ZONES = new HashMap<>(); 24 | 25 | public hrZoneHandler(View hrView){ 26 | this.hrView = hrView; 27 | enable = Prefs.getBoolean(Constants.KEY_HRZONE, true); 28 | setupZonesMap(); 29 | } 30 | 31 | private void setupZonesMap(){ 32 | Resources res = hrView.getResources(); 33 | HR_ZONES.put(new int[]{0, 60}, res.getDrawable(R.color.zonelow)); 34 | HR_ZONES.put(new int[]{60, 70}, res.getDrawable(R.color.zonelowmid)); 35 | HR_ZONES.put(new int[]{70, 80}, res.getDrawable(R.color.zonemid)); 36 | HR_ZONES.put(new int[]{80, 90}, res.getDrawable(R.color.zonemidhigh)); 37 | HR_ZONES.put(new int[]{90, 130}, res.getDrawable(R.color.zonehigh)); 38 | } 39 | 40 | public void addHrValue(int value){ 41 | if(!enable) return; 42 | int hrZone = hrUtils.hrZonePercentageInt(value); 43 | 44 | for(Map.Entry entry : HR_ZONES.entrySet()){ 45 | int[] zones = (int[]) entry.getKey(); 46 | Drawable drawable = (Drawable) entry.getValue(); 47 | 48 | if(zones.length >= 2 && hrZone > zones[0] && hrZone < zones[1]){ 49 | hrView.setBackground(drawable); 50 | return; 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/handlers/timeHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.handlers; 26 | 27 | import android.os.Handler; 28 | import android.os.Looper; 29 | import android.widget.TextView; 30 | 31 | import java.text.SimpleDateFormat; 32 | import java.util.Date; 33 | import java.util.Locale; 34 | 35 | public class timeHandler { 36 | 37 | private Handler timeHandler; 38 | 39 | public timeHandler(TextView time){ 40 | timeHandler = new Handler(Looper.getMainLooper()); 41 | timeHandler.postDelayed(new Runnable() { 42 | @Override 43 | public void run() { 44 | time.setText(new SimpleDateFormat("HH:mm", Locale.US).format(new Date())); 45 | timeHandler.postDelayed(this, 1000); 46 | } 47 | }, 10); 48 | } 49 | 50 | public void stop(){ 51 | timeHandler.removeCallbacksAndMessages(null); 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/handlers/timerHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.handlers; 26 | 27 | import android.content.Context; 28 | import android.os.CountDownTimer; 29 | import android.os.Handler; 30 | import android.widget.TextView; 31 | 32 | import me.micrusa.amaztimer.Constants; 33 | import me.micrusa.amaztimer.utils.Utils; 34 | import me.micrusa.amaztimer.activities.TimerActivity; 35 | 36 | public class timerHandler { 37 | 38 | private TextView timerText; 39 | private CountDownTimer timer; 40 | private boolean running; 41 | private Context context; 42 | 43 | public timerHandler(TextView timerText, int seconds, timerInterface timerInterface, Context paramContext){ 44 | this.timerText = timerText; 45 | this.context = paramContext; 46 | running = true; 47 | timer = new CountDownTimer(seconds * 1000, 1000) { 48 | @Override 49 | public void onTick(long l) { 50 | updateTimer(l); 51 | } 52 | 53 | @Override 54 | public void onFinish() { 55 | if(!running) return; 56 | running = false; 57 | timerInterface.onFinish(); 58 | } 59 | }; 60 | timer.start(); 61 | } 62 | 63 | public void stop(){ 64 | if(running) 65 | timer.cancel(); 66 | running = false; 67 | } 68 | 69 | private void updateTimer(long millis){ 70 | int time = (int) millis / 1000; 71 | if(!running || !TimerActivity.isRunning) { 72 | timer.cancel(); 73 | return; 74 | } //Avoid vibrations/changes when not running 75 | timerText.setText(Utils.formatTime(time)); 76 | if(time < 4){ 77 | Utils.vibrate(Constants.SHORT_VIBRATION, context, true); 78 | if(time == 1){ 79 | new Handler().postDelayed(() -> { 80 | Utils.vibrate(Constants.LONG_VIBRATION, context, true); 81 | timerText.setText(Utils.formatTime(0)); 82 | }, 950); 83 | } 84 | } 85 | } 86 | 87 | public static interface timerInterface{ 88 | void onFinish(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/heartrate/hrUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.heartrate; 26 | 27 | import java.util.List; 28 | 29 | import me.micrusa.amaztimer.utils.PrefsUtil; 30 | 31 | public class hrUtils { 32 | public static String hrZonePercentage(int hr){ 33 | return hrZonePercentageInt(hr) + "%"; 34 | } 35 | 36 | public static int hrZonePercentageInt(int hr){ 37 | if(hr == 0 | PrefsUtil.getAge() == 0) 38 | return 0; 39 | 40 | //Source: https://www.ntnu.edu/cerg/hrmax#:~:text=Based%20on%20these%20tests%20we,211%20%2D%200.64*age%22. 41 | return (int) (hr * 100 / getMaxHr()); 42 | } 43 | 44 | public static int calculateKcal(int avgHr, int time){ 45 | int age = PrefsUtil.getAge(); 46 | int weight = PrefsUtil.getWeight(); 47 | boolean isMale = PrefsUtil.isMale(); 48 | if(avgHr==0||time==0||age==0||weight==0){return 0;} 49 | double kcalPerMin; 50 | //Formula from https://www.calculatorpro.com/calculator/calories-burned-by-heart-rate/ 51 | if(isMale){ 52 | kcalPerMin = (-55.0969 + (0.6309 * avgHr) + (0.1988 * weight) + (0.2017 * age)) / 4.184; 53 | }else{ 54 | kcalPerMin = (-20.4022 + (0.4472 * avgHr) + (0.1263 * weight) + (0.074) * age) / 4.184; 55 | } 56 | //Calculate kcal from kcal/min 57 | return (int) (kcalPerMin * time) / 60; 58 | } 59 | 60 | public static double getMaxHr(){ 61 | return 211 - 0.64 * PrefsUtil.getAge(); 62 | } 63 | 64 | public static int getAvg(List hr){ 65 | int totalHr = 0; 66 | for (int value : hr) { 67 | totalHr += value; 68 | } 69 | if(hr.size() != 0) 70 | return totalHr / hr.size(); 71 | else 72 | return 0; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/heartrate/listeners/experimentalListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.heartrate.listeners; 26 | 27 | import android.content.Context; 28 | import android.hardware.Sensor; 29 | import android.hardware.SensorEvent; 30 | import android.hardware.SensorEventListener; 31 | import android.hardware.SensorManager; 32 | import android.os.Handler; 33 | 34 | import java.util.ArrayList; 35 | 36 | import me.micrusa.amaztimer.utils.sensors.heartrate.hrSensor; 37 | import me.micrusa.amaztimer.utils.sensors.objects.Listener; 38 | import me.micrusa.amaztimer.utils.sensors.repsCounter.utils.Filtering; 39 | 40 | public class experimentalListener implements SensorEventListener, Listener { 41 | 42 | private ArrayList allHr = new ArrayList<>(); 43 | private long lastTime; 44 | 45 | public experimentalListener(){ 46 | this.lastTime = System.currentTimeMillis(); 47 | } 48 | 49 | @Override 50 | public void onSensorChanged(SensorEvent event) { 51 | float thisValue = event.values[0] / 100; 52 | if(!(thisValue >= 220 || thisValue <= 40)) 53 | allHr.add(thisValue); //Add just great values for a more accurate result 54 | 55 | long now = System.currentTimeMillis(); 56 | if(now - lastTime >= 750 && allHr.size() >= 1) { //This sensor is SO fast so limit rate to a value every 750ms 57 | double[] values = Filtering.filterSignal(allHr, 80000, 30000, 2, 0, 15); 58 | double totalValue = 0; 59 | for(double value : values) 60 | totalValue += value; 61 | hrSensor.getInstance().newValue((int) (totalValue / values.length)); 62 | lastTime = now; 63 | } 64 | } 65 | 66 | @Override 67 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 68 | hrSensor.getInstance().onAccuracyChanged(sensor, accuracy); 69 | } 70 | 71 | public void register(Context context){ 72 | SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 73 | sm.registerListener(this, sm.getDefaultSensor(65538 /*PPG Sensor*/), 74 | 200_000 /*This value is ignored*/, 500_000 /*500ms batching*/, 75 | new Handler() /*Use a handler to avoid freezes*/); 76 | } 77 | public void unregister(Context context){ 78 | SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 79 | sm.unregisterListener(this); 80 | } 81 | } -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/heartrate/listeners/mainListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.heartrate.listeners; 26 | 27 | import android.content.Context; 28 | import android.hardware.Sensor; 29 | import android.hardware.SensorEvent; 30 | import android.hardware.SensorEventListener; 31 | import android.hardware.SensorManager; 32 | import android.os.Handler; 33 | 34 | import me.micrusa.amaztimer.utils.sensors.heartrate.hrSensor; 35 | import me.micrusa.amaztimer.utils.sensors.objects.Listener; 36 | 37 | public class mainListener implements SensorEventListener, Listener { 38 | @Override 39 | public void onSensorChanged(SensorEvent event) { 40 | hrSensor.getInstance().newValue((int) event.values[0]); 41 | } 42 | @Override 43 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 44 | hrSensor.getInstance().onAccuracyChanged(sensor, accuracy); 45 | } 46 | 47 | public void register(Context context){ 48 | SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 49 | sm.registerListener(this, sm.getDefaultSensor(21 /*Android HR sensor (processed data)*/), 50 | SensorManager.SENSOR_DELAY_FASTEST, 500_000 /*500ms batching*/, 51 | new Handler() /*Use a handler to avoid freezes*/); 52 | } 53 | public void unregister(Context context){ 54 | SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 55 | sm.unregisterListener(this); 56 | } 57 | } -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/objects/Listener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.objects; 26 | 27 | import android.content.Context; 28 | 29 | public interface Listener { 30 | void register(Context context); 31 | void unregister(Context context); 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/repsCounter/RepsConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.repsCounter; 26 | 27 | import android.content.Context; 28 | 29 | import java.util.ArrayList; 30 | 31 | import me.micrusa.amaztimer.R; 32 | import me.micrusa.amaztimer.utils.sensors.repsCounter.objects.Exercise; 33 | 34 | public class RepsConstants { 35 | 36 | public static final int PEAK_CHECKING_INTERVAL = 1000; //1s 37 | 38 | public static final Exercise[] EXERCISES = new Exercise[]{ 39 | new Exercise(R.string.bicepscurl, 13, 29, 2, 'X'), 40 | new Exercise(R.string.benchpress, 13, 27, 2, 'X'), 41 | new Exercise(R.string.crunches, 13, 27, 2, 'X'), 42 | new Exercise(R.string.pullups, 13, 25, 1, 'X'), 43 | new Exercise(R.string.jjacks, 13, 29, 2, 'X'), 44 | new Exercise(R.string.other, 13, 27, 2, 'X') 45 | }; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/repsCounter/RepsListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.repsCounter; 26 | 27 | public interface RepsListener { 28 | void onNewRepsValue(int reps); 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/repsCounter/listeners/Accelerometer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.repsCounter.listeners; 26 | 27 | import android.content.Context; 28 | import android.hardware.Sensor; 29 | import android.hardware.SensorEvent; 30 | import android.hardware.SensorEventListener; 31 | import android.hardware.SensorManager; 32 | import android.os.Handler; 33 | 34 | import org.tinylog.Logger; 35 | 36 | import java.util.ArrayList; 37 | 38 | import me.micrusa.amaztimer.utils.sensors.objects.Listener; 39 | import me.micrusa.amaztimer.utils.sensors.repsCounter.RepsCounter; 40 | 41 | public class Accelerometer implements SensorEventListener, Listener { 42 | 43 | @Override 44 | public void onSensorChanged(SensorEvent event) { 45 | float accelerationX = event.values[0]; 46 | float accelerationY = event.values[1]; 47 | float accelerationZ = event.values[2]; 48 | 49 | //Noise filtering 50 | if (Math.abs(accelerationX) < RepsCounter.CURRENT_EXERCISE.MIN_MOVEMENT_TO_RECORD) accelerationX = 0; 51 | if (Math.abs(accelerationY) < RepsCounter.CURRENT_EXERCISE.MIN_MOVEMENT_TO_RECORD) accelerationY = 0; 52 | if (Math.abs(accelerationZ) < RepsCounter.CURRENT_EXERCISE.MIN_MOVEMENT_TO_RECORD) accelerationZ = 0; 53 | 54 | //Logger.debug("Received X:" + accelerationX + " Y:" + accelerationY + " Z:" + accelerationZ); 55 | 56 | RepsCounter.newAccelValues(accelerationX, accelerationY, accelerationZ); 57 | } 58 | 59 | @Override 60 | public void onAccuracyChanged(Sensor sensor, int i) { 61 | 62 | } 63 | 64 | @Override 65 | public void register(Context context) { 66 | SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 67 | Sensor accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 68 | 69 | sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME, new Handler()); 70 | } 71 | 72 | @Override 73 | public void unregister(Context context) { 74 | SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 75 | sm.unregisterListener(this); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/repsCounter/listeners/Gyroscope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.repsCounter.listeners; 26 | 27 | import android.content.Context; 28 | import android.hardware.Sensor; 29 | import android.hardware.SensorEvent; 30 | import android.hardware.SensorEventListener; 31 | import android.hardware.SensorManager; 32 | import android.os.Handler; 33 | 34 | import me.micrusa.amaztimer.utils.sensors.objects.Listener; 35 | import me.micrusa.amaztimer.utils.sensors.repsCounter.RepsCounter; 36 | 37 | public class Gyroscope implements SensorEventListener, Listener { 38 | @Override 39 | public void onSensorChanged(SensorEvent event) { 40 | RepsCounter.newGyroValues(event.values[0], event.values[2]); 41 | } 42 | 43 | @Override 44 | public void onAccuracyChanged(Sensor sensor, int i) { 45 | 46 | } 47 | 48 | @Override 49 | public void register(Context context) { 50 | SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 51 | Sensor gyro = sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE); 52 | 53 | sm.registerListener(this, gyro, SensorManager.SENSOR_DELAY_GAME, new Handler()); 54 | } 55 | 56 | @Override 57 | public void unregister(Context context) { 58 | SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 59 | sm.unregisterListener(this); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/repsCounter/objects/Exercise.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.repsCounter.objects; 26 | 27 | public class Exercise { 28 | 29 | private int name_stringid; 30 | 31 | public int PEAKS_POSITIONS_CHECK; 32 | public int CHEBYSHEV_FILTER_RIPPLE_PERCENT; 33 | public float MIN_MOVEMENT_TO_RECORD; 34 | public char AXIS; 35 | 36 | public Exercise(int name_id, int PEAKS_POSITIONS_CHECK, int CHEBYSHEV_FILTER_RIPPLE_PERCENT, float MIN_MOVEMENT_TO_RECORD, char axis){ 37 | this.name_stringid = name_id; 38 | this.PEAKS_POSITIONS_CHECK = PEAKS_POSITIONS_CHECK; 39 | this.CHEBYSHEV_FILTER_RIPPLE_PERCENT = CHEBYSHEV_FILTER_RIPPLE_PERCENT; 40 | this.MIN_MOVEMENT_TO_RECORD = MIN_MOVEMENT_TO_RECORD; 41 | this.AXIS = axis; 42 | } 43 | 44 | public int getNameId(){ 45 | return name_stringid; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/repsCounter/ui/ExerciseAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.repsCounter.ui; 26 | 27 | import android.content.Context; 28 | import android.view.LayoutInflater; 29 | import android.view.View; 30 | import android.view.ViewGroup; 31 | import android.widget.ArrayAdapter; 32 | import android.widget.TextView; 33 | 34 | import androidx.annotation.NonNull; 35 | 36 | import java.util.ArrayList; 37 | 38 | import me.micrusa.amaztimer.R; 39 | import me.micrusa.amaztimer.utils.sensors.repsCounter.objects.Exercise; 40 | 41 | public class ExerciseAdapter extends ArrayAdapter { 42 | 43 | public ExerciseAdapter(@NonNull Context context, ArrayList exs) { 44 | super(context, 0, exs); 45 | } 46 | 47 | @Override 48 | public View getView(int position, View convertView, ViewGroup parent) { 49 | if (convertView == null) { 50 | final Exercise exercise = getItem(position); 51 | 52 | convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_exercise, parent, false); 53 | 54 | TextView name = convertView.findViewById(R.id.exerciseName); 55 | name.setText(exercise.getNameId()); 56 | } 57 | 58 | return convertView; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/repsCounter/ui/dialog/ExerciseDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.repsCounter.ui.dialog; 26 | 27 | import android.app.Dialog; 28 | import android.content.Context; 29 | import android.os.Bundle; 30 | import android.view.Window; 31 | import android.widget.ListView; 32 | 33 | import androidx.annotation.NonNull; 34 | 35 | import java.util.ArrayList; 36 | import java.util.Arrays; 37 | 38 | import me.micrusa.amaztimer.R; 39 | import me.micrusa.amaztimer.utils.sensors.repsCounter.RepsConstants; 40 | import me.micrusa.amaztimer.utils.sensors.repsCounter.RepsCounter; 41 | import me.micrusa.amaztimer.utils.sensors.repsCounter.objects.Exercise; 42 | import me.micrusa.amaztimer.utils.sensors.repsCounter.ui.ExerciseAdapter; 43 | 44 | public abstract class ExerciseDialog extends Dialog { 45 | 46 | protected Context context; 47 | private ListView lv; 48 | 49 | public ExerciseDialog(@NonNull Context context) { 50 | super(context); 51 | 52 | this.context = context; 53 | } 54 | 55 | @Override 56 | protected void onCreate(Bundle savedInstanceState) { 57 | super.onCreate(savedInstanceState); 58 | requestWindowFeature(Window.FEATURE_NO_TITLE); 59 | setContentView(R.layout.dialog_exercise_select); 60 | 61 | lv = findViewById(R.id.exerciseList); 62 | ExerciseAdapter adapter = new ExerciseAdapter(context, new ArrayList<>(Arrays.asList(RepsConstants.EXERCISES))); 63 | 64 | lv.setAdapter(adapter); 65 | lv.setOnItemClickListener((adapterView, view, i, l) -> { 66 | Exercise ex = (Exercise) adapterView.getItemAtPosition(i); 67 | onExerciseClick(ex); 68 | 69 | dismiss(); 70 | }); 71 | } 72 | 73 | public void onExerciseClick(Exercise exercise){ 74 | RepsCounter.setExercise(exercise); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/repsCounter/ui/dialog/NewRepExerciseDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.repsCounter.ui.dialog; 26 | 27 | import android.content.Context; 28 | 29 | import androidx.annotation.NonNull; 30 | 31 | public class NewRepExerciseDialog extends ExerciseDialog { 32 | public NewRepExerciseDialog(@NonNull Context context) { 33 | super(context); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/sensors/repsCounter/utils/PeaksChecker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.sensors.repsCounter.utils; 26 | 27 | import java.util.HashMap; 28 | 29 | import me.micrusa.amaztimer.utils.sensors.repsCounter.RepsCounter; 30 | 31 | public class PeaksChecker { 32 | 33 | public static HashMap get(double[] arr) { 34 | HashMap peaks = new HashMap<>(); 35 | 36 | for (int i = 1; i < arr.length; i++) 37 | if (isPeak(arr, i, RepsCounter.CURRENT_EXERCISE.PEAKS_POSITIONS_CHECK)) 38 | peaks.put(arr[i], i); 39 | 40 | return peaks; 41 | } 42 | 43 | private static boolean isPeak(double[] arr, int i, int checkPositions){ 44 | for(int x = 1; x <= checkPositions; x++){ 45 | boolean peak = isPeakLoop(arr, i, x); 46 | if (!peak) return false; 47 | } 48 | return true; 49 | } 50 | 51 | private static boolean isPeakLoop(double[] arr, int i, int checkPos){ 52 | if(i - checkPos >= 0 && i + checkPos < arr.length) 53 | return arr[i - checkPos] <= arr[i] && arr[i] >= arr[i + checkPos] && arr[i] != 0; 54 | else 55 | return false; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/tcx/TCXConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.tcx; 26 | 27 | public class TCXConstants { 28 | public final static String STATUS_ACTIVE = "Active"; 29 | public final static String STATUS_RESTING = "Resting"; 30 | 31 | public final static String DATE_FORMAT = "yyyy-MM-dd"; 32 | public final static String CHAR_DATETIME = "T"; 33 | public final static String TIME_FORMAT = "HH:mm:ss"; 34 | public final static String CHAR_AFTERTIME = "Z"; 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/tcx/TCXUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.tcx; 26 | 27 | import com.pixplicity.easyprefs.library.Prefs; 28 | 29 | import java.text.SimpleDateFormat; 30 | import java.util.Calendar; 31 | import java.util.Date; 32 | import java.util.Locale; 33 | import java.util.TimeZone; 34 | 35 | import me.micrusa.amaztimer.Constants; 36 | 37 | public class TCXUtils { 38 | public static String formatDate(Date date){ 39 | //Workaround for wrong times 40 | Calendar calendar = Calendar.getInstance(); 41 | calendar.setTime(date); 42 | int hours = calendar.get(Calendar.HOUR) + Integer.parseInt(Prefs.getString(Constants.KEY_TCX_TIME, "0")); 43 | calendar.set(Calendar.HOUR, hours); 44 | date = calendar.getTime(); 45 | 46 | SimpleDateFormat dateFormat = new SimpleDateFormat(TCXConstants.DATE_FORMAT, Locale.US); 47 | SimpleDateFormat timeFormat = new SimpleDateFormat(TCXConstants.TIME_FORMAT, Locale.US); 48 | dateFormat.setTimeZone(TimeZone.getDefault()); 49 | timeFormat.setTimeZone(TimeZone.getDefault()); 50 | return dateFormat.format(date) 51 | + TCXConstants.CHAR_DATETIME 52 | + timeFormat.format(date) 53 | + TCXConstants.CHAR_AFTERTIME; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/tcx/data/Lap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.tcx.data; 26 | 27 | import java.util.Date; 28 | import java.util.LinkedList; 29 | 30 | import me.micrusa.amaztimer.utils.tcx.TCXUtils; 31 | import me.micrusa.amaztimer.utils.sensors.heartrate.hrUtils; 32 | 33 | public class Lap { 34 | 35 | private LinkedList tps = new LinkedList<>(); 36 | private String StartTime; 37 | private String intensity; 38 | private long longStartTime; 39 | private long timeInSecs; 40 | private int kcal = 0; 41 | 42 | public Lap(){ 43 | this.longStartTime = System.currentTimeMillis(); 44 | this.StartTime = TCXUtils.formatDate(new Date()); 45 | } 46 | 47 | public void endLap(long currentTimeMillis){ 48 | this.timeInSecs = (currentTimeMillis - this.longStartTime) / 1000; 49 | } 50 | 51 | public void addTrackpoint(Trackpoint tp){ 52 | this.tps.add(tp); 53 | } 54 | 55 | public String getStartTime(){ 56 | return this.StartTime; 57 | } 58 | 59 | public long getTimeInSeconds(){ 60 | return this.timeInSecs; 61 | } 62 | 63 | public int getAvgHr(){ 64 | int totalhr = 0; 65 | for (Trackpoint trackpoint : this.tps){ 66 | totalhr = totalhr + trackpoint.getHr(); 67 | } 68 | if(this.tps.size() != 0) 69 | return totalhr / this.tps.size(); 70 | else 71 | return 0; 72 | 73 | } 74 | 75 | public void calcCalories(){ 76 | this.kcal = hrUtils.calculateKcal(getAvgHr(), (int) getTimeInSeconds()); 77 | } 78 | 79 | public int getKcal(){ 80 | return this.kcal; 81 | } 82 | 83 | public int getMaxHr(){ 84 | int max = 0; 85 | for (Trackpoint trackpoint : this.tps){ 86 | if(trackpoint.getHr() > max) 87 | max = trackpoint.getHr(); 88 | } 89 | return max; 90 | } 91 | 92 | public LinkedList getTrackpoints(){ 93 | return this.tps; 94 | } 95 | 96 | public boolean isLapEmpty(){ 97 | return this.tps.size() == 0; 98 | } 99 | 100 | public void setIntensity(String Intensity){ 101 | this.intensity = Intensity; 102 | } 103 | 104 | public String getIntensity(){ 105 | return this.intensity; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/tcx/data/TCXData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.tcx.data; 26 | 27 | import java.util.LinkedList; 28 | 29 | public class TCXData { 30 | 31 | private LinkedList laps = new LinkedList<>(); 32 | 33 | public boolean isEmpty(){ 34 | return laps.size() == 0; 35 | } 36 | 37 | public void addLap(Lap lap){ 38 | laps.add(lap); 39 | } 40 | 41 | public LinkedList getLaps(){ 42 | return this.laps; 43 | } 44 | 45 | public String getTime(){ 46 | if (!this.isEmpty()) 47 | return this.laps.get(0).getStartTime(); 48 | else 49 | return null; 50 | } 51 | 52 | public String getSportName(){ 53 | return "Other"; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/me/micrusa/amaztimer/utils/tcx/data/Trackpoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2020 Miguel Cruces 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package me.micrusa.amaztimer.utils.tcx.data; 26 | 27 | import java.util.Date; 28 | 29 | import me.micrusa.amaztimer.utils.tcx.TCXUtils; 30 | 31 | public class Trackpoint { 32 | 33 | private String time; 34 | private int hr; 35 | 36 | public Trackpoint(int Hr, Date Date){ 37 | this.hr = Hr; 38 | this.time = TCXUtils.formatDate(Date); 39 | } 40 | 41 | public int getHr(){ 42 | return this.hr; 43 | } 44 | 45 | public String getTime(){ 46 | return this.time; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/add.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/circle_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 15 | 19 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/remove.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/round_keyboard_arrow_right_black_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micrusa/AmazTimer/482ae866160b05a3e9e9c30617e5d13ddcc890aa/app/src/main/res/drawable/round_keyboard_arrow_right_black_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/sadd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micrusa/AmazTimer/482ae866160b05a3e9e9c30617e5d13ddcc890aa/app/src/main/res/drawable/sadd.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/scircle_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 12 | 18 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selected_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 15 | 19 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/sremove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micrusa/AmazTimer/482ae866160b05a3e9e9c30617e5d13ddcc890aa/app/src/main/res/drawable/sremove.png -------------------------------------------------------------------------------- /app/src/main/res/font/applemint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/font/customfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micrusa/AmazTimer/482ae866160b05a3e9e9c30617e5d13ddcc890aa/app/src/main/res/font/customfont.ttf -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_app_info.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 17 | 28 | 29 | 39 | 40 | 49 | 50 | 58 | 59 | 67 | 68 | 76 | 77 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 33 |