diff --git a/app/build.gradle b/app/build.gradle index 0121f553..49da233e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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" diff --git a/app/src/main/java/com/rtbishop/lookingsat/repo/SatPass.kt b/app/src/main/java/com/rtbishop/lookingsat/repo/SatPass.kt new file mode 100644 index 00000000..5bad66eb --- /dev/null +++ b/app/src/main/java/com/rtbishop/lookingsat/repo/SatPass.kt @@ -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) \ No newline at end of file diff --git a/app/src/main/java/com/rtbishop/lookingsat/ui/SatPassAdapter.kt b/app/src/main/java/com/rtbishop/lookingsat/ui/SatPassAdapter.kt index 105403ee..d6287a65 100644 --- a/app/src/main/java/com/rtbishop/lookingsat/ui/SatPassAdapter.kt +++ b/app/src/main/java/com/rtbishop/lookingsat/ui/SatPassAdapter.kt @@ -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) : +class SatPassAdapter(private val satPassList: List) : RecyclerView.Adapter() { override fun getItemCount(): Int { @@ -27,16 +27,19 @@ class SatPassAdapter(private val satPassList: MutableList) : val satPass = satPassList[position] val satName = holder.itemView.findViewById(R.id.card_sat_name) - val passVector = holder.itemView.findViewById(R.id.card_pass_vector) val maxEl = holder.itemView.findViewById(R.id.card_max_el) + val passVector = holder.itemView.findViewById(R.id.card_pass_vector) val passStart = holder.itemView.findViewById(R.id.card_pass_start) val passEnd = holder.itemView.findViewById(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), diff --git a/app/src/main/java/com/rtbishop/lookingsat/ui/SkyFragment.kt b/app/src/main/java/com/rtbishop/lookingsat/ui/SkyFragment.kt index 13f4f012..a7f9c44d 100644 --- a/app/src/main/java/com/rtbishop/lookingsat/ui/SkyFragment.kt +++ b/app/src/main/java/com/rtbishop/lookingsat/ui/SkyFragment.kt @@ -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 = 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 + } } } } \ No newline at end of file diff --git a/app/src/main/java/com/rtbishop/lookingsat/vm/MainViewModel.kt b/app/src/main/java/com/rtbishop/lookingsat/vm/MainViewModel.kt index 024b0bf7..cde6e41e 100644 --- a/app/src/main/java/com/rtbishop/lookingsat/vm/MainViewModel.kt +++ b/app/src/main/java/com/rtbishop/lookingsat/vm/MainViewModel.kt @@ -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 = _debugMessage + private val _gsp = MutableLiveData( GroundStationPosition( preferences.getDouble(keyLat, 0.0), @@ -44,17 +50,41 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { ) val gsp: LiveData = _gsp - fun updateRecycler(): MutableList { - var satPassList = mutableListOf() - try { - val tles = TLE.importSat(getApplication().openFileInput(tleFile)) + var tleList: List = loadTwoLineElementFile().sortedWith(compareBy { it.name }) - val passPredictor = PassPredictor(tles[0], _gsp.value) - satPassList = passPredictor.getPasses(Date(), 6, false) + private fun loadTwoLineElementFile(): List { + return try { + TLE.importSat(getApplication().openFileInput(tleFile)) } catch (exception: FileNotFoundException) { _debugMessage.postValue("TLE file wasn't found") + emptyList() } - return satPassList + } + + suspend fun updateRecycler(): List { + val satPassList = mutableListOf() + var sortedList = listOf() + 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().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") diff --git a/app/src/main/res/layout/fragment_sky.xml b/app/src/main/res/layout/fragment_sky.xml index cd2eae29..5c8cbba8 100644 --- a/app/src/main/res/layout/fragment_sky.xml +++ b/app/src/main/res/layout/fragment_sky.xml @@ -6,10 +6,22 @@ android:layout_height="match_parent" tools:context=".ui.SkyFragment"> + +