diff --git a/app/src/main/java/com/rtbishop/look4sat/ui/adapters/TransAdapter.kt b/app/src/main/java/com/rtbishop/look4sat/ui/adapters/TransAdapter.kt index 6bdfed5c..e53ecc61 100644 --- a/app/src/main/java/com/rtbishop/look4sat/ui/adapters/TransAdapter.kt +++ b/app/src/main/java/com/rtbishop/look4sat/ui/adapters/TransAdapter.kt @@ -30,17 +30,25 @@ import com.rtbishop.look4sat.databinding.ItemTransBinding import com.rtbishop.look4sat.utility.PassPredictor import java.util.* -class TransAdapter : RecyclerView.Adapter() { +class TransAdapter(context: Context) : RecyclerView.Adapter() { - private var transmittersList = emptyList() private lateinit var predictor: PassPredictor + private val divider = 1000000f + private val strNo = context.getString(R.string.btn_no) + private val strYes = context.getString(R.string.btn_yes) + private val mode = context.getString(R.string.trans_mode) + private val formatLink = context.getString(R.string.trans_down_low_doppler) + private val formatLinkNull = context.getString(R.string.no_downlink_doppler) + private val isInverted = context.getString(R.string.trans_inverted) + private var transmittersList = emptyList() - fun setPredictor(predict: PassPredictor) { - predictor = predict + fun setPredictor(predictor: PassPredictor) { + this.predictor = predictor } fun setList(list: List) { transmittersList = list + notifyDataSetChanged() } override fun getItemCount(): Int { @@ -61,82 +69,24 @@ class TransAdapter : RecyclerView.Adapter() { RecyclerView.ViewHolder(itemView) { fun bind(satTrans: SatTrans) { - val context: Context = itemView.context - val freqDivider = 1000000f + val dateNow = Date() + binding.description.text = satTrans.description - binding.transDescription.text = satTrans.description + if (satTrans.downlinkLow != null) { + val downFreq = predictor.getDownlinkFreq(satTrans.downlinkLow, dateNow) / divider + binding.downlink.text = String.format(formatLink, downFreq) + } else binding.downlink.text = formatLinkNull - if (satTrans.downlinkLow != null && satTrans.downlinkHigh == null) { - binding.transDownlink.text = String - .format( - context.getString(R.string.trans_down_low), - satTrans.downlinkLow / freqDivider - ) - binding.transDownlinkDoppler.text = String - .format( - context.getString(R.string.trans_down_low_doppler), - predictor.getDownlinkFreq(satTrans.downlinkLow, Date()) / freqDivider - ) - } else if (satTrans.downlinkLow != null && satTrans.downlinkHigh != null) { - binding.transDownlink.text = String - .format( - context.getString(R.string.trans_down_lowHigh), - satTrans.downlinkLow / freqDivider, - satTrans.downlinkHigh / freqDivider - ) - binding.transDownlinkDoppler.text = String - .format( - context.getString(R.string.trans_down_lowHigh_doppler), - predictor.getDownlinkFreq(satTrans.downlinkLow, Date()) / freqDivider, - predictor.getDownlinkFreq(satTrans.downlinkHigh, Date()) / freqDivider - ) - } else { - binding.transDownlink.text = context.getString(R.string.no_downlink) - binding.transDownlinkDoppler.text = context.getString(R.string.no_downlink_doppler) - } + if (satTrans.uplinkLow != null) { + val upFreq = predictor.getUplinkFreq(satTrans.uplinkLow, dateNow) / divider + binding.uplink.text = String.format(formatLink, upFreq) + } else binding.uplink.text = formatLinkNull - if (satTrans.uplinkLow != null && satTrans.uplinkHigh == null) { - binding.transUplink.text = String.format( - context.getString(R.string.trans_up_low), - satTrans.uplinkLow / freqDivider - ) - binding.transUplinkDoppler.text = String.format( - context.getString(R.string.trans_up_low_doppler), - predictor.getUplinkFreq(satTrans.uplinkLow, Date()) / freqDivider - ) - } else if (satTrans.uplinkLow != null && satTrans.uplinkHigh != null) { - binding.transUplink.text = String.format( - context.getString(R.string.trans_up_lowHigh), - satTrans.uplinkLow / freqDivider, - satTrans.uplinkHigh / freqDivider - ) - binding.transUplinkDoppler.text = String.format( - context.getString(R.string.trans_up_lowHigh_doppler), - predictor.getUplinkFreq(satTrans.uplinkLow, Date()) / freqDivider, - predictor.getUplinkFreq(satTrans.uplinkHigh, Date()) / freqDivider - ) - } else { - binding.transUplink.text = context.getString(R.string.no_uplink) - binding.transUplinkDoppler.text = context.getString(R.string.no_uplink_doppler) - } + if (satTrans.mode != null) binding.mode.text = String.format(mode, satTrans.mode) + else binding.mode.text = String.format(mode, strNo) - if (satTrans.mode != null) { - binding.transMode.text = - String.format(context.getString(R.string.trans_mode), satTrans.mode) - } else { - binding.transMode.text = context.getString(R.string.no_mode) - } - if (satTrans.isInverted) { - binding.transInverted.text = String.format( - context.getString(R.string.trans_inverted), - context.getString(R.string.btn_yes) - ) - } else { - binding.transInverted.text = String.format( - context.getString(R.string.trans_inverted), - context.getString(R.string.btn_no) - ) - } + if (satTrans.isInverted) binding.isInverted.text = String.format(isInverted, strYes) + else binding.isInverted.text = String.format(isInverted, strNo) } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/ui/fragments/PolarFragment.kt b/app/src/main/java/com/rtbishop/look4sat/ui/fragments/PolarFragment.kt index 43ee944a..0135db6f 100644 --- a/app/src/main/java/com/rtbishop/look4sat/ui/fragments/PolarFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/ui/fragments/PolarFragment.kt @@ -24,9 +24,7 @@ import android.hardware.* import android.os.Bundle import android.view.View import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentActivity import androidx.fragment.app.activityViewModels -import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.navArgs import androidx.recyclerview.widget.LinearLayoutManager import com.rtbishop.look4sat.R @@ -37,9 +35,8 @@ import com.rtbishop.look4sat.databinding.FragmentPolarBinding import com.rtbishop.look4sat.ui.adapters.TransAdapter import com.rtbishop.look4sat.ui.views.PolarView import com.rtbishop.look4sat.utility.PrefsManager +import com.rtbishop.look4sat.utility.RecyclerDivider import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch import java.util.* import javax.inject.Inject import kotlin.math.round @@ -50,24 +47,26 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener { @Inject lateinit var prefsManager: PrefsManager - private lateinit var mainActivity: FragmentActivity + private lateinit var transmitterAdapter: TransAdapter private lateinit var binding: FragmentPolarBinding private lateinit var satPass: SatPass private lateinit var sensorManager: SensorManager private val viewModel: SharedViewModel by activityViewModels() private val args: PolarFragmentArgs by navArgs() - private val transmitterAdapter = TransAdapter() private var magneticDeclination = 0f private var polarView: PolarView? = null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - mainActivity = requireActivity() binding = FragmentPolarBinding.bind(view) - sensorManager = mainActivity.getSystemService(Context.SENSOR_SERVICE) as SensorManager + sensorManager = requireContext().getSystemService(Context.SENSOR_SERVICE) as SensorManager + transmitterAdapter = TransAdapter(requireContext()) binding.recycler.apply { - layoutManager = LinearLayoutManager(mainActivity) + setHasFixedSize(true) adapter = transmitterAdapter + isVerticalScrollBarEnabled = false + layoutManager = LinearLayoutManager(context) + addItemDecoration(RecyclerDivider(R.drawable.rec_divider_dark)) } calculateMagneticDeclination() observePasses() @@ -109,20 +108,26 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener { viewModel.getPasses().observe(viewLifecycleOwner, { result -> if (result is Result.Success) { satPass = result.data[args.satPassIndex] - polarView = PolarView(mainActivity, satPass) + polarView = PolarView(requireContext(), satPass) binding.frame.addView(polarView) + observeTimer() observeTransmitters() - refreshText() } }) } + private fun observeTimer() { + viewModel.getCurrentTimeMillis().observe(viewLifecycleOwner, { + transmitterAdapter.notifyDataSetChanged() + setPassText(Date(it)) + }) + } + private fun observeTransmitters() { viewModel.getTransmittersForSat(satPass.tle.catnum).observe(viewLifecycleOwner, { if (it.isNotEmpty()) { transmitterAdapter.setPredictor(satPass.predictor) transmitterAdapter.setList(it) - transmitterAdapter.notifyDataSetChanged() binding.recycler.visibility = View.VISIBLE binding.noTransMsg.visibility = View.INVISIBLE } else { @@ -133,33 +138,22 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener { } private fun calculateMagneticDeclination() { - val position = prefsManager.getStationPosition() - val geoField = GeomagneticField( - position.latitude.toFloat(), - position.longitude.toFloat(), - position.heightAMSL.toFloat(), - System.currentTimeMillis() - ) - magneticDeclination = geoField.declination - } - - private fun refreshText() { - lifecycleScope.launch { - while (true) { - setPassText() - polarView?.invalidate() - transmitterAdapter.notifyDataSetChanged() - delay(3000) - } + prefsManager.getStationPosition().let { + magneticDeclination = GeomagneticField( + it.latitude.toFloat(), + it.longitude.toFloat(), + it.heightAMSL.toFloat(), + System.currentTimeMillis() + ).declination } } - private fun setPassText() { - val satPos = satPass.predictor.getSatPos(Date()) - val polarAz = mainActivity.getString(R.string.pat_azimuth) - val polarEl = mainActivity.getString(R.string.pat_elevation) - val polarRng = mainActivity.getString(R.string.pat_distance) - val polarAlt = mainActivity.getString(R.string.pat_altitude) + private fun setPassText(date: Date) { + val satPos = satPass.predictor.getSatPos(date) + val polarAz = getString(R.string.pat_azimuth) + val polarEl = getString(R.string.pat_elevation) + val polarRng = getString(R.string.pat_distance) + val polarAlt = getString(R.string.pat_altitude) binding.azimuth.text = String.format(polarAz, Math.toDegrees(satPos.azimuth)) binding.elevation.text = String.format(polarEl, Math.toDegrees(satPos.elevation)) binding.distance.text = String.format(polarRng, satPos.range) diff --git a/app/src/main/java/com/rtbishop/look4sat/ui/views/PolarView.kt b/app/src/main/java/com/rtbishop/look4sat/ui/views/PolarView.kt index a770a901..53e71274 100644 --- a/app/src/main/java/com/rtbishop/look4sat/ui/views/PolarView.kt +++ b/app/src/main/java/com/rtbishop/look4sat/ui/views/PolarView.kt @@ -22,16 +22,16 @@ class PolarView(context: Context) : View(context) { private val polarWidth = resources.displayMetrics.widthPixels private val polarCenter = polarWidth / 2f private val scale = resources.displayMetrics.density - private val radius = polarWidth * 0.49f - private val txtSize = scale * 15 + private val radius = polarWidth * 0.48f + private val txtSize = scale * 16 private val path: Path = Path() - private var azimuth = 0f + private val piDiv2 = Math.PI / 2.0 private val radarPaint = Paint().apply { isAntiAlias = true color = ContextCompat.getColor(context, R.color.greyLight) style = Paint.Style.STROKE - strokeWidth = scale + strokeWidth = scale * 1.6f } private val txtPaint = Paint().apply { isAntiAlias = true @@ -42,7 +42,7 @@ class PolarView(context: Context) : View(context) { isAntiAlias = true color = ContextCompat.getColor(context, R.color.satTrack) style = Paint.Style.STROKE - strokeWidth = scale + strokeWidth = scale * 1.6f } private val satPaint = Paint().apply { isAntiAlias = true @@ -51,13 +51,10 @@ class PolarView(context: Context) : View(context) { } override fun onDraw(canvas: Canvas) { - canvas.rotate(-azimuth, polarCenter, polarCenter) canvas.translate(polarCenter, polarCenter) drawRadarView(canvas) drawRadarText(canvas) - if (!pass.tle.isDeepspace) { - drawPassTrajectory(canvas, pass) - } + if (!pass.tle.isDeepspace) drawPassTrajectory(canvas, pass) drawSatellite(canvas, pass) } @@ -99,18 +96,16 @@ class PolarView(context: Context) : View(context) { if (satPos.elevation > 0) { val x = sph2CartX(satPos.azimuth, satPos.elevation, radius.toDouble()) val y = sph2CartY(satPos.azimuth, satPos.elevation, radius.toDouble()) - cvs.drawCircle(x, -y, txtSize / 3, satPaint) + cvs.drawCircle(x, -y, txtSize / 2.6f, satPaint) } } private fun sph2CartX(azimuth: Double, elevation: Double, r: Double): Float { - val piDiv2 = Math.PI / 2.0 val radius = r * (piDiv2 - elevation) / piDiv2 return (radius * cos(piDiv2 - azimuth)).toFloat() } private fun sph2CartY(azimuth: Double, elevation: Double, r: Double): Float { - val piDiv2 = Math.PI / 2.0 val radius = r * (piDiv2 - elevation) / piDiv2 return (radius * sin(piDiv2 - azimuth)).toFloat() } diff --git a/app/src/main/res/drawable/ic_arrow.xml b/app/src/main/res/drawable/ic_arrow.xml index ea5ac792..ec6928c6 100644 --- a/app/src/main/res/drawable/ic_arrow.xml +++ b/app/src/main/res/drawable/ic_arrow.xml @@ -1,22 +1,3 @@ - - + android:pathData="M8,5v14l11,-7z" /> diff --git a/app/src/main/res/layout/fragment_entries.xml b/app/src/main/res/layout/fragment_entries.xml index 0ca47e2c..11416905 100644 --- a/app/src/main/res/layout/fragment_entries.xml +++ b/app/src/main/res/layout/fragment_entries.xml @@ -28,10 +28,7 @@ diff --git a/app/src/main/res/layout/fragment_passes.xml b/app/src/main/res/layout/fragment_passes.xml index 1bf8ccf6..c31ca871 100644 --- a/app/src/main/res/layout/fragment_passes.xml +++ b/app/src/main/res/layout/fragment_passes.xml @@ -29,10 +29,7 @@ diff --git a/app/src/main/res/layout/fragment_polar.xml b/app/src/main/res/layout/fragment_polar.xml index edee13d8..9593f14a 100644 --- a/app/src/main/res/layout/fragment_polar.xml +++ b/app/src/main/res/layout/fragment_polar.xml @@ -23,6 +23,13 @@ android:layout_height="match_parent" android:keepScreenOn="true"> + + + app:layout_constraintTop_toBottomOf="@+id/polar_bar" /> diff --git a/app/src/main/res/layout/item_trans.xml b/app/src/main/res/layout/item_trans.xml index e137eb07..10d8b6f6 100644 --- a/app/src/main/res/layout/item_trans.xml +++ b/app/src/main/res/layout/item_trans.xml @@ -19,177 +19,120 @@ + app:cardCornerRadius="0dp"> + android:layout_height="wrap_content"> + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_chainStyle="spread_inside" + app:layout_constraintStart_toEndOf="@+id/img_trans" + app:layout_constraintTop_toTopOf="parent" /> - - - - + app:layout_constraintTop_toBottomOf="@+id/description" /> + app:layout_constraintStart_toEndOf="@+id/img_uplink" /> - - + app:layout_constraintTop_toBottomOf="@+id/downlink" /> + app:layout_constraintBaseline_toBaselineOf="@+id/mode" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@+id/mode" /> - - - - + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index d66cb961..55ae2d41 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -45,10 +45,7 @@ Показывать время пролета по UTC Модуляция: нет - Восход: нет - Нисход: нет - Тек. восход: нет - Тек. нисход: нет + нет Не найдены трансиверы для этого спутника Ошибка импорта спутников @@ -63,14 +60,6 @@ Модуляция: %s Инверсия: %s - Восход: %.4fMHz - Восход: %.4f - %.4fMHz - Нисход: %.4f MHz - Нисход: %.4f - %.4fMHz - Тек. восход: %.4fMHz - Тек. восход: %.4f - %.4fMHz - Тек. нисход: %.4fMHz - Тек. нисход: %.4f - %.4fMHz Приложение для слежения за спутниками радио и погоды для платформы Android diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 3a1cf156..5489eefa 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -22,9 +22,9 @@ #FFE082 #FFCA28 #121212 - #C0C0C0 + #D0D0D0 #808080 - #1d1d1d + #1e1e1e #B00020 #26FFE082 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index edf43fd0..64c21a50 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -46,10 +46,7 @@ Show pass time in UTC Mode: null - Uplink: null - Downlink: null - Curr. uplink: null - Curr. downlink: null + null No transceivers found for this satellite Error importing satellite data @@ -69,17 +66,11 @@ Lat: %.1f°, Lon: %.1f° Vel: %.2f km/s - %s Mode: %s Inverted: %s - Uplink: %.4fMHz - Uplink: %.4f - %.4fMHz - Downlink: %.4fMHz - Downlink: %.4f - %.4fMHz - Curr. uplink: %.4fMHz - Curr. uplink: %.4f - %.4fMHz - Curr. downlink: %.4fMHz - Curr. downlink: %.4f - %.4fMHz + %s + %.4f + %.4f - %.4f Amateur radio and weather satellites passes calculator for Android diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 06f1511b..3d172c08 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -26,4 +26,10 @@ @android:color/transparent + +