mirror of
https://github.com/dzeiocom/OpenHealth.git
synced 2025-06-07 15:29:55 +00:00
Stated Adding Water Intake
This commit is contained in:
parent
e1f11e1ae2
commit
077397749c
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,12 +1,7 @@
|
|||||||
*.iml
|
*.iml
|
||||||
.gradle
|
.gradle
|
||||||
/local.properties
|
/local.properties
|
||||||
/.idea/caches
|
/.idea
|
||||||
/.idea/libraries
|
|
||||||
/.idea/modules.xml
|
|
||||||
/.idea/workspace.xml
|
|
||||||
/.idea/navEditor.xml
|
|
||||||
/.idea/assetWizardSettings.xml
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/build
|
/build
|
||||||
/captures
|
/captures
|
||||||
|
17
.idea/deploymentTargetDropDown.xml
generated
Normal file
17
.idea/deploymentTargetDropDown.xml
generated
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="deploymentTargetDropDown">
|
||||||
|
<runningDeviceTargetSelectedWithDropDown>
|
||||||
|
<Target>
|
||||||
|
<type value="RUNNING_DEVICE_TARGET" />
|
||||||
|
<deviceKey>
|
||||||
|
<Key>
|
||||||
|
<type value="SERIAL_NUMBER" />
|
||||||
|
<value value="14e181ff" />
|
||||||
|
</Key>
|
||||||
|
</deviceKey>
|
||||||
|
</Target>
|
||||||
|
</runningDeviceTargetSelectedWithDropDown>
|
||||||
|
<timeTargetWasSelectedWithDropDown value="2021-12-21T23:29:01.995426900Z" />
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="Reformat" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
5
.idea/misc.xml
generated
5
.idea/misc.xml
generated
@ -7,6 +7,8 @@
|
|||||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_import.xml" value="0.1" />
|
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_import.xml" value="0.1" />
|
||||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/menu/activity_main_drawer.xml" value="0.10989583333333333" />
|
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/menu/activity_main_drawer.xml" value="0.10989583333333333" />
|
||||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/menu/main.xml" value="0.1875" />
|
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/menu/main.xml" value="0.1875" />
|
||||||
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/drawable/half_circle.xml" value="0.421" />
|
||||||
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/drawable/ic_ellipse_2.xml" value="0.4165" />
|
||||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/drawable/ic_logo_app.xml" value="0.163" />
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/drawable/ic_logo_app.xml" value="0.163" />
|
||||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/activity_main.xml" value="0.5" />
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/activity_main.xml" value="0.5" />
|
||||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/app_bar_main.xml" value="0.5192107995846313" />
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/app_bar_main.xml" value="0.5192107995846313" />
|
||||||
@ -15,9 +17,10 @@
|
|||||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/dialog_edit_weight.xml" value="0.33" />
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/dialog_edit_weight.xml" value="0.33" />
|
||||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/dialog_register_weight.xml" value="0.5" />
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/dialog_register_weight.xml" value="0.5" />
|
||||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_gallery.xml" value="0.3109375" />
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_gallery.xml" value="0.3109375" />
|
||||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_home.xml" value="0.25" />
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_home.xml" value="0.6845493562231759" />
|
||||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_import.xml" value="0.55" />
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_import.xml" value="0.55" />
|
||||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_list_weight.xml" value="0.33" />
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_list_weight.xml" value="0.33" />
|
||||||
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_water_home.xml" value="0.55" />
|
||||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/layout_item_weight.xml" value="0.5" />
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/layout_item_weight.xml" value="0.5" />
|
||||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/nav_header_main.xml" value="0.3109375" />
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/layout/nav_header_main.xml" value="0.3109375" />
|
||||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/menu/activity_main_drawer.xml" value="0.39947916666666666" />
|
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/menu/activity_main_drawer.xml" value="0.39947916666666666" />
|
||||||
|
@ -5,10 +5,7 @@ import android.os.Bundle
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.findNavController
|
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import androidx.navigation.ui.AppBarConfiguration
|
import androidx.navigation.ui.AppBarConfiguration
|
||||||
import androidx.navigation.ui.navigateUp
|
import androidx.navigation.ui.navigateUp
|
||||||
@ -16,9 +13,6 @@ import androidx.navigation.ui.setupActionBarWithNavController
|
|||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.navigation.ui.setupWithNavController
|
||||||
import com.dzeio.openhealth.core.BaseActivity
|
import com.dzeio.openhealth.core.BaseActivity
|
||||||
import com.dzeio.openhealth.databinding.ActivityMainBinding
|
import com.dzeio.openhealth.databinding.ActivityMainBinding
|
||||||
import com.dzeio.openhealth.ui.main.home.HomeFragmentDirections
|
|
||||||
import com.google.android.material.navigation.NavigationView
|
|
||||||
import com.google.android.material.snackbar.Snackbar
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
|
@ -4,18 +4,27 @@ import android.content.Context
|
|||||||
import androidx.room.Database
|
import androidx.room.Database
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
|
import com.dzeio.openhealth.data.weight.Water
|
||||||
|
import com.dzeio.openhealth.data.weight.WaterDao
|
||||||
import com.dzeio.openhealth.data.weight.WeightDao
|
import com.dzeio.openhealth.data.weight.WeightDao
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
|
|
||||||
@Database(entities = [Weight::class], version = 1, exportSchema = false)
|
@Database(
|
||||||
|
entities = [
|
||||||
|
Weight::class,
|
||||||
|
Water::class
|
||||||
|
], version = 1, exportSchema = false
|
||||||
|
)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
abstract fun weightDao() : WeightDao
|
abstract fun weightDao(): WeightDao
|
||||||
|
abstract fun waterDao(): WaterDao
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DATABASE_NAME = "open_health"
|
private const val DATABASE_NAME = "open_health"
|
||||||
|
|
||||||
// For Singleton instantiation
|
// For Singleton instantiation
|
||||||
@Volatile private var instance: AppDatabase? = null
|
@Volatile
|
||||||
|
private var instance: AppDatabase? = null
|
||||||
|
|
||||||
fun getInstance(context: Context): AppDatabase {
|
fun getInstance(context: Context): AppDatabase {
|
||||||
return instance ?: synchronized(this) {
|
return instance ?: synchronized(this) {
|
||||||
|
29
app/src/main/java/com/dzeio/openhealth/data/water/Water.kt
Normal file
29
app/src/main/java/com/dzeio/openhealth/data/water/Water.kt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.dzeio.openhealth.data.weight
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import java.sql.Date
|
||||||
|
import java.text.DateFormat.getDateInstance
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
data class Water(
|
||||||
|
@PrimaryKey(autoGenerate = true) var id: Long = 0,
|
||||||
|
var value: Int = 0,
|
||||||
|
@ColumnInfo(index = true)
|
||||||
|
var timestamp: Long = System.currentTimeMillis(),
|
||||||
|
var source: String = "OpenHealth"
|
||||||
|
) {
|
||||||
|
init {
|
||||||
|
val cal = Calendar.getInstance()
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 0)
|
||||||
|
cal.set(Calendar.MINUTE, 0)
|
||||||
|
cal.set(Calendar.SECOND, 0)
|
||||||
|
cal.set(Calendar.MILLISECOND, 0)
|
||||||
|
|
||||||
|
timestamp = cal.timeInMillis
|
||||||
|
}
|
||||||
|
|
||||||
|
fun formatTimestamp(): String = getDateInstance().format(Date(timestamp))
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.dzeio.openhealth.data.weight
|
||||||
|
|
||||||
|
import androidx.room.*
|
||||||
|
import com.dzeio.openhealth.core.BaseDao
|
||||||
|
import dagger.Provides
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface WaterDao : BaseDao<Water> {
|
||||||
|
|
||||||
|
@Query("SELECT * FROM Water")
|
||||||
|
fun getAll(): Flow<List<Water>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM Water where id = :weightId")
|
||||||
|
fun getOne(weightId: Long): Flow<Water?>
|
||||||
|
|
||||||
|
|
||||||
|
@Query("Select count(*) from Water")
|
||||||
|
fun getCount(): Flow<Int>
|
||||||
|
|
||||||
|
@Query("Select * FROM Water WHERE id=(SELECT max(id) FROM Water)")
|
||||||
|
fun last(): Flow<Water?>
|
||||||
|
|
||||||
|
@Query("DELETE FROM Water where source = :source")
|
||||||
|
suspend fun deleteFromSource(source: String)
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.dzeio.openhealth.data.weight
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import kotlinx.coroutines.flow.*
|
||||||
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class WaterRepository @Inject constructor(
|
||||||
|
private val waterDao: WaterDao
|
||||||
|
) {
|
||||||
|
fun getWaters() = waterDao.getAll()
|
||||||
|
|
||||||
|
fun lastWater() = waterDao.last()
|
||||||
|
|
||||||
|
fun getWater(id: Long) = waterDao.getOne(id)
|
||||||
|
|
||||||
|
suspend fun addWater(value: Water) = waterDao.insert(value)
|
||||||
|
suspend fun deleteWater(value: Water) = waterDao.delete(value)
|
||||||
|
suspend fun deleteFromSource(value: String) = waterDao.deleteFromSource(value)
|
||||||
|
|
||||||
|
fun todayWater() = lastWater().filter {
|
||||||
|
val cal = Calendar.getInstance()
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 0)
|
||||||
|
cal.set(Calendar.MINUTE, 0)
|
||||||
|
cal.set(Calendar.SECOND, 0)
|
||||||
|
cal.set(Calendar.MILLISECOND, 0)
|
||||||
|
Log.d("WaterRepository", "${it?.timestamp} ${cal.timeInMillis}")
|
||||||
|
return@filter it?.timestamp == cal.timeInMillis
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ package com.dzeio.openhealth.di
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.dzeio.openhealth.data.AppDatabase
|
import com.dzeio.openhealth.data.AppDatabase
|
||||||
|
import com.dzeio.openhealth.data.weight.WaterDao
|
||||||
import com.dzeio.openhealth.data.weight.WeightDao
|
import com.dzeio.openhealth.data.weight.WeightDao
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
@ -24,4 +25,9 @@ class DatabaseModule {
|
|||||||
fun provideWeightDao(appDatabase: AppDatabase): WeightDao {
|
fun provideWeightDao(appDatabase: AppDatabase): WeightDao {
|
||||||
return appDatabase.weightDao()
|
return appDatabase.weightDao()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun provideWaterDao(appDatabase: AppDatabase): WaterDao {
|
||||||
|
return appDatabase.waterDao()
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.dzeio.openhealth.connectors
|
package com.dzeio.openhealth.extensions
|
||||||
|
|
||||||
enum class DataType {
|
enum class DataType {
|
||||||
WEIGHT
|
WEIGHT
|
@ -1,10 +1,10 @@
|
|||||||
package com.dzeio.openhealth.connectors
|
package com.dzeio.openhealth.extensions
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
|
|
||||||
abstract class Connector {
|
abstract class Extension {
|
||||||
|
|
||||||
enum class Data {
|
enum class Data {
|
||||||
WEIGHT,
|
WEIGHT,
|
||||||
@ -13,7 +13,7 @@ abstract class Connector {
|
|||||||
|
|
||||||
abstract val sourceID: String
|
abstract val sourceID: String
|
||||||
|
|
||||||
open fun init(activity: Activity) {}
|
open fun init(activity: Activity): Array<Data> = arrayOf()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as Activity/Fragment onRequestPermissionResult
|
* Same as Activity/Fragment onRequestPermissionResult
|
||||||
@ -27,5 +27,7 @@ abstract class Connector {
|
|||||||
*/
|
*/
|
||||||
open fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {}
|
open fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {}
|
||||||
|
|
||||||
|
open fun <T> import(data: Data, cb: (item: T, end: Boolean) -> Unit) {}
|
||||||
|
|
||||||
open fun importWeight(callback: (weight: Weight, end: Boolean) -> Unit) {}
|
open fun importWeight(callback: (weight: Weight, end: Boolean) -> Unit) {}
|
||||||
}
|
}
|
@ -1,173 +1,186 @@
|
|||||||
package com.dzeio.openhealth.connectors
|
package com.dzeio.openhealth.extensions
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
||||||
import com.google.android.gms.fitness.Fitness
|
import com.google.android.gms.fitness.Fitness
|
||||||
import com.google.android.gms.fitness.FitnessOptions
|
import com.google.android.gms.fitness.FitnessOptions
|
||||||
import com.google.android.gms.fitness.data.DataPoint
|
import com.google.android.gms.fitness.data.DataPoint
|
||||||
import com.google.android.gms.fitness.data.DataSet
|
import com.google.android.gms.fitness.data.DataType
|
||||||
import com.google.android.gms.fitness.data.DataType
|
import com.google.android.gms.fitness.request.DataReadRequest
|
||||||
import com.google.android.gms.fitness.request.DataReadRequest
|
import java.text.DateFormat
|
||||||
import java.text.DateFormat
|
import java.util.*
|
||||||
import java.util.*
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
class GoogleFit(
|
||||||
class GoogleFit(
|
private val activity: Activity,
|
||||||
private val activity: Activity,
|
) : Extension() {
|
||||||
) : Connector() {
|
companion object {
|
||||||
companion object {
|
const val TAG = "GoogleFitConnector"
|
||||||
const val TAG = "GoogleFitConnector"
|
}
|
||||||
}
|
|
||||||
|
override val sourceID: String = "GoogleFit"
|
||||||
override val sourceID: String = "GoogleFit"
|
|
||||||
|
private val fitnessOptions = FitnessOptions.builder()
|
||||||
private val fitnessOptions = FitnessOptions.builder()
|
.addDataType(DataType.TYPE_WEIGHT)
|
||||||
.addDataType(DataType.TYPE_WEIGHT)
|
.addDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE)
|
||||||
.addDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE)
|
.build()
|
||||||
.build()
|
|
||||||
|
private fun checkPermissionsAndRun(data: Data) {
|
||||||
private fun checkPermissionsAndRun(data: Data) {
|
if (permissionApproved()) {
|
||||||
if (permissionApproved()) {
|
signIn(data)
|
||||||
signIn(data)
|
} else {
|
||||||
} else {
|
Log.d(TAG, "Asking for permission")
|
||||||
Log.d(TAG, "Asking for permission")
|
// Ask for permission
|
||||||
// Ask for permission
|
ActivityCompat.requestPermissions(
|
||||||
ActivityCompat.requestPermissions(
|
activity,
|
||||||
activity,
|
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
|
||||||
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
|
data.ordinal
|
||||||
data.ordinal
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private fun permissionApproved(): Boolean {
|
||||||
private fun permissionApproved(): Boolean {
|
val approved = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
val approved = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(
|
||||||
PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(
|
activity,
|
||||||
activity,
|
Manifest.permission.ACCESS_FINE_LOCATION)
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION)
|
} else {
|
||||||
} else {
|
true
|
||||||
true
|
}
|
||||||
}
|
return approved
|
||||||
return approved
|
}
|
||||||
}
|
|
||||||
|
private fun signIn(data: Data) {
|
||||||
private fun signIn(data: Data) {
|
if (oAuthPermissionsApproved()) {
|
||||||
if (oAuthPermissionsApproved()) {
|
startImport(data)
|
||||||
startImport(data)
|
} else {
|
||||||
} else {
|
Log.d("GoogleFitImporter", "Signing In")
|
||||||
Log.d("GoogleFitImporter", "Signing In")
|
GoogleSignIn.requestPermissions(
|
||||||
GoogleSignIn.requestPermissions(
|
activity,
|
||||||
activity,
|
data.ordinal,
|
||||||
data.ordinal,
|
getGoogleAccount(), fitnessOptions)
|
||||||
getGoogleAccount(), fitnessOptions)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private fun oAuthPermissionsApproved() = GoogleSignIn.hasPermissions(getGoogleAccount(), fitnessOptions)
|
||||||
private fun oAuthPermissionsApproved() = GoogleSignIn.hasPermissions(getGoogleAccount(), fitnessOptions)
|
|
||||||
|
private fun getGoogleAccount() = GoogleSignIn.getAccountForExtension(activity, fitnessOptions)
|
||||||
private fun getGoogleAccount() = GoogleSignIn.getAccountForExtension(activity, fitnessOptions)
|
|
||||||
|
private val timeRange by lazy {
|
||||||
private val timeRange by lazy {
|
val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
|
||||||
val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
|
calendar.time = Date()
|
||||||
calendar.time = Date()
|
val endTime = calendar.timeInMillis
|
||||||
val endTime = calendar.timeInMillis
|
|
||||||
|
// Set year to 2013 to be sure to get data from when Google Fit Started to today
|
||||||
// Set year to 2013 to be sure to get data from when Google Fit Started to today
|
calendar.set(Calendar.YEAR, 2013)
|
||||||
calendar.set(Calendar.YEAR, 2013)
|
val startTime = calendar.timeInMillis
|
||||||
val startTime = calendar.timeInMillis
|
arrayOf(startTime, endTime)
|
||||||
arrayOf(startTime, endTime)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
private fun startImport(data: Data) {
|
||||||
private fun startImport(data: Data) {
|
Log.d("GoogleFitImporter", "Importing for ${data.name}")
|
||||||
Log.d("GoogleFitImporter", "Importing for ${data.name}")
|
|
||||||
|
val dateFormat = DateFormat.getDateInstance()
|
||||||
val dateFormat = DateFormat.getDateInstance()
|
Log.i(TAG, "Range Start: ${dateFormat.format(timeRange[0])}")
|
||||||
Log.i(TAG, "Range Start: ${dateFormat.format(timeRange[0])}")
|
Log.i(TAG, "Range End: ${dateFormat.format(timeRange[1])}")
|
||||||
Log.i(TAG, "Range End: ${dateFormat.format(timeRange[1])}")
|
|
||||||
|
var type = DataType.TYPE_WEIGHT
|
||||||
var type = DataType.TYPE_WEIGHT
|
var timeUnit = TimeUnit.MILLISECONDS
|
||||||
var timeUnit = TimeUnit.MILLISECONDS
|
|
||||||
|
when (data) {
|
||||||
when (data) {
|
Data.STEPS -> {
|
||||||
Data.STEPS -> {
|
type = DataType.TYPE_STEP_COUNT_CUMULATIVE
|
||||||
type = DataType.TYPE_STEP_COUNT_CUMULATIVE
|
}
|
||||||
}
|
else -> {}
|
||||||
else -> {}
|
}
|
||||||
}
|
|
||||||
|
runRequest(DataReadRequest.Builder()
|
||||||
runRequest(DataReadRequest.Builder()
|
.read(type)
|
||||||
.read(type)
|
.setTimeRange(timeRange[0], timeRange[1], timeUnit)
|
||||||
.setTimeRange(timeRange[0], timeRange[1], timeUnit)
|
.build(), data)
|
||||||
.build(), data)
|
|
||||||
|
}
|
||||||
}
|
|
||||||
|
private fun runRequest(request: DataReadRequest, data: Data) {
|
||||||
private fun runRequest(request: DataReadRequest, data: Data) {
|
Fitness.getHistoryClient(activity, GoogleSignIn.getAccountForExtension(activity, fitnessOptions))
|
||||||
Fitness.getHistoryClient(activity, GoogleSignIn.getAccountForExtension(activity, fitnessOptions))
|
.readData(request)
|
||||||
.readData(request)
|
.addOnSuccessListener { response ->
|
||||||
.addOnSuccessListener { response ->
|
Log.d(TAG, "Received response! ${response.dataSets.size} ${response.buckets.size} ${response.status}")
|
||||||
Log.d(TAG, "Received response! ${response.dataSets.size} ${response.buckets.size} ${response.status}")
|
for (dataSet in response.dataSets) {
|
||||||
for (dataSet in response.dataSets) {
|
Log.i(TAG, "Data returned for Data type: ${dataSet.dataType.name} ${dataSet.dataPoints.size}")
|
||||||
Log.i(TAG, "Data returned for Data type: ${dataSet.dataType.name} ${dataSet.dataPoints.size}")
|
dataSet.dataPoints.forEachIndexed { index, dp ->
|
||||||
dataSet.dataPoints.forEachIndexed { index, dp ->
|
val isLast = (index + 1) == dataSet.dataPoints.size
|
||||||
val isLast = (index + 1) == dataSet.dataPoints.size
|
|
||||||
|
// Global
|
||||||
// Global
|
Log.i(TAG,"Importing Data point:")
|
||||||
Log.i(TAG,"Importing Data point:")
|
Log.i(TAG,"\tType: ${dp.dataType.name}")
|
||||||
Log.i(TAG,"\tType: ${dp.dataType.name}")
|
Log.i(TAG,"\tStart: ${dp.getStartTimeString()}")
|
||||||
Log.i(TAG,"\tStart: ${dp.getStartTimeString()}")
|
Log.i(TAG,"\tEnd: ${dp.getEndTimeString()}")
|
||||||
Log.i(TAG,"\tEnd: ${dp.getEndTimeString()}")
|
|
||||||
|
// Field Specifics
|
||||||
// Field Specifics
|
for (field in dp.dataType.fields) {
|
||||||
for (field in dp.dataType.fields) {
|
Log.i(TAG,"\tField: ${field.name} Value: ${dp.getValue(field)}")
|
||||||
Log.i(TAG,"\tField: ${field.name} Value: ${dp.getValue(field)}")
|
when (data) {
|
||||||
when (data) {
|
Data.WEIGHT -> {
|
||||||
Data.WEIGHT -> {
|
val weight = Weight()
|
||||||
val weight = Weight()
|
weight.timestamp = dp.getStartTime(TimeUnit.MILLISECONDS)
|
||||||
weight.timestamp = dp.getStartTime(TimeUnit.MILLISECONDS)
|
weight.weight = dp.getValue(field).asFloat()
|
||||||
weight.weight = dp.getValue(field).asFloat()
|
weightCallback(weight, isLast)
|
||||||
weightCallback(weight, isLast)
|
}
|
||||||
}
|
else -> {}
|
||||||
else -> {}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
.addOnFailureListener { e ->
|
||||||
.addOnFailureListener { e ->
|
Log.e(TAG,"There was an error reading data from Google Fit", e)
|
||||||
Log.e(TAG,"There was an error reading data from Google Fit", e)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private fun DataPoint.getStartTimeString(): String = Date(this.getStartTime(TimeUnit.SECONDS) * 1000L).toLocaleString()
|
||||||
private fun DataPoint.getStartTimeString(): String = Date(this.getStartTime(TimeUnit.SECONDS) * 1000L).toLocaleString()
|
|
||||||
|
private fun DataPoint.getEndTimeString(): String = Date(this.getEndTime(TimeUnit.SECONDS) * 1000L).toLocaleString()
|
||||||
private fun DataPoint.getEndTimeString(): String = Date(this.getEndTime(TimeUnit.SECONDS) * 1000L).toLocaleString()
|
|
||||||
|
override fun onRequestPermissionResult(
|
||||||
override fun onRequestPermissionResult(
|
requestCode: Int,
|
||||||
requestCode: Int,
|
permission: Array<String>,
|
||||||
permission: Array<String>,
|
grantResult: IntArray
|
||||||
grantResult: IntArray
|
) {
|
||||||
) {
|
signIn(Data.values()[requestCode])
|
||||||
signIn(Data.values()[requestCode])
|
}
|
||||||
}
|
|
||||||
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
signIn(Data.values()[requestCode])
|
||||||
signIn(Data.values()[requestCode])
|
}
|
||||||
}
|
|
||||||
|
private lateinit var weightCallback: (weight: Weight, end: Boolean) -> Unit
|
||||||
private lateinit var weightCallback: (weight: Weight, end: Boolean) -> Unit
|
|
||||||
|
override fun importWeight(callback: (weight: Weight, end: Boolean) -> Unit) {
|
||||||
override fun importWeight(callback: (weight: Weight, end: Boolean) -> Unit) {
|
this.weightCallback = callback
|
||||||
this.weightCallback = callback
|
checkPermissionsAndRun(Data.WEIGHT)
|
||||||
checkPermissionsAndRun(Data.WEIGHT)
|
}
|
||||||
}
|
|
||||||
|
private lateinit var callback : (item: Any, end: Boolean) -> Unit
|
||||||
|
|
||||||
|
override fun <T> import(data: Data, cb: (item: T, end: Boolean) -> Unit) {
|
||||||
|
callback = cb as (item: Any, end: Boolean) -> Unit
|
||||||
|
when (data) {
|
||||||
|
Data.WEIGHT -> {
|
||||||
|
checkPermissionsAndRun(data)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
Log.d(TAG, "PRRRRRRRRRRRRR")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.dzeio.openhealth.connectors
|
package com.dzeio.openhealth.extensions
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
@ -7,7 +7,6 @@ import android.os.Build
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import com.dzeio.openhealth.data.AppDatabase
|
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
||||||
import com.google.android.gms.fitness.Fitness
|
import com.google.android.gms.fitness.Fitness
|
||||||
@ -22,7 +21,6 @@ import com.google.android.gms.fitness.request.OnDataPointListener
|
|||||||
import com.google.android.gms.fitness.request.SensorRequest
|
import com.google.android.gms.fitness.request.SensorRequest
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.time.*
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
@ -1,108 +1,108 @@
|
|||||||
package com.dzeio.openhealth.connectors.samsunghealth
|
package com.dzeio.openhealth.extensions.samsunghealth
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.dzeio.openhealth.connectors.Connector
|
import com.dzeio.openhealth.extensions.Extension
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
import com.samsung.android.sdk.healthdata.*
|
import com.samsung.android.sdk.healthdata.*
|
||||||
import com.samsung.android.sdk.healthdata.HealthConstants.StepCount
|
import com.samsung.android.sdk.healthdata.HealthConstants.StepCount
|
||||||
import com.samsung.android.sdk.healthdata.HealthDataStore.ConnectionListener
|
import com.samsung.android.sdk.healthdata.HealthDataStore.ConnectionListener
|
||||||
import com.samsung.android.sdk.healthdata.HealthPermissionManager.*
|
import com.samsung.android.sdk.healthdata.HealthPermissionManager.*
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does not FUCKING work
|
* Does not FUCKING work
|
||||||
*/
|
*/
|
||||||
class SamsungHealth(
|
class SamsungHealth(
|
||||||
private val context: Activity
|
private val context: Activity
|
||||||
) : Connector() {
|
) : Extension() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "SamsungHealthConnector"
|
const val TAG = "SamsungHealthConnector"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val listener = object : ConnectionListener {
|
private val listener = object : ConnectionListener {
|
||||||
override fun onConnected() {
|
override fun onConnected() {
|
||||||
Log.d(TAG, "Connected!")
|
Log.d(TAG, "Connected!")
|
||||||
if (isPermissionAcquired()) {
|
if (isPermissionAcquired()) {
|
||||||
reporter.start()
|
reporter.start()
|
||||||
} else {
|
} else {
|
||||||
requestPermission()
|
requestPermission()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
override fun onConnectionFailed(p0: HealthConnectionErrorResult?) {
|
override fun onConnectionFailed(p0: HealthConnectionErrorResult?) {
|
||||||
Log.d(TAG, "Health data service is not available.")
|
Log.d(TAG, "Health data service is not available.")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDisconnected() {
|
override fun onDisconnected() {
|
||||||
Log.d(TAG, "Health data service is disconnected.")
|
Log.d(TAG, "Health data service is disconnected.")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val store : HealthDataStore = HealthDataStore(context, listener)
|
private val store : HealthDataStore = HealthDataStore(context, listener)
|
||||||
|
|
||||||
private fun isPermissionAcquired(): Boolean {
|
private fun isPermissionAcquired(): Boolean {
|
||||||
val permKey = PermissionKey(StepCount.HEALTH_DATA_TYPE, PermissionType.READ)
|
val permKey = PermissionKey(StepCount.HEALTH_DATA_TYPE, PermissionType.READ)
|
||||||
val pmsManager = HealthPermissionManager(store)
|
val pmsManager = HealthPermissionManager(store)
|
||||||
try {
|
try {
|
||||||
// Check whether the permissions that this application needs are acquired
|
// Check whether the permissions that this application needs are acquired
|
||||||
val resultMap = pmsManager.isPermissionAcquired(setOf(permKey))
|
val resultMap = pmsManager.isPermissionAcquired(setOf(permKey))
|
||||||
return !resultMap.containsValue(java.lang.Boolean.FALSE)
|
return !resultMap.containsValue(java.lang.Boolean.FALSE)
|
||||||
} catch (e: java.lang.Exception) {
|
} catch (e: java.lang.Exception) {
|
||||||
Log.e(TAG, "Permission request fails.", e)
|
Log.e(TAG, "Permission request fails.", e)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun requestPermission() {
|
private fun requestPermission() {
|
||||||
val permKey = PermissionKey(StepCount.HEALTH_DATA_TYPE, PermissionType.READ)
|
val permKey = PermissionKey(StepCount.HEALTH_DATA_TYPE, PermissionType.READ)
|
||||||
val pmsManager = HealthPermissionManager(store)
|
val pmsManager = HealthPermissionManager(store)
|
||||||
try {
|
try {
|
||||||
// Show user permission UI for allowing user to change options
|
// Show user permission UI for allowing user to change options
|
||||||
pmsManager.requestPermissions(setOf(permKey), context)
|
pmsManager.requestPermissions(setOf(permKey), context)
|
||||||
.setResultListener { result: PermissionResult ->
|
.setResultListener { result: PermissionResult ->
|
||||||
Log.d(TAG, "Permission callback is received.")
|
Log.d(TAG, "Permission callback is received.")
|
||||||
val resultMap =
|
val resultMap =
|
||||||
result.resultMap
|
result.resultMap
|
||||||
if (resultMap.containsValue(java.lang.Boolean.FALSE)) {
|
if (resultMap.containsValue(java.lang.Boolean.FALSE)) {
|
||||||
Log.d(TAG, "No Data???")
|
Log.d(TAG, "No Data???")
|
||||||
} else {
|
} else {
|
||||||
// Get the current step count and display it
|
// Get the current step count and display it
|
||||||
reporter.start()
|
reporter.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Permission setting fails.", e)
|
Log.e(TAG, "Permission setting fails.", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val stepCountObserver = object : StepCountReporter.StepCountObserver {
|
private val stepCountObserver = object : StepCountReporter.StepCountObserver {
|
||||||
override fun onChanged(count: Int) {
|
override fun onChanged(count: Int) {
|
||||||
Log.d(TAG, "Step reported : $count")
|
Log.d(TAG, "Step reported : $count")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val reporter = StepCountReporter(store, stepCountObserver, Handler(Looper.getMainLooper()))
|
private val reporter = StepCountReporter(store, stepCountObserver, Handler(Looper.getMainLooper()))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connector
|
* Connector
|
||||||
*/
|
*/
|
||||||
|
|
||||||
override val sourceID: String = "SamsungHealth"
|
override val sourceID: String = "SamsungHealth"
|
||||||
|
|
||||||
override fun onRequestPermissionResult(
|
override fun onRequestPermissionResult(
|
||||||
requestCode: Int,
|
requestCode: Int,
|
||||||
permission: Array<String>,
|
permission: Array<String>,
|
||||||
grantResult: IntArray
|
grantResult: IntArray
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {}
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {}
|
||||||
|
|
||||||
override fun importWeight(callback: (weight: Weight, end: Boolean) -> Unit) {
|
override fun importWeight(callback: (weight: Weight, end: Boolean) -> Unit) {
|
||||||
store.connectService()
|
store.connectService()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.dzeio.openhealth.connectors.samsunghealth
|
package com.dzeio.openhealth.extensions.samsunghealth
|
||||||
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.util.Log
|
import android.util.Log
|
@ -1,32 +1,42 @@
|
|||||||
package com.dzeio.openhealth.ui.main.home
|
package com.dzeio.openhealth.ui.home
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity.RESULT_OK
|
import android.app.Activity.RESULT_OK
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.drawable.BitmapDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.commit
|
import android.widget.LinearLayout
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.dzeio.openhealth.R
|
import com.dzeio.openhealth.R
|
||||||
import com.dzeio.openhealth.core.BaseFragment
|
import com.dzeio.openhealth.core.BaseFragment
|
||||||
|
import com.dzeio.openhealth.data.weight.Water
|
||||||
import com.dzeio.openhealth.databinding.FragmentHomeBinding
|
import com.dzeio.openhealth.databinding.FragmentHomeBinding
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
import com.dzeio.openhealth.ui.dialogs.AddWeightDialog
|
import com.dzeio.openhealth.ui.weight.AddWeightDialog
|
||||||
import com.dzeio.openhealth.ui.main.list_weight.ListWeightFragment
|
import com.dzeio.openhealth.utils.BitmapUtils
|
||||||
|
import com.dzeio.openhealth.utils.DrawUtils
|
||||||
import com.github.mikephil.charting.components.AxisBase
|
import com.github.mikephil.charting.components.AxisBase
|
||||||
import com.github.mikephil.charting.components.Description
|
import com.github.mikephil.charting.components.Description
|
||||||
import com.github.mikephil.charting.components.XAxis
|
import com.github.mikephil.charting.components.XAxis
|
||||||
import com.github.mikephil.charting.components.YAxis
|
|
||||||
import com.github.mikephil.charting.data.Entry
|
import com.github.mikephil.charting.data.Entry
|
||||||
import com.github.mikephil.charting.data.LineData
|
import com.github.mikephil.charting.data.LineData
|
||||||
import com.github.mikephil.charting.data.LineDataSet
|
import com.github.mikephil.charting.data.LineDataSet
|
||||||
import com.github.mikephil.charting.formatter.ValueFormatter
|
import com.github.mikephil.charting.formatter.ValueFormatter
|
||||||
|
import com.google.android.material.color.MaterialColors
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.*
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.io.IOException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
@ -50,6 +60,54 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
|
|||||||
AddWeightDialog().show(requireActivity().supportFragmentManager, null)
|
AddWeightDialog().show(requireActivity().supportFragmentManager, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.fragmentHomeWaterAdd.setOnClickListener {
|
||||||
|
lifecycleScope.launchWhenStarted {
|
||||||
|
|
||||||
|
Log.d(TAG, "Collecting latest $this")
|
||||||
|
if (viewModel.fetchTodayWater().count() == 0) {
|
||||||
|
Log.d(TAG, "No value, Adding...")
|
||||||
|
val w = Water()
|
||||||
|
w.value = 200
|
||||||
|
viewModel.updateWater(w)
|
||||||
|
return@launchWhenStarted
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
viewModel.fetchTodayWater().count()
|
||||||
|
val item = viewModel.fetchTodayWater().lastOrNull()
|
||||||
|
Log.d(TAG, "Collected latest $item")
|
||||||
|
if (item == null) {
|
||||||
|
|
||||||
|
val w = Water()
|
||||||
|
w.value = 200
|
||||||
|
viewModel.updateWater(w)
|
||||||
|
} else {
|
||||||
|
item.value += 200
|
||||||
|
viewModel.updateWater(item)
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
Log.e(TAG, "EXCEPTION", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.fragmentHomeWaterRemove.setOnClickListener {
|
||||||
|
lifecycleScope.launch {
|
||||||
|
|
||||||
|
val item = viewModel.fetchTodayWater().first()
|
||||||
|
Log.d(TAG, "Collected latest $it")
|
||||||
|
if (item != null) {
|
||||||
|
item.value -= 200
|
||||||
|
if (item.value == 0) {
|
||||||
|
viewModel.deleteWater(item)
|
||||||
|
} else {
|
||||||
|
viewModel.updateWater(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding.listWeight.setOnClickListener {
|
binding.listWeight.setOnClickListener {
|
||||||
Log.d("T", "Trying to move")
|
Log.d("T", "Trying to move")
|
||||||
|
|
||||||
@ -106,7 +164,10 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
|
|||||||
binding.weightGraph.axisRight.setDrawGridLines(false)
|
binding.weightGraph.axisRight.setDrawGridLines(false)
|
||||||
binding.weightGraph.xAxis.valueFormatter = object : ValueFormatter() {
|
binding.weightGraph.xAxis.valueFormatter = object : ValueFormatter() {
|
||||||
override fun getAxisLabel(value: Float, axis: AxisBase?): String {
|
override fun getAxisLabel(value: Float, axis: AxisBase?): String {
|
||||||
return SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date(value.toLong()))
|
return SimpleDateFormat(
|
||||||
|
"yyyy-MM-dd",
|
||||||
|
Locale.getDefault()
|
||||||
|
).format(Date(value.toLong()))
|
||||||
//return super.getAxisLabel(value, axis)
|
//return super.getAxisLabel(value, axis)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,6 +182,7 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
|
|||||||
// )
|
// )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("PrivateResource")
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
|
|
||||||
@ -132,68 +194,48 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
|
|||||||
updateGraph(it)
|
updateGraph(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
lifecycleScope.launchWhenStarted {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
viewModel.fetchTodayWater().collect {
|
||||||
Log.d(TAG, "Activity Result!")
|
Log.d(TAG, "Pouet? $it")
|
||||||
when (resultCode) {
|
if (it != null) {
|
||||||
RESULT_OK -> {
|
updateWater(it.value)
|
||||||
// fit.performActionForRequestCode(ActionRequestCode.FIND_DATA_SOURCES)
|
} else {
|
||||||
}
|
updateWater(0)
|
||||||
else -> {
|
}
|
||||||
Log.e(TAG, "Error: $requestCode, $resultCode")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateWater(0)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
|
private fun updateWater(water: Int) {
|
||||||
grantResults: IntArray) {
|
binding.fragmentHomeWaterCurrent.text = water.toString()
|
||||||
when {
|
|
||||||
grantResults.isEmpty() -> {
|
|
||||||
// If user interaction was interrupted, the permission request
|
|
||||||
// is cancelled and you receive empty arrays.
|
|
||||||
Log.i(TAG, "User interaction was cancelled.")
|
|
||||||
}
|
|
||||||
|
|
||||||
grantResults[0] == PackageManager.PERMISSION_GRANTED -> {
|
val graph = BitmapUtils.convertToMutable(
|
||||||
Log.d(TAG, "Granted")
|
requireContext(),
|
||||||
// Permission was granted.
|
BitmapFactory.decodeResource(resources, R.drawable.ellipse)
|
||||||
// val fitActionRequestCode = ActionRequestCode.values()[requestCode]
|
)
|
||||||
// fitActionRequestCode.let {
|
|
||||||
// // fit.signIn(ActionRequestCode.FIND_DATA_SOURCES)
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
// Permission denied.
|
|
||||||
|
|
||||||
// In this Activity we've chosen to notify the user that they
|
graph?.let { btmp ->
|
||||||
// have rejected a core permission for the app since it makes the Activity useless.
|
val canvas = Canvas(btmp)
|
||||||
// We're communicating this message in a Snackbar since this is a sample app, but
|
DrawUtils.drawArc(
|
||||||
// core permissions would typically be best requested during a welcome-screen flow.
|
canvas,
|
||||||
|
100 * water / 1200,
|
||||||
|
MaterialColors.getColor(
|
||||||
|
requireView(),
|
||||||
|
com.google.android.material.R.attr.colorPrimary
|
||||||
|
)
|
||||||
|
)
|
||||||
|
canvas.save()
|
||||||
|
|
||||||
// Additionally, it is important to remember that a permission might have been
|
// val params = binding.background.layoutParams
|
||||||
// rejected without asking the user for permission (device policy or "Never ask
|
// params.height = binding.background.measuredWidth
|
||||||
// again" prompts). Therefore, a user interface affordance is typically implemented
|
// binding.background.layoutParams = params
|
||||||
// when permissions are denied. Otherwise, your app could appear unresponsive to
|
|
||||||
// touches or interactions which have required permissions.
|
binding.background.setImageBitmap(graph)
|
||||||
Log.e(TAG, "Error")
|
|
||||||
// Snackbar.make(
|
|
||||||
// findViewById(R.id.main_activity_view),
|
|
||||||
// R.string.permission_denied_explanation,
|
|
||||||
// Snackbar.LENGTH_INDEFINITE)
|
|
||||||
// .setAction(R.string.settings) {
|
|
||||||
// // Build intent that displays the App settings screen.
|
|
||||||
// val intent = Intent()
|
|
||||||
// intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
|
|
||||||
// val uri = Uri.fromParts("package",
|
|
||||||
// BuildConfig.APPLICATION_ID, null)
|
|
||||||
// intent.data = uri
|
|
||||||
// intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
// startActivity(intent)
|
|
||||||
// }
|
|
||||||
// .show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,14 +1,20 @@
|
|||||||
package com.dzeio.openhealth.ui.main.home
|
package com.dzeio.openhealth.ui.home
|
||||||
|
|
||||||
import com.dzeio.openhealth.core.BaseViewModel
|
import com.dzeio.openhealth.core.BaseViewModel
|
||||||
|
import com.dzeio.openhealth.data.weight.Water
|
||||||
|
import com.dzeio.openhealth.data.weight.WaterRepository
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
import com.dzeio.openhealth.data.weight.WeightRepository
|
import com.dzeio.openhealth.data.weight.WeightRepository
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class HomeViewModel @Inject internal constructor(
|
class HomeViewModel @Inject internal constructor(
|
||||||
private val weightRepository: WeightRepository
|
private val weightRepository: WeightRepository,
|
||||||
|
private val waterRepository: WaterRepository
|
||||||
) : BaseViewModel() {
|
) : BaseViewModel() {
|
||||||
|
|
||||||
fun fetchWeights() = weightRepository.getWeights()
|
fun fetchWeights() = weightRepository.getWeights()
|
||||||
@ -20,4 +26,11 @@ class HomeViewModel @Inject internal constructor(
|
|||||||
suspend fun deleteWeight(weight: Weight) = weightRepository.deleteWeight(weight)
|
suspend fun deleteWeight(weight: Weight) = weightRepository.deleteWeight(weight)
|
||||||
|
|
||||||
suspend fun addWeight(weight: Weight) = weightRepository.addWeight(weight)
|
suspend fun addWeight(weight: Weight) = weightRepository.addWeight(weight)
|
||||||
|
|
||||||
|
fun fetchTodayWater() = waterRepository.todayWater()
|
||||||
|
|
||||||
|
suspend fun updateWater(water: Water) = waterRepository.addWater(water)
|
||||||
|
suspend fun deleteWater(water: Water) = waterRepository.deleteWater(water)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.dzeio.openhealth.ui.main.imports
|
package com.dzeio.openhealth.ui.imports
|
||||||
|
|
||||||
import android.app.ProgressDialog
|
import android.app.ProgressDialog
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@ -11,10 +11,10 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.dzeio.openhealth.connectors.Connector
|
import com.dzeio.openhealth.extensions.Extension
|
||||||
import com.dzeio.openhealth.connectors.GoogleFit
|
import com.dzeio.openhealth.extensions.GoogleFit
|
||||||
//import com.dzeio.openhealth.connectors.GoogleFit
|
//import com.dzeio.openhealth.connectors.GoogleFit
|
||||||
import com.dzeio.openhealth.connectors.samsunghealth.SamsungHealth
|
import com.dzeio.openhealth.extensions.samsunghealth.SamsungHealth
|
||||||
import com.dzeio.openhealth.core.BaseFragment
|
import com.dzeio.openhealth.core.BaseFragment
|
||||||
import com.dzeio.openhealth.databinding.FragmentImportBinding
|
import com.dzeio.openhealth.databinding.FragmentImportBinding
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
@ -30,7 +30,7 @@ class ImportFragment : BaseFragment<ImportViewModel, FragmentImportBinding>(Impo
|
|||||||
|
|
||||||
private lateinit var progressDialog: ProgressDialog
|
private lateinit var progressDialog: ProgressDialog
|
||||||
|
|
||||||
private lateinit var fit: Connector
|
private lateinit var fit: Extension
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
@ -43,9 +43,7 @@ class ImportFragment : BaseFragment<ImportViewModel, FragmentImportBinding>(Impo
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding.importGoogleFit.setOnClickListener {
|
binding.importGoogleFit.setOnClickListener {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
importFromGoogleFit()
|
||||||
importFromGoogleFit()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
binding.importSamsungHealth.setOnClickListener {
|
binding.importSamsungHealth.setOnClickListener {
|
||||||
importFromSamsungHealth()
|
importFromSamsungHealth()
|
@ -1,11 +1,10 @@
|
|||||||
package com.dzeio.openhealth.ui.main.imports
|
package com.dzeio.openhealth.ui.imports
|
||||||
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import com.dzeio.openhealth.core.BaseViewModel
|
import com.dzeio.openhealth.core.BaseViewModel
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
import com.dzeio.openhealth.data.weight.WeightRepository
|
import com.dzeio.openhealth.data.weight.WeightRepository
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import java.security.CodeSource
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
|||||||
|
package com.dzeio.openhealth.ui.water
|
||||||
|
|
@ -1,68 +1,67 @@
|
|||||||
package com.dzeio.openhealth.ui.dialogs
|
package com.dzeio.openhealth.ui.weight
|
||||||
|
|
||||||
import android.app.AlertDialog
|
import android.view.LayoutInflater
|
||||||
import android.view.LayoutInflater
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.lifecycleScope
|
import com.dzeio.openhealth.R
|
||||||
import com.dzeio.openhealth.R
|
import com.dzeio.openhealth.core.BaseDialog
|
||||||
import com.dzeio.openhealth.core.BaseDialog
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.databinding.DialogAddWeightBinding
|
||||||
import com.dzeio.openhealth.databinding.DialogAddWeightBinding
|
import com.dzeio.openhealth.ui.home.HomeViewModel
|
||||||
import com.dzeio.openhealth.ui.main.home.HomeViewModel
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
|
@AndroidEntryPoint
|
||||||
@AndroidEntryPoint
|
class AddWeightDialog : BaseDialog<HomeViewModel, DialogAddWeightBinding>(HomeViewModel::class.java) {
|
||||||
class AddWeightDialog : BaseDialog<HomeViewModel, DialogAddWeightBinding>(HomeViewModel::class.java) {
|
|
||||||
|
override val bindingInflater: (LayoutInflater) -> DialogAddWeightBinding = DialogAddWeightBinding::inflate
|
||||||
override val bindingInflater: (LayoutInflater) -> DialogAddWeightBinding = DialogAddWeightBinding::inflate
|
|
||||||
|
override fun onBuilderInit(builder: MaterialAlertDialogBuilder) {
|
||||||
override fun onBuilderInit(builder: MaterialAlertDialogBuilder) {
|
super.onBuilderInit(builder)
|
||||||
super.onBuilderInit(builder)
|
|
||||||
|
builder.apply {
|
||||||
builder.apply {
|
setTitle("Add your weight (kg)")
|
||||||
setTitle("Add your weight (kg)")
|
setIcon(activity?.let { ContextCompat.getDrawable(it, R.drawable.ic_outline_timeline_24) })
|
||||||
setIcon(activity?.let { ContextCompat.getDrawable(it, R.drawable.ic_outline_timeline_24) })
|
setPositiveButton("Validate") { dialog, _ ->
|
||||||
setPositiveButton("Validate") { dialog, _ ->
|
save()
|
||||||
save()
|
}
|
||||||
}
|
setNegativeButton("Cancel") { dialog, _ ->
|
||||||
setNegativeButton("Cancel") { dialog, _ ->
|
dialog.cancel()
|
||||||
dialog.cancel()
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
override fun onCreated() {
|
||||||
override fun onCreated() {
|
super.onCreated()
|
||||||
super.onCreated()
|
|
||||||
|
lifecycleScope.launchWhenStarted {
|
||||||
lifecycleScope.launchWhenStarted {
|
viewModel.lastWeight().collect {
|
||||||
viewModel.lastWeight().collect {
|
if (it != null) {
|
||||||
if (it != null) {
|
binding.kg.value = it.weight.toInt()
|
||||||
binding.kg.value = it.weight.toInt()
|
binding.gram.value = ((it.weight - it.weight.toInt()) * 10 ).toInt()
|
||||||
binding.gram.value = ((it.weight - it.weight.toInt()) * 10 ).toInt()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
binding.kg.maxValue = 636
|
||||||
binding.kg.maxValue = 636
|
binding.kg.minValue = 0
|
||||||
binding.kg.minValue = 0
|
|
||||||
|
binding.gram.maxValue = 9
|
||||||
binding.gram.maxValue = 9
|
binding.gram.minValue = 0
|
||||||
binding.gram.minValue = 0
|
}
|
||||||
}
|
|
||||||
|
private fun save() {
|
||||||
private fun save() {
|
val weight = Weight().apply {
|
||||||
val weight = Weight().apply {
|
weight = binding.kg.value + (binding.gram.value.toFloat() / 10)
|
||||||
weight = binding.kg.value + (binding.gram.value.toFloat() / 10)
|
source = "OpenHealth"
|
||||||
source = "OpenHealth"
|
|
||||||
|
}
|
||||||
}
|
lifecycleScope.launchWhenCreated {
|
||||||
lifecycleScope.launchWhenCreated {
|
viewModel.addWeight(weight)
|
||||||
viewModel.addWeight(weight)
|
}
|
||||||
}
|
//callback?.invoke()
|
||||||
//callback?.invoke()
|
dialog?.dismiss()
|
||||||
dialog?.dismiss()
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,162 +1,165 @@
|
|||||||
package com.dzeio.openhealth.ui.dialogs
|
package com.dzeio.openhealth.ui.weight
|
||||||
|
|
||||||
import android.app.AlertDialog
|
import android.app.Dialog
|
||||||
import android.app.DatePickerDialog
|
import android.os.Build
|
||||||
import android.app.Dialog
|
import android.os.Bundle
|
||||||
import android.content.res.Resources
|
import android.util.Log
|
||||||
import android.os.Build
|
import android.view.LayoutInflater
|
||||||
import android.os.Bundle
|
import android.view.MenuItem
|
||||||
import android.util.Log
|
import android.view.Window
|
||||||
import android.view.LayoutInflater
|
import androidx.core.content.ContextCompat
|
||||||
import android.view.MenuItem
|
import androidx.lifecycle.lifecycleScope
|
||||||
import android.view.ViewGroup
|
import androidx.navigation.fragment.findNavController
|
||||||
import android.view.Window
|
import androidx.navigation.fragment.navArgs
|
||||||
import androidx.annotation.RequiresApi
|
import com.dzeio.openhealth.R
|
||||||
import androidx.core.content.ContextCompat
|
import com.dzeio.openhealth.core.BaseFullscreenDialog
|
||||||
import androidx.lifecycle.lifecycleScope
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
import androidx.navigation.fragment.findNavController
|
import com.dzeio.openhealth.databinding.DialogEditWeightBinding
|
||||||
import androidx.navigation.fragment.navArgs
|
import com.dzeio.openhealth.ui.home.HomeViewModel
|
||||||
import com.dzeio.openhealth.R
|
import com.google.android.material.datepicker.MaterialDatePicker
|
||||||
import com.dzeio.openhealth.core.BaseFullscreenDialog
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.google.android.material.timepicker.MaterialTimePicker
|
||||||
import com.dzeio.openhealth.databinding.DialogAddWeightBinding
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.dzeio.openhealth.databinding.DialogEditWeightBinding
|
import kotlinx.coroutines.flow.collect
|
||||||
import com.dzeio.openhealth.ui.main.home.HomeViewModel
|
import java.util.*
|
||||||
import com.google.android.material.datepicker.MaterialDatePicker
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
@AndroidEntryPoint
|
||||||
import com.google.android.material.timepicker.MaterialTimePicker
|
class EditWeightDialog :
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
BaseFullscreenDialog<HomeViewModel, DialogEditWeightBinding>(HomeViewModel::class.java) {
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import java.util.*
|
override val bindingInflater: (LayoutInflater) -> DialogEditWeightBinding =
|
||||||
|
DialogEditWeightBinding::inflate
|
||||||
@AndroidEntryPoint
|
|
||||||
class EditWeightDialog : BaseFullscreenDialog<HomeViewModel, DialogEditWeightBinding>(HomeViewModel::class.java) {
|
override val isFullscreenLayout = true
|
||||||
|
|
||||||
override val bindingInflater: (LayoutInflater) -> DialogEditWeightBinding = DialogEditWeightBinding::inflate
|
val args: EditWeightDialogArgs by navArgs()
|
||||||
|
|
||||||
override val isFullscreenLayout = true
|
lateinit var weight: Weight
|
||||||
|
|
||||||
val args: EditWeightDialogArgs by navArgs()
|
// override fun onBuilderInit(builder: AlertDialog.Builder) {
|
||||||
|
// super.onBuilderInit(builder)
|
||||||
lateinit var weight: Weight
|
//
|
||||||
|
// builder.apply {
|
||||||
// override fun onBuilderInit(builder: AlertDialog.Builder) {
|
// setTitle("Add your weight (kg)")
|
||||||
// super.onBuilderInit(builder)
|
// setIcon(activity?.let { ContextCompat.getDrawable(it, R.drawable.ic_outline_timeline_24) })
|
||||||
//
|
// setPositiveButton("Validate") { dialog, _ ->
|
||||||
// builder.apply {
|
// save()
|
||||||
// setTitle("Add your weight (kg)")
|
// }
|
||||||
// setIcon(activity?.let { ContextCompat.getDrawable(it, R.drawable.ic_outline_timeline_24) })
|
// setNegativeButton("Cancel") { dialog, _ ->
|
||||||
// setPositiveButton("Validate") { dialog, _ ->
|
// dialog.cancel()
|
||||||
// save()
|
// }
|
||||||
// }
|
//
|
||||||
// setNegativeButton("Cancel") { dialog, _ ->
|
// }
|
||||||
// dialog.cancel()
|
// }
|
||||||
// }
|
|
||||||
//
|
override fun onDialogInit(dialog: Dialog) {
|
||||||
// }
|
super.onDialogInit(dialog)
|
||||||
// }
|
|
||||||
|
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||||
override fun onDialogInit(dialog: Dialog) {
|
}
|
||||||
super.onDialogInit(dialog)
|
|
||||||
|
override fun onCreated(savedInstanceState: Bundle?) {
|
||||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
super.onCreated(savedInstanceState)
|
||||||
}
|
|
||||||
|
lifecycleScope.launchWhenStarted {
|
||||||
override fun onCreated(savedInstanceState: Bundle?) {
|
viewModel.fetchWeight(args.id).collect {
|
||||||
super.onCreated(savedInstanceState)
|
weight = it!!
|
||||||
|
binding.layoutDialogEditWeightKg.value = it.weight.toInt()
|
||||||
lifecycleScope.launchWhenStarted {
|
binding.layoutDialogEditWeightGram.value =
|
||||||
viewModel.fetchWeight(args.id).collect {
|
((it.weight - it.weight.toInt()) * 10).toInt()
|
||||||
weight = it!!
|
|
||||||
binding.layoutDialogEditWeightKg.value = it.weight.toInt()
|
binding.layoutDialogEditWeightTimestamp.setText(it.formatTimestamp())
|
||||||
binding.layoutDialogEditWeightGram.value = ((it.weight - it.weight.toInt()) * 10 ).toInt()
|
}
|
||||||
|
}
|
||||||
binding.layoutDialogEditWeightTimestamp.setText(it.formatTimestamp())
|
|
||||||
}
|
binding.layoutDialogEditWeightKg.maxValue = 636
|
||||||
}
|
binding.layoutDialogEditWeightKg.minValue = 0
|
||||||
|
|
||||||
binding.layoutDialogEditWeightKg.maxValue = 636
|
binding.layoutDialogEditWeightGram.maxValue = 9
|
||||||
binding.layoutDialogEditWeightKg.minValue = 0
|
binding.layoutDialogEditWeightGram.minValue = 0
|
||||||
|
|
||||||
binding.layoutDialogEditWeightGram.maxValue = 9
|
binding.layoutDialogEditWeightTimestamp.setOnClickListener {
|
||||||
binding.layoutDialogEditWeightGram.minValue = 0
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
val date = Date(weight.timestamp)
|
||||||
binding.layoutDialogEditWeightTimestamp.setOnClickListener {
|
val datePicker = MaterialDatePicker.Builder.datePicker()
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
.setTitleText("Select Date")
|
||||||
val date = Date(weight.timestamp)
|
.setSelection(weight.timestamp)
|
||||||
val datePicker = MaterialDatePicker.Builder.datePicker()
|
.build()
|
||||||
.setTitleText("Select Date")
|
|
||||||
.setSelection(weight.timestamp)
|
val fragManager = requireActivity().supportFragmentManager
|
||||||
.build()
|
|
||||||
|
datePicker.addOnPositiveButtonClickListener { tsp ->
|
||||||
val fragManager = requireActivity().supportFragmentManager
|
val timePicker = MaterialTimePicker.Builder()
|
||||||
|
.setHour(date.hours)
|
||||||
datePicker.addOnPositiveButtonClickListener { tsp ->
|
.setMinute(date.minutes)
|
||||||
val timePicker = MaterialTimePicker.Builder()
|
.setTitleText("Pouet")
|
||||||
.setHour(date.hours)
|
.build()
|
||||||
.setMinute(date.minutes)
|
|
||||||
.setTitleText("Pouet")
|
timePicker.addOnPositiveButtonClickListener {
|
||||||
.build()
|
Log.d("T", "${timePicker.hour} ${timePicker.minute}")
|
||||||
|
val newDate = Date(tsp)
|
||||||
timePicker.addOnPositiveButtonClickListener {
|
newDate.hours = timePicker.hour
|
||||||
Log.d("T", "${timePicker.hour} ${timePicker.minute}")
|
newDate.minutes = timePicker.minute
|
||||||
val newDate = Date(tsp)
|
weight.timestamp = newDate.time
|
||||||
newDate.hours = timePicker.hour
|
binding.layoutDialogEditWeightTimestamp.setText(weight.formatTimestamp())
|
||||||
newDate.minutes = timePicker.minute
|
Log.d("Res", newDate.time.toString())
|
||||||
weight.timestamp = newDate.time
|
}
|
||||||
binding.layoutDialogEditWeightTimestamp.setText(weight.formatTimestamp())
|
timePicker.show(fragManager, "dialog")
|
||||||
Log.d("Res", newDate.time.toString())
|
}
|
||||||
}
|
datePicker.show(fragManager, "dialog")
|
||||||
timePicker.show(fragManager, "dialog")
|
Log.d("Tag", "${date.year + 1900}, ${date.month}, ${date.day}")
|
||||||
}
|
// val dg = DatePickerDialog(requireActivity())
|
||||||
datePicker.show(fragManager, "dialog")
|
// dg.setOnDateSetListener { _, year, month, day ->
|
||||||
Log.d("Tag", "${date.year + 1900}, ${date.month}, ${date.day}")
|
//
|
||||||
// val dg = DatePickerDialog(requireActivity())
|
// }
|
||||||
// dg.setOnDateSetListener { _, year, month, day ->
|
// dg.updateDate(date.year + 1900, date.month, date.day)
|
||||||
//
|
// dg.show()
|
||||||
// }
|
} else {
|
||||||
// dg.updateDate(date.year + 1900, date.month, date.day)
|
TODO("VERSION.SDK_INT < N")
|
||||||
// dg.show()
|
}
|
||||||
} else {
|
|
||||||
TODO("VERSION.SDK_INT < N")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
|
||||||
|
private fun save() {
|
||||||
}
|
lifecycleScope.launchWhenCreated {
|
||||||
|
weight.weight =
|
||||||
private fun save() {
|
binding.layoutDialogEditWeightKg.value + (binding.layoutDialogEditWeightGram.value.toFloat() / 10)
|
||||||
lifecycleScope.launchWhenCreated {
|
viewModel.addWeight(weight)
|
||||||
weight.weight = binding.layoutDialogEditWeightKg.value + (binding.layoutDialogEditWeightGram.value.toFloat() / 10)
|
findNavController().popBackStack()
|
||||||
viewModel.addWeight(weight)
|
}
|
||||||
findNavController().popBackStack()
|
}
|
||||||
}
|
|
||||||
}
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
return when (item.itemId) {
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
R.id.menu_fullscreen_dialog_save -> {
|
||||||
return when (item.itemId) {
|
save()
|
||||||
R.id.menu_fullscreen_dialog_save -> {
|
true
|
||||||
save()
|
}
|
||||||
true
|
R.id.menu_fullscreen_dialog_delete -> {
|
||||||
}
|
MaterialAlertDialogBuilder(requireContext())
|
||||||
R.id.menu_fullscreen_dialog_delete -> {
|
.setTitle("Delete Weight?")
|
||||||
MaterialAlertDialogBuilder(requireContext())
|
.setMessage("Are you sure you want to delete this weight?")
|
||||||
.setTitle("Delete Weight?")
|
.setPositiveButton("Yes") { _, _ ->
|
||||||
.setMessage("Are you sure you want to delete this weight?")
|
lifecycleScope.launchWhenStarted {
|
||||||
.setPositiveButton("Yes") {_, _ ->
|
viewModel.deleteWeight(weight)
|
||||||
lifecycleScope.launchWhenStarted {
|
findNavController().popBackStack()
|
||||||
viewModel.deleteWeight(weight)
|
}
|
||||||
findNavController().popBackStack()
|
}
|
||||||
}
|
.setIcon(
|
||||||
}
|
ContextCompat.getDrawable(
|
||||||
.setIcon(ContextCompat.getDrawable(requireContext(), R.drawable.ic_outline_delete_24))
|
requireContext(),
|
||||||
.setNegativeButton("No") { _, _ ->}
|
R.drawable.ic_outline_delete_24
|
||||||
.show()
|
)
|
||||||
true
|
)
|
||||||
}
|
.setNegativeButton("No") { _, _ -> }
|
||||||
else -> super.onOptionsItemSelected(item)
|
.show()
|
||||||
}
|
true
|
||||||
|
}
|
||||||
}
|
else -> super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,54 +1,53 @@
|
|||||||
package com.dzeio.openhealth.ui.main.list_weight
|
package com.dzeio.openhealth.ui.weight
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.os.bundleOf
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import com.dzeio.openhealth.adapters.WeightAdapter
|
||||||
import com.dzeio.openhealth.adapters.WeightAdapter
|
import com.dzeio.openhealth.core.BaseFragment
|
||||||
import com.dzeio.openhealth.core.BaseFragment
|
import com.dzeio.openhealth.databinding.FragmentListWeightBinding
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.ui.home.HomeViewModel
|
||||||
import com.dzeio.openhealth.databinding.FragmentListWeightBinding
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import com.dzeio.openhealth.ui.dialogs.EditWeightDialog
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import com.dzeio.openhealth.ui.main.home.HomeViewModel
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
import kotlinx.coroutines.flow.collect
|
class ListWeightFragment :
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
BaseFragment<HomeViewModel, FragmentListWeightBinding>(HomeViewModel::class.java) {
|
||||||
import java.util.*
|
|
||||||
|
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentListWeightBinding =
|
||||||
@AndroidEntryPoint
|
FragmentListWeightBinding::inflate
|
||||||
class ListWeightFragment : BaseFragment<HomeViewModel, FragmentListWeightBinding>(HomeViewModel::class.java) {
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentListWeightBinding = FragmentListWeightBinding::inflate
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
val recycler = binding.list
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
val manager = LinearLayoutManager(requireContext())
|
||||||
val recycler = binding.list
|
recycler.layoutManager = manager
|
||||||
|
|
||||||
val manager = LinearLayoutManager(requireContext())
|
val adapter = WeightAdapter()
|
||||||
recycler.layoutManager = manager
|
adapter.onItemClick = {
|
||||||
|
findNavController().navigate(
|
||||||
val adapter = WeightAdapter()
|
ListWeightFragmentDirections.actionNavListWeightToNavEditWeight(
|
||||||
adapter.onItemClick = {
|
it.id
|
||||||
findNavController().navigate(ListWeightFragmentDirections.actionNavListWeightToNavEditWeight(it.id))
|
)
|
||||||
//EditWeightDialog().show(requireActivity().supportFragmentManager, "dialog")
|
)
|
||||||
}
|
//EditWeightDialog().show(requireActivity().supportFragmentManager, "dialog")
|
||||||
recycler.adapter = adapter
|
}
|
||||||
|
recycler.adapter = adapter
|
||||||
viewLifecycleOwner.lifecycleScope.launchWhenCreated {
|
|
||||||
viewModel.fetchWeights().collectLatest {
|
viewLifecycleOwner.lifecycleScope.launchWhenCreated {
|
||||||
val itt = it.toMutableList()
|
viewModel.fetchWeights().collectLatest {
|
||||||
itt.sortWith { o1, o2 -> if (o1.timestamp > o2.timestamp) -1 else 1 }
|
val itt = it.toMutableList()
|
||||||
adapter.set(itt)
|
itt.sortWith { o1, o2 -> if (o1.timestamp > o2.timestamp) -1 else 1 }
|
||||||
}
|
adapter.set(itt)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
}
|
49
app/src/main/java/com/dzeio/openhealth/utils/BitmapUtils.kt
Normal file
49
app/src/main/java/com/dzeio/openhealth/utils/BitmapUtils.kt
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package com.dzeio.openhealth.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import java.io.File
|
||||||
|
import java.io.RandomAccessFile
|
||||||
|
import java.nio.channels.FileChannel
|
||||||
|
|
||||||
|
object BitmapUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find source of function lol
|
||||||
|
*/
|
||||||
|
fun convertToMutable(context: Context, imgIn: Bitmap): Bitmap? {
|
||||||
|
val width = imgIn.width
|
||||||
|
val height = imgIn.height
|
||||||
|
val type = imgIn.config
|
||||||
|
var outputFile: File? = null
|
||||||
|
val outputDir = context.cacheDir
|
||||||
|
try {
|
||||||
|
outputFile = File.createTempFile(
|
||||||
|
System.currentTimeMillis().toString(),
|
||||||
|
null,
|
||||||
|
outputDir
|
||||||
|
)
|
||||||
|
outputFile.deleteOnExit()
|
||||||
|
val randomAccessFile = RandomAccessFile(outputFile, "rw")
|
||||||
|
val channel = randomAccessFile.channel
|
||||||
|
val map = channel.map(
|
||||||
|
FileChannel.MapMode.READ_WRITE,
|
||||||
|
0,
|
||||||
|
(imgIn.rowBytes * height).toLong()
|
||||||
|
)
|
||||||
|
imgIn.copyPixelsToBuffer(map)
|
||||||
|
imgIn.recycle()
|
||||||
|
val result = Bitmap.createBitmap(width, height, type)
|
||||||
|
map.position(0)
|
||||||
|
result.copyPixelsFromBuffer(map)
|
||||||
|
channel.close()
|
||||||
|
randomAccessFile.close()
|
||||||
|
outputFile.delete()
|
||||||
|
return result
|
||||||
|
} catch (e: Exception) {
|
||||||
|
} finally {
|
||||||
|
outputFile?.delete()
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
30
app/src/main/java/com/dzeio/openhealth/utils/DrawUtils.kt
Normal file
30
app/src/main/java/com/dzeio/openhealth/utils/DrawUtils.kt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package com.dzeio.openhealth.utils
|
||||||
|
|
||||||
|
import android.graphics.*
|
||||||
|
|
||||||
|
object DrawUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fuck Graphics
|
||||||
|
*/
|
||||||
|
fun drawArc(canvas: Canvas, percent: Int, pColor: Int) {
|
||||||
|
canvas.width
|
||||||
|
val spacing = 120f
|
||||||
|
val r1 = RectF(
|
||||||
|
spacing,
|
||||||
|
spacing,
|
||||||
|
canvas.width - spacing,
|
||||||
|
canvas.height * 2 - spacing * 3
|
||||||
|
)
|
||||||
|
val paint = Paint()
|
||||||
|
paint.apply {
|
||||||
|
strokeWidth = 200f
|
||||||
|
style = Paint.Style.STROKE
|
||||||
|
color = pColor
|
||||||
|
isAntiAlias = true
|
||||||
|
strokeCap = Paint.Cap.ROUND
|
||||||
|
}
|
||||||
|
canvas.drawArc(r1, 180f, 180 * percent / 100f, false, paint)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
BIN
app/src/main/res/drawable/ellipse.png
Normal file
BIN
app/src/main/res/drawable/ellipse.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.0 KiB |
12
app/src/main/res/drawable/vector_elipse_empty.xml
Normal file
12
app/src/main/res/drawable/vector_elipse_empty.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="156dp"
|
||||||
|
android:height="81dp"
|
||||||
|
android:viewportWidth="156"
|
||||||
|
android:viewportHeight="81">
|
||||||
|
<path
|
||||||
|
android:pathData="M153,78C153,36.579 119.421,3 78,3C36.579,3 3,36.579 3,78"
|
||||||
|
android:strokeWidth="5"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#C9C5CA"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
@ -1,10 +1,157 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".ui.main.home.HomeFragment">
|
android:orientation="vertical"
|
||||||
|
tools:context=".ui.home.HomeFragment">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:weightSum="2"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
style="?attr/materialCardViewFilledStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_weight="1">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="54dp"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:weightSum="2">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/TextAppearance.Material3.TitleMedium"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Weight"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="end">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:src="@drawable/ic_baseline_add_24" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/ic_outline_hexagon_24" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:gravity="bottom"
|
||||||
|
android:weightSum="3">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/fragment_home_water_remove"
|
||||||
|
android:layout_width="18dp"
|
||||||
|
android:layout_height="18dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:src="@drawable/ic_outline_hexagon_24"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/linearLayout"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/linearLayout"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/linearLayout" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linearLayout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/background">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/fragment_home_water_current"
|
||||||
|
style="@style/TextAppearance.Material3.LabelMedium"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="900ml"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/fragment_home_water_total"
|
||||||
|
style="@style/TextAppearance.Material3.LabelMedium"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="1200ml"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/fragment_home_water_add"
|
||||||
|
android:layout_width="18dp"
|
||||||
|
android:layout_height="18dp"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:src="@drawable/ic_baseline_add_24"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/linearLayout"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/linearLayout"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/linearLayout" />
|
||||||
|
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/background"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintDimensionRatio="2:1"
|
||||||
|
android:src="@drawable/ic_outline_hexagon_24"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<!-- Unused Currently -->
|
||||||
|
<!-- <com.google.android.material.card.MaterialCardView-->
|
||||||
|
<!-- style="?attr/materialCardViewFilledStyle"-->
|
||||||
|
<!-- android:layout_width="match_parent"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:layout_marginStart="16dp"-->
|
||||||
|
<!-- android:layout_marginTop="16dp"-->
|
||||||
|
<!-- android:layout_weight="1"-->
|
||||||
|
<!-- android:layout_marginEnd="16dp">-->
|
||||||
|
|
||||||
|
<!-- </com.google.android.material.card.MaterialCardView>-->
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
style="?attr/materialCardViewFilledStyle"
|
style="?attr/materialCardViewFilledStyle"
|
||||||
@ -12,41 +159,34 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp">
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="horizontal">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<LinearLayout
|
||||||
android:id="@+id/constraintLayout2"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="54dp"
|
android:layout_height="54dp"
|
||||||
android:layout_marginHorizontal="16dp"
|
android:layout_marginHorizontal="16dp"
|
||||||
android:gravity="fill_horizontal|center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
android:weightSum="2">
|
||||||
tools:layout_editor_absoluteX="16dp">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/TextAppearance.Material3.TitleMedium"
|
style="@style/TextAppearance.Material3.TitleMedium"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Weight"
|
android:text="Weight"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_weight="1" />
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_weight="1"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:gravity="end">
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/add_weight"
|
android:id="@+id/add_weight"
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
@ -58,24 +198,17 @@
|
|||||||
android:id="@+id/list_weight"
|
android:id="@+id/list_weight"
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:src="@drawable/ic_outline_hexagon_24"
|
android:src="@drawable/ic_outline_hexagon_24" />
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.github.mikephil.charting.charts.LineChart
|
<com.github.mikephil.charting.charts.LineChart
|
||||||
android:id="@+id/weight_graph"
|
android:id="@+id/weight_graph"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="200dp"
|
android:layout_height="200dp"
|
||||||
android:minHeight="200dp"
|
android:minHeight="200dp" />
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/constraintLayout2" />
|
|
||||||
|
|
||||||
<!-- <com.jjoe64.graphview.GraphView-->
|
<!-- <com.jjoe64.graphview.GraphView-->
|
||||||
<!-- android:id="@+id/weight_graph"-->
|
<!-- android:id="@+id/weight_graph"-->
|
||||||
@ -87,8 +220,8 @@
|
|||||||
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||||
<!-- app:layout_constraintTop_toBottomOf="@+id/constraintLayout2" />-->
|
<!-- app:layout_constraintTop_toBottomOf="@+id/constraintLayout2" />-->
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</LinearLayout>
|
@ -4,7 +4,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".ui.main.imports.ImportFragment">
|
tools:context=".ui.imports.ImportFragment">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_slideshow"
|
android:id="@+id/text_slideshow"
|
||||||
|
@ -11,4 +11,4 @@
|
|||||||
android:padding="16dp"
|
android:padding="16dp"
|
||||||
|
|
||||||
tools:listitem="@layout/layout_item_weight"
|
tools:listitem="@layout/layout_item_weight"
|
||||||
tools:context=".ui.main.list_weight.ListWeightFragment" />
|
tools:context=".ui.weight.ListWeightFragment" />
|
6
app/src/main/res/layout/fragment_water_home.xml
Normal file
6
app/src/main/res/layout/fragment_water_home.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/nav_home"
|
android:id="@+id/nav_home"
|
||||||
android:name="com.dzeio.openhealth.ui.main.home.HomeFragment"
|
android:name="com.dzeio.openhealth.ui.home.HomeFragment"
|
||||||
android:label="@string/menu_home"
|
android:label="@string/menu_home"
|
||||||
tools:layout="@layout/fragment_home" >
|
tools:layout="@layout/fragment_home" >
|
||||||
<action
|
<action
|
||||||
@ -28,13 +28,13 @@
|
|||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/nav_import"
|
android:id="@+id/nav_import"
|
||||||
android:name="com.dzeio.openhealth.ui.main.imports.ImportFragment"
|
android:name="com.dzeio.openhealth.ui.imports.ImportFragment"
|
||||||
android:label="@string/menu_import"
|
android:label="@string/menu_import"
|
||||||
tools:layout="@layout/fragment_import" />
|
tools:layout="@layout/fragment_import" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/nav_list_weight"
|
android:id="@+id/nav_list_weight"
|
||||||
android:name="com.dzeio.openhealth.ui.main.list_weight.ListWeightFragment"
|
android:name="com.dzeio.openhealth.ui.weight.ListWeightFragment"
|
||||||
android:label="@string/menu_list_weight"
|
android:label="@string/menu_list_weight"
|
||||||
tools:layout="@layout/fragment_list_weight" >
|
tools:layout="@layout/fragment_list_weight" >
|
||||||
<action
|
<action
|
||||||
@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/nav_edit_weight"
|
android:id="@+id/nav_edit_weight"
|
||||||
android:name="com.dzeio.openhealth.ui.dialogs.EditWeightDialog"
|
android:name="com.dzeio.openhealth.ui.weight.EditWeightDialog"
|
||||||
android:label="@string/menu_edit_weight"
|
android:label="@string/menu_edit_weight"
|
||||||
tools:layout="@layout/dialog_edit_weight">
|
tools:layout="@layout/dialog_edit_weight">
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user