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