Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .DS_Store
Binary file not shown.
Binary file added .gradle/.DS_Store
Binary file not shown.
Binary file added .gradle/8.0/.DS_Store
Binary file not shown.
Binary file modified app/.DS_Store
Binary file not shown.
Binary file modified app/src/.DS_Store
Binary file not shown.
4 changes: 4 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,8 @@
<!-- Declare the internet feature -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Declare the location feature -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

</manifest>
123 changes: 102 additions & 21 deletions app/src/main/java/com/example/nailapp/ui/nixsensor/NixSensorActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.graphics.Color
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.AdapterView
import android.widget.ListView
import android.widget.ProgressBar
import android.widget.Toast
Expand All @@ -31,13 +32,15 @@ import androidx.core.graphics.ColorUtils
import com.example.nailapp.R
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.Spinner
import android.widget.TextView

class NixSensorActivity : AppCompatActivity() {

//Iman: check the runOnUI thread and see if that will affect the dropdown feature I added
class NixSensorActivity : AppCompatActivity(), AdapterView.OnItemSelectedListener {
private lateinit var binding: ActivityNixsensorBinding
private var recalledDevice: IDeviceCompat? = null

private val phColors = mutableMapOf(
private var measurementColors = mutableMapOf(
"5.0" to intArrayOf(142, 100, 131),
"6.0" to intArrayOf(137, 99, 133),
"7.0" to intArrayOf(124, 103, 130),
Expand All @@ -46,12 +49,14 @@ class NixSensorActivity : AppCompatActivity() {
private lateinit var deviceListView: ListView
private lateinit var progressBar: ProgressBar
private val deviceList = mutableListOf<IDeviceCompat>()
private var measurementChosen: String = "pH"

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityNixsensorBinding.inflate(layoutInflater)
setContentView(binding.root)
displayPHColors()
setupDropDownMenu()
displayMeasurementColors()
setupUI()
initializeScanner()
}
Expand Down Expand Up @@ -160,18 +165,47 @@ class NixSensorActivity : AppCompatActivity() {
}
}

private fun displayPHColors() {
private fun displayMeasurementColors() {
// Set the background color of each sample view
phColors["5.0"]?.let { rgb ->
when (measurementChosen) {
"Nitrate" -> {
val values = arrayOf("6.0", "8.0", "10.0", "12.0")
setColorChart(values, 14f)
}
"Glucose" -> {
val values = arrayOf("80.0", "90.0", "100.0", "110.0")
setColorChart(values, 13.5f)
}
else -> { // else show pH levels that are set to show by default
val values = arrayOf("5.0", "6.0", "7.0", "8.0")
setColorChart(values, 14f)
}
}

}

private fun setColorChart(value: Array<String>, textsize: Float){
binding.textSample6.text = "$measurementChosen ${value[0]}" //"pH 5.0"
binding.textSample6.textSize = textsize
measurementColors[value[0]]?.let { rgb ->
binding.colorSample6.setBackgroundColor(Color.rgb(rgb[0], rgb[1], rgb[2]))
}
phColors["6.0"]?.let { rgb ->

binding.textSample7.text = "$measurementChosen ${value[1]}" //"pH 6.0"
binding.textSample7.textSize = textsize
measurementColors[value[1]]?.let { rgb ->
binding.colorSample7.setBackgroundColor(Color.rgb(rgb[0], rgb[1], rgb[2]))
}
phColors["7.0"]?.let { rgb ->

binding.textSample8.text = "${measurementChosen} ${value[2]}" //"pH 7.0"
binding.textSample8.textSize = textsize
measurementColors[value[2]]?.let { rgb ->
binding.colorSample8.setBackgroundColor(Color.rgb(rgb[0], rgb[1], rgb[2]))
}
phColors["8.0"]?.let { rgb ->

binding.textSample9.text = "$measurementChosen ${value[3]}" //"pH 8.0"
binding.textSample9.textSize = textsize
measurementColors[value[3]]?.let { rgb ->
binding.colorSample9.setBackgroundColor(Color.rgb(rgb[0], rgb[1], rgb[2]))
}
}
Expand Down Expand Up @@ -206,13 +240,13 @@ class NixSensorActivity : AppCompatActivity() {
}

private fun predictPH(rgbValue: IntArray): String {
val nearestLab = phColors
val distances = nearestLab.map { (ph, value) ->
val distance = euclideanDistance(rgbValue, value)
val labdistance = labDistance(rgbValue,value)
Log.d(TAG, "RGB Distance to pH $ph: $distance")
Log.d(TAG, "LAB Distance to pH $ph: $labdistance")
ph to distance
val nearestLab = measurementColors
val distances = nearestLab.map { (measurementColorsKey, measurementColorsValue) ->
val distance = euclideanDistance(rgbValue, measurementColorsValue)
val labdistance = labDistance(rgbValue,measurementColorsValue)
Log.d(TAG, "RGB Distance to $measurementChosen $measurementColorsKey: $distance")
Log.d(TAG, "LAB Distance to $measurementChosen $measurementColorsKey: $labdistance")
measurementColorsKey to distance
}

return distances.minByOrNull { it.second }?.first ?: "Unknown"
Expand Down Expand Up @@ -287,24 +321,71 @@ class NixSensorActivity : AppCompatActivity() {
val dialogView = layoutInflater.inflate(R.layout.dialog_ph_color, null)
builder.setView(dialogView)

val pHEditText = dialogView.findViewById<EditText>(R.id.edit_ph_value)
val measurementEditText = dialogView.findViewById<EditText>(R.id.edit_ph_value)
measurementEditText.hint = "$measurementChosen Value"

val redEditText = dialogView.findViewById<EditText>(R.id.edit_red_value)
val greenEditText = dialogView.findViewById<EditText>(R.id.edit_green_value)
val blueEditText = dialogView.findViewById<EditText>(R.id.edit_blue_value)

builder.setPositiveButton("Save") { _, _ ->
val ph = pHEditText.text.toString()
val measurementAssignedNumber = measurementEditText.text.toString()
val red = redEditText.text.toString().toIntOrNull() ?: 0
val green = greenEditText.text.toString().toIntOrNull() ?: 0
val blue = blueEditText.text.toString().toIntOrNull() ?: 0

if (ph.isNotEmpty()) {
phColors[ph] = intArrayOf(red, green, blue)
displayPHColors() // Update the UI to reflect changes
if (measurementAssignedNumber.isNotEmpty()) {
measurementColors[measurementAssignedNumber] = intArrayOf(red, green, blue)
displayMeasurementColors() // Update the UI to reflect changes
}
}

builder.setNegativeButton("Cancel", null)
builder.show()
}

private fun setupDropDownMenu() {
//Variables for drop down menu:
val spinner = findViewById<Spinner>(R.id.dropdown_menu)
val arrayAdapter = ArrayAdapter.createFromResource(this, R.array.dropdown_options, android.R.layout.simple_spinner_item)

arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = arrayAdapter
spinner.onItemSelectedListener = this
}

override fun onItemSelected(adapterview: AdapterView<*>?, view: View?, position: Int, id: Long) {
val text = adapterview?.getItemAtPosition(position).toString()
Toast.makeText(adapterview!!.context, text, Toast.LENGTH_SHORT).show() //!! == non-null assertion operator

val temp = text.split(" ").toTypedArray() // Split by spaces -> temp = [pH, Levels]
measurementChosen = temp[0]

//Change layout based on chosen dropdown option:
if (measurementChosen == "Nitrate"){
//Toast.makeText(adapterview!!.context, measurementChosen, Toast.LENGTH_SHORT).show() //Testing
measurementColors = mutableMapOf(
"6.0" to intArrayOf(142, 100, 131),
"8.0" to intArrayOf(137, 99, 133),
"10.0" to intArrayOf(124, 103, 130),
"12.0" to intArrayOf(95, 104, 132)
)
} else if (measurementChosen == "Glucose"){
//Toast.makeText(adapterview!!.context, measurementChosen, Toast.LENGTH_SHORT).show() //Testing
measurementColors = mutableMapOf(
"80.0" to intArrayOf(142, 100, 131),
"90.0" to intArrayOf(137, 99, 133),
"100.0" to intArrayOf(124, 103, 130),
"110.0" to intArrayOf(95, 104, 132)
)
}

// Refresh the layout after updating the map
displayMeasurementColors()

}

override fun onNothingSelected(p0: AdapterView<*>?) {
TODO("Not yet implemented")
}
}
22 changes: 18 additions & 4 deletions app/src/main/res/layout/activity_nixsensor.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@
android:text="Finding Device"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintHorizontal_bias="0.111"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.847" />
app:layout_constraintVertical_bias="0.959" />

<Button
android:id="@+id/buttonH"
Expand Down Expand Up @@ -114,7 +114,7 @@
app:layout_constraintHorizontal_bias="0.49"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.394" />
app:layout_constraintVertical_bias="0.414" />

<View
android:id="@+id/colorSquare"
Expand Down Expand Up @@ -251,7 +251,21 @@
app:layout_constraintHorizontal_bias="0.952"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textrange"
app:layout_constraintVertical_bias="0.309" />
app:layout_constraintVertical_bias="0.299" />

<Spinner
android:id="@+id/dropdown_menu"
android:layout_width="409dp"
android:layout_height="wrap_content"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="676dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.05"
app:layout_constraintHorizontal_bias="0.052"
/>


</androidx.constraintlayout.widget.ConstraintLayout>
11 changes: 11 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,15 @@
</string>

<string name="questionnaire_link"><a href="https://docs.google.com/forms/d/e/1FAIpQLScEJKbR6rpwW6nnI2bu5QkQB2RaRxrV6G14_ZMa4ps8SBBXkw/viewform?usp=sf_link">Questionnaire</a></string>

<string-array name="dropdown_options">
<item> pH Levels </item>
<item> Nitrate Levels </item>
<item> Glucose Levels </item>
</string-array>

<string-array name="ph_level_options">


</string-array>
</resources>
26 changes: 10 additions & 16 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
## For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# Default value: -Xmx1024m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# This option should only be used with decoupled projects. For more details, visit
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
#Wed Nov 27 06:24:00 PST 2024
android.nonTransitiveRClass=true
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
org.gradle.jvmargs=-Xmx1024M -Dkotlin.daemon.jvm.options\="-Xmx1024M" -Dfile.encoding\=UTF-8
8 changes: 3 additions & 5 deletions local.properties
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/Users/kuyuanhao/Library/Android/sdk
#Sun Nov 24 17:21:33 PST 2024
sdk.dir=/Users/imankonjo2020/Library/Android/sdk
Binary file modified nixrepo/.DS_Store
Binary file not shown.
Binary file modified nixrepo/com/.DS_Store
Binary file not shown.