mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Added pass preferences dialog. Pass prefs are stored in sharedPrefs.
This commit is contained in:
1 parent
cc53847374
commit
0f5b734933
6 files changed
+119
-14
No files matched your search
@@ -18,6 +18,7 @@ import com.github.amsacode.predict4java.TLE
|
|||||||
import com.google.android.gms.location.LocationServices
|
import com.google.android.gms.location.LocationServices
|
||||||
import com.rtbishop.lookingsat.repo.Repository
|
import com.rtbishop.lookingsat.repo.Repository
|
||||||
import com.rtbishop.lookingsat.repo.SatPass
|
import com.rtbishop.lookingsat.repo.SatPass
|
||||||
|
import com.rtbishop.lookingsat.repo.SatPassPrefs
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@@ -43,6 +44,14 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
private val _debugMessage = MutableLiveData("")
|
private val _debugMessage = MutableLiveData("")
|
||||||
val debugMessage: LiveData<String> = _debugMessage
|
val debugMessage: LiveData<String> = _debugMessage
|
||||||
|
|
||||||
|
private val _satPassPrefs = MutableLiveData<SatPassPrefs>(
|
||||||
|
SatPassPrefs(
|
||||||
|
preferences.getInt("hoursAhead", 8),
|
||||||
|
preferences.getDouble("maxEl", 20.0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val satPassPrefs: LiveData<SatPassPrefs> = _satPassPrefs
|
||||||
|
|
||||||
private val _gsp = MutableLiveData<GroundStationPosition>(
|
private val _gsp = MutableLiveData<GroundStationPosition>(
|
||||||
GroundStationPosition(
|
GroundStationPosition(
|
||||||
preferences.getDouble(keyLat, 0.0),
|
preferences.getDouble(keyLat, 0.0),
|
||||||
@@ -71,13 +80,14 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
suspend fun getPassesForSelectedSatellites(): List<SatPass> {
|
suspend fun getPassesForSelectedSatellites(): List<SatPass> {
|
||||||
val satPassList = mutableListOf<SatPass>()
|
val satPassList = mutableListOf<SatPass>()
|
||||||
var sortedList = listOf<SatPass>()
|
var sortedList = listOf<SatPass>()
|
||||||
|
val hoursAhead = satPassPrefs.value?.hoursAhead ?: 8
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
for ((tle, value) in tleSelectedMap) {
|
for ((tle, value) in tleSelectedMap) {
|
||||||
if (value) {
|
if (value) {
|
||||||
try {
|
try {
|
||||||
Log.d(tag, "Trying ${tle.name}")
|
Log.d(tag, "Trying ${tle.name}")
|
||||||
val passPredictor = PassPredictor(tle, gsp.value)
|
val passPredictor = PassPredictor(tle, gsp.value)
|
||||||
val passes = passPredictor.getPasses(Date(), 6, false)
|
val passes = passPredictor.getPasses(Date(), hoursAhead, false)
|
||||||
for (pass in passes) {
|
for (pass in passes) {
|
||||||
Log.d(tag, "Trying ${pass.maxEl}")
|
Log.d(tag, "Trying ${pass.maxEl}")
|
||||||
satPassList.add(SatPass(tle.name, tle.catnum, pass))
|
satPassList.add(SatPass(tle.name, tle.catnum, pass))
|
||||||
@@ -96,6 +106,15 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
return sortedList
|
return sortedList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updatePassPrefs(hoursAhead: Int, maxEl: Double) {
|
||||||
|
_satPassPrefs.postValue(SatPassPrefs(hoursAhead, maxEl))
|
||||||
|
preferences.edit {
|
||||||
|
putInt("hoursAhead", hoursAhead)
|
||||||
|
putDouble("maxEl", maxEl)
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun updateLocation() {
|
fun updateLocation() {
|
||||||
fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
|
fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? ->
|
||||||
val lat = location?.latitude ?: 0.0
|
val lat = location?.latitude ?: 0.0
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package com.rtbishop.lookingsat.repo
|
||||||
|
|
||||||
|
data class SatPassPrefs(val hoursAhead: Int, val maxEl: Double)
|
||||||
@@ -35,7 +35,7 @@ class SatPassAdapter(private val satPassList: List<SatPass>) :
|
|||||||
satName.text = String.format("%s", satPass.satName)
|
satName.text = String.format("%s", satPass.satName)
|
||||||
maxEl.text = String.format("%.1f°", satPass.pass.maxEl)
|
maxEl.text = String.format("%.1f°", satPass.pass.maxEl)
|
||||||
passVector.text =
|
passVector.text =
|
||||||
String.format("V: %02d° -> %02d°", satPass.pass.aosAzimuth, satPass.pass.losAzimuth)
|
String.format("V: %2d° -> %2d°", satPass.pass.aosAzimuth, satPass.pass.losAzimuth)
|
||||||
passStart.text =
|
passStart.text =
|
||||||
SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(satPass.pass.startTime)
|
SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(satPass.pass.startTime)
|
||||||
passEnd.text =
|
passEnd.text =
|
||||||
|
|||||||
@@ -5,10 +5,7 @@ import android.os.CountDownTimer
|
|||||||
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 android.widget.ImageButton
|
import android.widget.*
|
||||||
import android.widget.ProgressBar
|
|
||||||
import android.widget.TextView
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
@@ -55,11 +52,35 @@ class SkyFragment : Fragment() {
|
|||||||
|
|
||||||
recViewFuture.layoutManager = LinearLayoutManager(activity)
|
recViewFuture.layoutManager = LinearLayoutManager(activity)
|
||||||
|
|
||||||
|
btnPassPrefs.setOnClickListener { showSatPassPrefsDialog() }
|
||||||
fab.setOnClickListener { showSelectSatDialog() }
|
fab.setOnClickListener { showSelectSatDialog() }
|
||||||
|
|
||||||
resetTimer()
|
resetTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showSatPassPrefsDialog() {
|
||||||
|
val context = activity as MainActivity
|
||||||
|
val satPassPrefView = View.inflate(context, R.layout.sat_pass_pref, null)
|
||||||
|
val etHours = satPassPrefView.findViewById<EditText>(R.id.pass_pref_et_hours)
|
||||||
|
val etMaxEl = satPassPrefView.findViewById<EditText>(R.id.pass_pref_et_maxEl)
|
||||||
|
etHours.setText(viewModel.satPassPrefs.value?.hoursAhead.toString())
|
||||||
|
etMaxEl.setText(viewModel.satPassPrefs.value?.maxEl.toString())
|
||||||
|
|
||||||
|
val builder = AlertDialog.Builder(context)
|
||||||
|
builder.setTitle(getString(R.string.title_pass_pref))
|
||||||
|
.setPositiveButton(getString(R.string.btn_ok)) { _, _ ->
|
||||||
|
val hoursAhead = etHours.text.toString().toInt()
|
||||||
|
val maxEl = etMaxEl.text.toString().toDouble()
|
||||||
|
viewModel.updatePassPrefs(hoursAhead, maxEl)
|
||||||
|
}
|
||||||
|
.setNegativeButton(getString(R.string.btn_cancel)) { dialog, _ ->
|
||||||
|
dialog.cancel()
|
||||||
|
}
|
||||||
|
.setView(satPassPrefView)
|
||||||
|
.create()
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
private fun showSelectSatDialog() {
|
private fun showSelectSatDialog() {
|
||||||
val tleSelectedMap = viewModel.tleSelectedMap
|
val tleSelectedMap = viewModel.tleSelectedMap
|
||||||
val tleMainListSize = viewModel.tleMainList.size
|
val tleMainListSize = viewModel.tleMainList.size
|
||||||
@@ -81,23 +102,23 @@ class SkyFragment : Fragment() {
|
|||||||
|
|
||||||
val selectionMap = mutableMapOf<TLE, Boolean>()
|
val selectionMap = mutableMapOf<TLE, Boolean>()
|
||||||
val builder = AlertDialog.Builder(activity as MainActivity)
|
val builder = AlertDialog.Builder(activity as MainActivity)
|
||||||
builder.setTitle("Select satellites to track")
|
builder.setTitle(getString(R.string.title_select_sat))
|
||||||
.setMultiChoiceItems(tleNameArray, tleCheckedArray) { _, which, isChecked ->
|
.setMultiChoiceItems(tleNameArray, tleCheckedArray) { _, which, isChecked ->
|
||||||
selectionMap[viewModel.tleMainList[which]] = isChecked
|
selectionMap[viewModel.tleMainList[which]] = isChecked
|
||||||
}
|
}
|
||||||
.setPositiveButton("Ok") { _, _ ->
|
.setPositiveButton(getString(R.string.btn_ok)) { _, _ ->
|
||||||
for ((tle, value) in selectionMap) {
|
for ((tle, value) in selectionMap) {
|
||||||
tleSelectedMap[tle] = value
|
tleSelectedMap[tle] = value
|
||||||
calculatePasses()
|
calculatePasses()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.setNeutralButton("Clear All") { _, _ ->
|
.setNegativeButton(getString(R.string.btn_cancel)) { dialog, _ ->
|
||||||
|
dialog.cancel()
|
||||||
|
}
|
||||||
|
.setNeutralButton(getString(R.string.btn_clear)) { _, _ ->
|
||||||
tleSelectedMap.clear()
|
tleSelectedMap.clear()
|
||||||
calculatePasses()
|
calculatePasses()
|
||||||
}
|
}
|
||||||
.setNegativeButton("Cancel") { dialog, _ ->
|
|
||||||
dialog.cancel()
|
|
||||||
}
|
|
||||||
.create()
|
.create()
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
@@ -134,7 +155,7 @@ class SkyFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onTick(millisUntilFinished: Long) {
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
timeToAos.text = String.format(
|
timeToAos.text = String.format(
|
||||||
"AOS -%02d:%02d:%02d",
|
getString(R.string.pattern_aos),
|
||||||
TimeUnit.MILLISECONDS.toHours(millisUntilFinished) % 60,
|
TimeUnit.MILLISECONDS.toHours(millisUntilFinished) % 60,
|
||||||
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
|
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
|
||||||
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60
|
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60
|
||||||
@@ -152,6 +173,6 @@ class SkyFragment : Fragment() {
|
|||||||
(aosTimer as CountDownTimer).cancel()
|
(aosTimer as CountDownTimer).cancel()
|
||||||
aosTimer = null
|
aosTimer = null
|
||||||
}
|
}
|
||||||
timeToAos.text = String.format("AOS -%02d:%02d:%02d", 0, 0, 0)
|
timeToAos.text = String.format(getString(R.string.pattern_aos), 0, 0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/pass_pref_root"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pass_pref_tv_hours"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/pass_pref_tv_hours"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/pass_pref_et_hours"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/pass_pref_hint_hours"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="number"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/pass_pref_tv_hours"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/pass_pref_tv_hours"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/pass_pref_tv_hours" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pass_pref_tv_maxEl"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/pass_pref_tv_maxEl"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/pass_pref_et_hours"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/pass_pref_et_hours"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/pass_pref_et_hours" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/pass_pref_et_maxEl"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/pass_pref_hint_maxEl"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="number"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/pass_pref_tv_maxEl"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/pass_pref_tv_maxEl"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/pass_pref_tv_maxEl" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -29,6 +29,19 @@
|
|||||||
<string name="card_pass_aos_time">13:14:15</string>
|
<string name="card_pass_aos_time">13:14:15</string>
|
||||||
<string name="card_pass_los_time">16:17:18</string>
|
<string name="card_pass_los_time">16:17:18</string>
|
||||||
|
|
||||||
|
<string name="btn_ok">OK</string>
|
||||||
|
<string name="btn_cancel">Cancel</string>
|
||||||
|
<string name="btn_clear">Clear All</string>
|
||||||
|
|
||||||
|
<string name="title_pass_pref">Passes preferences</string>
|
||||||
|
<string name="title_select_sat">Select satellites to track</string>
|
||||||
|
|
||||||
|
<string name="pass_pref_tv_hours">Show passes that occur within X hours</string>
|
||||||
|
<string name="pass_pref_hint_hours">Hours ahead</string>
|
||||||
|
<string name="pass_pref_tv_maxEl">Show passes with max elevation above</string>
|
||||||
|
<string name="pass_pref_hint_maxEl">Max elevation</string>
|
||||||
|
|
||||||
|
<string name="pattern_aos">AOS -%02d:%02d:%02d</string>
|
||||||
<string name="map_content">Nasa Map</string>
|
<string name="map_content">Nasa Map</string>
|
||||||
<string name="placeholder">Placeholder</string>
|
<string name="placeholder">Placeholder</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in new issue
Block a user