Added SatPass class to get the full info of a pass for the recycler items. Still trying to figure out what the final app is going to look like. Sitting at home with a cold.

This commit is contained in:
Arty Bishop committed 2019-11-08 13:50:44 +01:00
1 parent b7291db0f9
commit a0f723e233
6 files changed
+100 -28

No files matched your search

+1
View File
@@ -46,6 +46,7 @@ dependencies {
implementation "androidx.navigation:navigation-ui-ktx:$navigation"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle"
implementation "androidx.work:work-runtime-ktx:$work"
implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-ktx:$room"
@@ -0,0 +1,5 @@
package com.rtbishop.lookingsat.repo
import com.github.amsacode.predict4java.SatPassTime
data class SatPass(val satName: String, val catNum: Int, val pass: SatPassTime)
@@ -5,12 +5,12 @@ import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.github.amsacode.predict4java.SatPassTime
import com.rtbishop.lookingsat.R
import com.rtbishop.lookingsat.repo.SatPass
import java.text.SimpleDateFormat
import java.util.*
class SatPassAdapter(private val satPassList: MutableList<SatPassTime>) :
class SatPassAdapter(private val satPassList: List<SatPass>) :
RecyclerView.Adapter<SatPassAdapter.ViewHolder>() {
override fun getItemCount(): Int {
@@ -27,16 +27,19 @@ class SatPassAdapter(private val satPassList: MutableList<SatPassTime>) :
val satPass = satPassList[position]
val satName = holder.itemView.findViewById<TextView>(R.id.card_sat_name)
val passVector = holder.itemView.findViewById<TextView>(R.id.card_pass_vector)
val maxEl = holder.itemView.findViewById<TextView>(R.id.card_max_el)
val passVector = holder.itemView.findViewById<TextView>(R.id.card_pass_vector)
val passStart = holder.itemView.findViewById<TextView>(R.id.card_pass_start)
val passEnd = holder.itemView.findViewById<TextView>(R.id.card_pass_end)
satName.text = String.format("%s", "Meteor M2-2")
passVector.text = String.format("V: %02d° -> %02d°", satPass.aosAzimuth, satPass.losAzimuth)
maxEl.text = String.format("%.1f°", satPass.maxEl)
passStart.text = SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(satPass.startTime)
passEnd.text = SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(satPass.endTime)
satName.text = String.format("%s", satPass.satName)
maxEl.text = String.format("%.1f°", satPass.pass.maxEl)
passVector.text =
String.format("V: %02d° -> %02d°", satPass.pass.aosAzimuth, satPass.pass.losAzimuth)
passStart.text =
SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(satPass.pass.startTime)
passEnd.text =
SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(satPass.pass.endTime)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
@@ -5,20 +5,31 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.ProgressBar
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.github.amsacode.predict4java.TLE
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.rtbishop.lookingsat.R
import com.rtbishop.lookingsat.repo.SatPass
import com.rtbishop.lookingsat.vm.MainViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class SkyFragment : Fragment() {
private lateinit var viewModel: MainViewModel
private lateinit var recView: RecyclerView
private lateinit var recAdapter: RecyclerView.Adapter<*>
private lateinit var recLayoutManager: RecyclerView.LayoutManager
private lateinit var btnRefresh: ImageButton
private lateinit var progressBar: ProgressBar
private lateinit var fab: FloatingActionButton
private var satPassList: List<SatPass> = emptyList()
override fun onCreateView(
inflater: LayoutInflater,
@@ -32,17 +43,25 @@ class SkyFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
btnRefresh = (activity as MainActivity).findViewById(R.id.toolbar_btn_refresh)
progressBar = view.findViewById(R.id.sky_progressbar)
recView = view.findViewById(R.id.sky_recycler)
fab = view.findViewById(R.id.sky_fab)
recView.layoutManager = LinearLayoutManager(activity)
recView.setHasFixedSize(true)
btnRefresh.setOnClickListener {
val satPassList = viewModel.updateRecycler()
recLayoutManager = LinearLayoutManager(activity)
recAdapter = SatPassAdapter(satPassList)
recView = view.findViewById(R.id.recycler_sky)
recView.setHasFixedSize(true)
recView.layoutManager = recLayoutManager
recView.adapter = recAdapter
lifecycleScope.launch(Dispatchers.Main) {
recView.visibility = View.INVISIBLE
progressBar.visibility = View.VISIBLE
progressBar.isIndeterminate = true
satPassList = viewModel.updateRecycler()
recAdapter = SatPassAdapter(satPassList)
recView.adapter = recAdapter
progressBar.isIndeterminate = false
progressBar.visibility = View.INVISIBLE
recView.visibility = View.VISIBLE
}
}
}
}
@@ -4,6 +4,7 @@ import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import android.location.Location
import android.util.Log
import androidx.core.content.edit
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
@@ -12,13 +13,15 @@ import androidx.lifecycle.viewModelScope
import androidx.preference.PreferenceManager
import com.github.amsacode.predict4java.GroundStationPosition
import com.github.amsacode.predict4java.PassPredictor
import com.github.amsacode.predict4java.SatPassTime
import com.github.amsacode.predict4java.SatNotFoundException
import com.github.amsacode.predict4java.TLE
import com.google.android.gms.location.LocationServices
import com.rtbishop.lookingsat.Injector
import com.rtbishop.lookingsat.repo.Repository
import com.rtbishop.lookingsat.repo.SatPass
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.FileNotFoundException
import java.io.IOException
import java.util.*
@@ -29,12 +32,15 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
private val keyLon = "LONGITUDE"
private val keyHeight = "HEIGHT"
private val tleFile = "tles.txt"
private val tag = "myTag"
private val repository: Repository = Injector.provideRepository(application)
private val preferences = PreferenceManager.getDefaultSharedPreferences(application)
private val fusedLocationClient = LocationServices.getFusedLocationProviderClient(application)
private val _debugMessage = MutableLiveData("")
val debugMessage: LiveData<String> = _debugMessage
private val _gsp = MutableLiveData<GroundStationPosition>(
GroundStationPosition(
preferences.getDouble(keyLat, 0.0),
@@ -44,17 +50,41 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
)
val gsp: LiveData<GroundStationPosition> = _gsp
fun updateRecycler(): MutableList<SatPassTime> {
var satPassList = mutableListOf<SatPassTime>()
try {
val tles = TLE.importSat(getApplication<Application>().openFileInput(tleFile))
var tleList: List<TLE> = loadTwoLineElementFile().sortedWith(compareBy { it.name })
val passPredictor = PassPredictor(tles[0], _gsp.value)
satPassList = passPredictor.getPasses(Date(), 6, false)
private fun loadTwoLineElementFile(): List<TLE> {
return try {
TLE.importSat(getApplication<Application>().openFileInput(tleFile))
} catch (exception: FileNotFoundException) {
_debugMessage.postValue("TLE file wasn't found")
emptyList()
}
return satPassList
}
suspend fun updateRecycler(): List<SatPass> {
val satPassList = mutableListOf<SatPass>()
var sortedList = listOf<SatPass>()
withContext(Dispatchers.Default) {
for (tle in tleList.subList(0, 1)) {
try {
Log.d(tag, "Trying ${tle.name}")
val passPredictor = PassPredictor(tle, gsp.value)
val passes = passPredictor.getPasses(Date(), 6, false)
for (pass in passes) {
Log.d(tag, "Trying ${pass.maxEl}")
satPassList.add(SatPass(tle.name, tle.catnum, pass))
}
} catch (exception: IllegalArgumentException) {
val tleProblem = "There was a problem with TLE"
Log.d(tag, tleProblem)
_debugMessage.postValue(tleProblem)
} catch (exception: SatNotFoundException) {
Log.d(tag, "Certain satellites shall not pass")
}
}
sortedList = satPassList.sortedWith(compareBy { it.pass.startTime })
}
return sortedList
}
fun updateLocation() {
@@ -77,9 +107,11 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
fun updateTwoLineElementFile() {
viewModelScope.launch(Dispatchers.IO) {
try {
val stream = repository.fetchTleStream()
getApplication<Application>().openFileOutput(tleFile, Context.MODE_PRIVATE).use {
it.write(repository.fetchTleStream().readBytes())
it.write(stream.readBytes())
}
tleList = TLE.importSat(stream)
_debugMessage.postValue("TLE file was updated")
} catch (exception: IOException) {
_debugMessage.postValue("Couldn't update TLE file")
+13 -1
View File
@@ -6,10 +6,22 @@
android:layout_height="match_parent"
tools:context=".ui.SkyFragment">
<ProgressBar
android:id="@+id/sky_progressbar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/sky_recycler"
app:layout_constraintEnd_toEndOf="@+id/sky_recycler"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_sky"
android:id="@+id/sky_recycler"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"