mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Implemented satellite selection save and load between app launches. Some code move and cleanup.
This commit is contained in:
1 parent
928ccd4991
commit
4d3930db89
3 files changed
+88
-77
No files matched your search
@@ -27,7 +27,6 @@ import java.io.ObjectOutputStream
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
class MainViewModel(application: Application) : AndroidViewModel(application) {
|
class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
|
|
||||||
private val defValueLoc = application.getString(R.string.def_gsp_loc)
|
private val defValueLoc = application.getString(R.string.def_gsp_loc)
|
||||||
@@ -38,7 +37,8 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
private val keyAlt = application.getString(R.string.key_alt)
|
private val keyAlt = application.getString(R.string.key_alt)
|
||||||
private val keyHours = application.getString(R.string.key_hours_ahead)
|
private val keyHours = application.getString(R.string.key_hours_ahead)
|
||||||
private val keyMinEl = application.getString(R.string.key_min_el)
|
private val keyMinEl = application.getString(R.string.key_min_el)
|
||||||
private val tleFileName = application.getString(R.string.tle_file_name)
|
private val tleMainListFileName = application.getString(R.string.tle_main_list_file_name)
|
||||||
|
private val tleSelectionFileName = application.getString(R.string.tle_selection_file_name)
|
||||||
private val app = application
|
private val app = application
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -52,6 +52,10 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
(app as LookingSatApp).appComponent.inject(this)
|
(app as LookingSatApp).appComponent.inject(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var passPrefs = SatPassPrefs(
|
||||||
|
preferences.getString(keyHours, defValueHours)!!.toInt(),
|
||||||
|
preferences.getString(keyMinEl, defValueMinEl)!!.toDouble()
|
||||||
|
)
|
||||||
val debugMessage = MutableLiveData("")
|
val debugMessage = MutableLiveData("")
|
||||||
val gsp = MutableLiveData<GroundStationPosition>(
|
val gsp = MutableLiveData<GroundStationPosition>(
|
||||||
GroundStationPosition(
|
GroundStationPosition(
|
||||||
@@ -60,54 +64,9 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
preferences.getString(keyAlt, defValueLoc)!!.toDouble()
|
preferences.getString(keyAlt, defValueLoc)!!.toDouble()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
var satPassList = emptyList<SatPass>()
|
var satPassList = emptyList<SatPass>()
|
||||||
var tleMainList = loadTwoLineElementFile()
|
var tleMainList = loadTwoLineElementFile()
|
||||||
var tleSelectedMap = mutableMapOf<TLE, Boolean>()
|
var selectionList = loadSelectionList()
|
||||||
var passPrefs = SatPassPrefs(
|
|
||||||
preferences.getString(keyHours, defValueHours)!!.toInt(),
|
|
||||||
preferences.getString(keyMinEl, defValueMinEl)!!.toDouble()
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun loadTwoLineElementFile(): List<TLE> {
|
|
||||||
try {
|
|
||||||
val fileInput = app.openFileInput(tleFileName)
|
|
||||||
val objectInput = ObjectInputStream(fileInput)
|
|
||||||
val tleList = objectInput.readObject()
|
|
||||||
return tleList as List<TLE>
|
|
||||||
} catch (e: FileNotFoundException) {
|
|
||||||
debugMessage.postValue("TLE file wasn't found")
|
|
||||||
} catch (e: IOException) {
|
|
||||||
debugMessage.postValue(e.toString())
|
|
||||||
}
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getPasses() {
|
|
||||||
val passList = mutableListOf<SatPass>()
|
|
||||||
withContext(Dispatchers.Default) {
|
|
||||||
tleSelectedMap.forEach { (tle, value) ->
|
|
||||||
if (value) {
|
|
||||||
try {
|
|
||||||
val predictor = PassPredictor(tle, gsp.value)
|
|
||||||
val passes = predictor.getPasses(Date(), passPrefs.hoursAhead, true)
|
|
||||||
passes.forEach { passList.add(SatPass(tle, predictor, it)) }
|
|
||||||
} catch (exception: IllegalArgumentException) {
|
|
||||||
debugMessage.postValue("There was a problem with ${tle.name}")
|
|
||||||
} catch (exception: SatNotFoundException) {
|
|
||||||
debugMessage.postValue("${tle.name} shall not pass")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
passList.retainAll { it.pass.maxEl >= passPrefs.maxEl }
|
|
||||||
passList.sortBy { it.pass.startTime }
|
|
||||||
}
|
|
||||||
satPassList = passList
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateSelectedSatMap(mutableMap: MutableMap<TLE, Boolean>) {
|
|
||||||
tleSelectedMap = mutableMap
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateGsp() {
|
fun updateGsp() {
|
||||||
val lat = preferences.getString(keyLat, defValueLoc)!!.toDouble()
|
val lat = preferences.getString(keyLat, defValueLoc)!!.toDouble()
|
||||||
@@ -145,7 +104,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
try {
|
try {
|
||||||
val inputStream = repository.fetchTleStream()
|
val inputStream = repository.fetchTleStream()
|
||||||
val tleList = TLE.importSat(inputStream).apply { sortBy { it.name } }
|
val tleList = TLE.importSat(inputStream).apply { sortBy { it.name } }
|
||||||
val fileOutStream = app.openFileOutput(tleFileName, Context.MODE_PRIVATE)
|
val fileOutStream = app.openFileOutput(tleMainListFileName, Context.MODE_PRIVATE)
|
||||||
ObjectOutputStream(fileOutStream).apply {
|
ObjectOutputStream(fileOutStream).apply {
|
||||||
writeObject(tleList)
|
writeObject(tleList)
|
||||||
flush()
|
flush()
|
||||||
@@ -170,7 +129,70 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateAndSaveSelectionList(list: MutableList<Int>) {
|
||||||
|
selectionList = list
|
||||||
|
try {
|
||||||
|
val fileOutputStream = app.openFileOutput(tleSelectionFileName, Context.MODE_PRIVATE)
|
||||||
|
ObjectOutputStream(fileOutputStream).apply {
|
||||||
|
writeObject(list)
|
||||||
|
flush()
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
} catch (exception: IOException) {
|
||||||
|
debugMessage.postValue(exception.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getPasses() {
|
||||||
|
val passList = mutableListOf<SatPass>()
|
||||||
|
withContext(Dispatchers.Default) {
|
||||||
|
selectionList.forEach { indexOfSelection ->
|
||||||
|
val tle = tleMainList[indexOfSelection]
|
||||||
|
try {
|
||||||
|
val predictor = PassPredictor(tle, gsp.value)
|
||||||
|
val passes = predictor.getPasses(Date(), passPrefs.hoursAhead, true)
|
||||||
|
passes.forEach { passList.add(SatPass(tle, predictor, it)) }
|
||||||
|
} catch (exception: IllegalArgumentException) {
|
||||||
|
debugMessage.postValue("There was a problem with ${tle.name}")
|
||||||
|
} catch (exception: SatNotFoundException) {
|
||||||
|
debugMessage.postValue("${tle.name} shall not pass")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
passList.retainAll { it.pass.maxEl >= passPrefs.maxEl }
|
||||||
|
passList.sortBy { it.pass.startTime }
|
||||||
|
}
|
||||||
|
satPassList = passList
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun getTransmittersForSat(id: Int): List<Transmitter> {
|
suspend fun getTransmittersForSat(id: Int): List<Transmitter> {
|
||||||
return repository.getTransmittersForSat(id)
|
return repository.getTransmittersForSat(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private fun loadTwoLineElementFile(): List<TLE> {
|
||||||
|
try {
|
||||||
|
val fileInputStream = app.openFileInput(tleMainListFileName)
|
||||||
|
val tleList = ObjectInputStream(fileInputStream).readObject()
|
||||||
|
return tleList as List<TLE>
|
||||||
|
} catch (exception: FileNotFoundException) {
|
||||||
|
debugMessage.postValue("TLE file wasn't found")
|
||||||
|
} catch (exception: IOException) {
|
||||||
|
debugMessage.postValue(exception.toString())
|
||||||
|
}
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private fun loadSelectionList(): MutableList<Int> {
|
||||||
|
try {
|
||||||
|
val fileInputStream = app.openFileInput(tleSelectionFileName)
|
||||||
|
val selectionList = ObjectInputStream(fileInputStream).readObject()
|
||||||
|
return selectionList as MutableList<Int>
|
||||||
|
} catch (exception: FileNotFoundException) {
|
||||||
|
debugMessage.postValue("Selection file wasn't found")
|
||||||
|
} catch (exception: IOException) {
|
||||||
|
debugMessage.postValue(exception.toString())
|
||||||
|
}
|
||||||
|
return mutableListOf()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -75,46 +75,34 @@ class SkyFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
btnRefresh.setOnClickListener { calculatePasses() }
|
btnRefresh.setOnClickListener { calculatePasses() }
|
||||||
fab.setOnClickListener { showSelectSatDialog() }
|
fab.setOnClickListener {
|
||||||
|
showSelectSatDialog(viewModel.tleMainList, viewModel.selectionList)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showSelectSatDialog() {
|
private fun showSelectSatDialog(tleMainList: List<TLE>, selectionList: MutableList<Int>) {
|
||||||
val tleMainList = viewModel.tleMainList
|
val tleNameArray = arrayOfNulls<String>(tleMainList.size).apply {
|
||||||
val tleNameArray = arrayOfNulls<String>(tleMainList.size)
|
tleMainList.withIndex().forEach { (position, tle) -> this[position] = tle.name }
|
||||||
val tleCheckedArray = BooleanArray(tleMainList.size)
|
}
|
||||||
val selectedSatMap = viewModel.tleSelectedMap
|
val tleCheckedArray = BooleanArray(tleMainList.size).apply {
|
||||||
val currentSelectionMap = mutableMapOf<TLE, Boolean>()
|
selectionList.forEach { this[it] = true }
|
||||||
|
|
||||||
if (selectedSatMap.isEmpty()) {
|
|
||||||
tleMainList.withIndex().forEach { (position, tle) ->
|
|
||||||
tleNameArray[position] = tle.name
|
|
||||||
tleCheckedArray[position] = false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tleMainList.withIndex().forEach { (position, tle) ->
|
|
||||||
tleNameArray[position] = tle.name
|
|
||||||
tleCheckedArray[position] = selectedSatMap.getOrDefault(tle, false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val builder = AlertDialog.Builder(activity as MainActivity)
|
val builder = AlertDialog.Builder(activity as MainActivity)
|
||||||
builder.setTitle(getString(R.string.title_select_sat))
|
builder.setTitle(getString(R.string.title_select_sat))
|
||||||
.setMultiChoiceItems(tleNameArray, tleCheckedArray) { _, which, isChecked ->
|
.setMultiChoiceItems(tleNameArray, tleCheckedArray) { _, which, isChecked ->
|
||||||
currentSelectionMap[tleMainList[which]] = isChecked
|
if (isChecked) selectionList.add(which)
|
||||||
|
else if (selectionList.contains(which)) selectionList.remove(which)
|
||||||
}
|
}
|
||||||
.setPositiveButton(getString(R.string.btn_ok)) { _, _ ->
|
.setPositiveButton(getString(R.string.btn_ok)) { _, _ ->
|
||||||
for ((tle, value) in currentSelectionMap) {
|
viewModel.updateAndSaveSelectionList(selectionList)
|
||||||
selectedSatMap[tle] = value
|
calculatePasses()
|
||||||
viewModel.updateSelectedSatMap(selectedSatMap)
|
|
||||||
calculatePasses()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.setNegativeButton(getString(R.string.btn_cancel)) { dialog, _ ->
|
.setNegativeButton(getString(R.string.btn_cancel)) { dialog, _ ->
|
||||||
dialog.cancel()
|
dialog.cancel()
|
||||||
}
|
}
|
||||||
.setNeutralButton(getString(R.string.btn_clear)) { _, _ ->
|
.setNeutralButton(getString(R.string.btn_clear)) { _, _ ->
|
||||||
selectedSatMap.clear()
|
selectionList.clear()
|
||||||
viewModel.updateSelectedSatMap(selectedSatMap)
|
viewModel.updateAndSaveSelectionList(selectionList)
|
||||||
calculatePasses()
|
calculatePasses()
|
||||||
}
|
}
|
||||||
.create()
|
.create()
|
||||||
|
|||||||
@@ -62,7 +62,8 @@
|
|||||||
<string name="key_hours_ahead">hours_ahead</string>
|
<string name="key_hours_ahead">hours_ahead</string>
|
||||||
<string name="key_min_el">min_elevation</string>
|
<string name="key_min_el">min_elevation</string>
|
||||||
<string name="key_update_freq">update_freq</string>
|
<string name="key_update_freq">update_freq</string>
|
||||||
<string name="tle_file_name">tleFile.txt</string>
|
<string name="tle_main_list_file_name">tleFile.txt</string>
|
||||||
|
<string name="tle_selection_file_name">tleSelection</string>
|
||||||
|
|
||||||
<string name="no">No</string>
|
<string name="no">No</string>
|
||||||
<string name="yes">Yes</string>
|
<string name="yes">Yes</string>
|
||||||
|
|||||||
Reference in new issue
Block a user