From c9b5e34a87a1284453f24ebc6dfaef98d5d7f333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=8C=B3=E2=9D=A4=20logve=2Eca=20=E2=9D=A4=F0=9F=8C=B3?= Date: Sat, 15 Jun 2024 09:36:42 -0400 Subject: [PATCH] =?UTF-8?q?aliens=20all=20around=20=F0=9F=9B=B0=EF=B8=8F?= =?UTF-8?q?=F0=9F=9B=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add gps request - icon to list dis/connect 🟡🟢 - stop btn will bring you to main page not close app --- .../com/example/mycompanion/MainActivity.kt | 108 +++++++++++++++--- .../com/example/mycompanion/SportAdapter.kt | 23 ++-- .../com/example/mycompanion/TimerActivity.kt | 19 ++- app/src/main/res/drawable/green_circle.xml | 4 + app/src/main/res/drawable/yellow_circle.xml | 4 + app/src/main/res/layout/activity_main.xml | 35 ++++-- app/src/main/res/layout/item_sport.xml | 33 ++++-- app/src/main/res/values-night/colors.xml | 12 ++ app/src/main/res/values/colors.xml | 11 ++ app/src/main/res/values/styles.xml | 12 ++ 10 files changed, 215 insertions(+), 46 deletions(-) create mode 100644 app/src/main/res/drawable/green_circle.xml create mode 100644 app/src/main/res/drawable/yellow_circle.xml create mode 100644 app/src/main/res/values-night/colors.xml create mode 100644 app/src/main/res/values/styles.xml diff --git a/app/src/main/java/com/example/mycompanion/MainActivity.kt b/app/src/main/java/com/example/mycompanion/MainActivity.kt index aece245..d9d650e 100644 --- a/app/src/main/java/com/example/mycompanion/MainActivity.kt +++ b/app/src/main/java/com/example/mycompanion/MainActivity.kt @@ -1,29 +1,47 @@ package com.example.mycompanion +import android.Manifest +import android.content.Context import android.content.Intent +import android.content.pm.PackageManager +import android.location.GnssStatus +import android.location.Location +import android.location.LocationListener +import android.location.LocationManager import android.os.Bundle import android.util.Log +import android.view.View import androidx.appcompat.app.AppCompatActivity +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import com.google.android.flexbox.FlexboxLayoutManager import com.google.android.flexbox.FlexDirection import com.google.android.flexbox.JustifyContent - -class MainActivity : AppCompatActivity() { +class MainActivity : AppCompatActivity(), LocationListener { private lateinit var selectedSport: String + private lateinit var locationManager: LocationManager + private lateinit var gpsStatusCircle: View + private var gpsSignalAcquired = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - val suffix = "_emoji" - val filteredResources = getResourcesWithSuffix(suffix) + locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager + + gpsStatusCircle = findViewById(R.id.gps_status_circle) - for (resource in filteredResources) { - Log.d("MainActivity", "Resource: $resource") + if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) + != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, + arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 1) + } else { + requestLocationUpdates() } + // Define the list of sports val sports = listOf( Sport(getString(R.string.badminton), getString(R.string.badminton_emoji), getString(R.string.badminton)), @@ -46,6 +64,74 @@ class MainActivity : AppCompatActivity() { recyclerView.adapter = SportAdapter(sports) { sport -> onSportClick(sport) } } + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + if (requestCode == 1) { + if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { + requestLocationUpdates() + } else { + // Permission denied, show a message to the user + Log.d("MainActivity", "Permission denied") + } + } + } + + private fun requestLocationUpdates() { + if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED) { + gpsStatusCircle.visibility = View.VISIBLE + gpsStatusCircle.setBackgroundResource(R.drawable.yellow_circle) + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, this) + locationManager.registerGnssStatusCallback(gnssStatusCallback, null) + } + } + + private val gnssStatusCallback = object : GnssStatus.Callback() { + override fun onStarted() { + gpsStatusCircle.visibility = View.VISIBLE + gpsStatusCircle.setBackgroundResource(R.drawable.yellow_circle) + gpsSignalAcquired = false + Log.d("MainActivity", "GPS searching for signal") + } + + override fun onStopped() { + gpsStatusCircle.visibility = View.GONE + gpsSignalAcquired = false + Log.d("MainActivity", "GPS stopped") + } + + override fun onFirstFix(ttffMillis: Int) { + gpsStatusCircle.setBackgroundResource(R.drawable.green_circle) + gpsSignalAcquired = true + Log.d("MainActivity", "GPS signal acquired") + } + + override fun onSatelliteStatusChanged(status: GnssStatus) { + if (gpsSignalAcquired) { + gpsStatusCircle.setBackgroundResource(R.drawable.green_circle) + } + } + } + + override fun onLocationChanged(location: Location) { + Log.d("MainActivity", "Location: ${location.latitude}, ${location.longitude}") + // GPS signal is acquired, setting the circle to green is handled by onFirstFix + gpsStatusCircle.setBackgroundResource(R.drawable.green_circle) + gpsSignalAcquired = true + } + + override fun onProviderEnabled(provider: String) { + gpsStatusCircle.visibility = View.VISIBLE + gpsStatusCircle.setBackgroundResource(R.drawable.yellow_circle) + Log.d("MainActivity", "GPS provider enabled") + } + + override fun onProviderDisabled(provider: String) { + gpsStatusCircle.visibility = View.GONE + gpsSignalAcquired = false + Log.d("MainActivity", "GPS provider disabled") + } + private fun onSportClick(sport: Sport) { selectedSport = sport.name Log.d("MainActivity", "Selected Sport: $selectedSport") @@ -56,15 +142,5 @@ class MainActivity : AppCompatActivity() { } startActivity(intent) } - private fun getResourcesWithSuffix(suffix: String): List { - val resources = mutableListOf() - val fields = R.drawable::class.java.fields // You can change this to R.string, R.layout, etc. - for (field in fields) { - if (field.name.endsWith(suffix)) { - resources.add(field.name) - } - } - return resources - } } diff --git a/app/src/main/java/com/example/mycompanion/SportAdapter.kt b/app/src/main/java/com/example/mycompanion/SportAdapter.kt index c52cc4a..a406020 100644 --- a/app/src/main/java/com/example/mycompanion/SportAdapter.kt +++ b/app/src/main/java/com/example/mycompanion/SportAdapter.kt @@ -6,8 +6,10 @@ import android.view.ViewGroup import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -class SportAdapter(private val sports: List, private val onClick: (Sport) -> Unit) : - RecyclerView.Adapter() { +class SportAdapter( + private val sports: List, + private val clickListener: (Sport) -> Unit +) : RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SportViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_sport, parent, false) @@ -15,20 +17,19 @@ class SportAdapter(private val sports: List, private val onClick: (Sport) } override fun onBindViewHolder(holder: SportViewHolder, position: Int) { - holder.bind(sports[position]) + holder.bind(sports[position], clickListener) } override fun getItemCount(): Int = sports.size - inner class SportViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - private val emojiTextView: TextView = itemView.findViewById(R.id.emojiTextView) - private val nameTextView: TextView = itemView.findViewById(R.id.nameTextView) + class SportViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + private val sportName: TextView = itemView.findViewById(R.id.sport_name) + private val sportEmoji: TextView = itemView.findViewById(R.id.sport_emoji) - fun bind(sport: Sport) { - emojiTextView.text = sport.emoji - nameTextView.text = sport.name - itemView.tag = sport.tag - itemView.setOnClickListener { onClick(sport) } + fun bind(sport: Sport, clickListener: (Sport) -> Unit) { + sportName.text = sport.name + sportEmoji.text = sport.emoji + itemView.setOnClickListener { clickListener(sport) } } } } diff --git a/app/src/main/java/com/example/mycompanion/TimerActivity.kt b/app/src/main/java/com/example/mycompanion/TimerActivity.kt index a6e06fd..4ee52f3 100644 --- a/app/src/main/java/com/example/mycompanion/TimerActivity.kt +++ b/app/src/main/java/com/example/mycompanion/TimerActivity.kt @@ -1,5 +1,6 @@ package com.example.mycompanion +import android.content.Intent import android.os.Bundle import android.os.Handler import android.os.Looper @@ -58,7 +59,23 @@ class TimerActivity : AppCompatActivity() { stopButton.setOnClickListener { Log.d("TimerActivity", "Training stopped at ${timerTextView.text}") - finishAffinity() + running = false + handler.removeCallbacks(runnable) + val intent = Intent(this, MainActivity::class.java) + startActivity(intent) + finish() // Optional: Call this if you want to remove TimerActivity from the back stack + } + } + + override fun onPause() { + super.onPause() + handler.removeCallbacks(runnable) + } + + override fun onResume() { + super.onResume() + if (running) { + handler.post(runnable) } } } diff --git a/app/src/main/res/drawable/green_circle.xml b/app/src/main/res/drawable/green_circle.xml new file mode 100644 index 0000000..5a3e4e8 --- /dev/null +++ b/app/src/main/res/drawable/green_circle.xml @@ -0,0 +1,4 @@ + + + diff --git a/app/src/main/res/drawable/yellow_circle.xml b/app/src/main/res/drawable/yellow_circle.xml new file mode 100644 index 0000000..84435e1 --- /dev/null +++ b/app/src/main/res/drawable/yellow_circle.xml @@ -0,0 +1,4 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 8c35dce..0b90be0 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -3,7 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".MainActivity"> + tools:context=".MainActivity" + android:background="@color/colorBackground"> - + android:layout_marginBottom="16dp"> + + + + + + android:layout_gravity="center"/> diff --git a/app/src/main/res/layout/item_sport.xml b/app/src/main/res/layout/item_sport.xml index 0418113..1f11aae 100644 --- a/app/src/main/res/layout/item_sport.xml +++ b/app/src/main/res/layout/item_sport.xml @@ -1,22 +1,33 @@ + android:orientation="horizontal" + android:padding="8dp" + android:background="?attr/selectableItemBackground" + android:clickable="true" + android:focusable="true"> + android:fontFamily="sans-serif-medium"/> + android:textColor="?android:attr/textColorPrimary" + android:background="@color/buttonBackground" + android:textSize="18sp" + android:padding="8dp" + android:gravity="center" + android:fontFamily="sans-serif-medium"/> diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml new file mode 100644 index 0000000..b943e07 --- /dev/null +++ b/app/src/main/res/values-night/colors.xml @@ -0,0 +1,12 @@ + + #FF5722 + #E64A19 + #4CAF50 + #121212 + #FFFFFF + #B0B0B0 + #4CAF50 + #FFEB3B + #FF5722 + #FFFFFF + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f8c6127..ee68021 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -7,4 +7,15 @@ #FF018786 #FF000000 #FFFFFFFF + + #FF5722 + #E64A19 + #4CAF50 + #F5F5F5 + #212121 + #757575 + #4CAF50 + #FFEB3B + #FF5722 + #FFFFFF \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..2c9e637 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,12 @@ + + + + + +