Added Api 21 support. Fixed the bug with geostationary satellites calculations. Showing them on top of the list in separate ViewHolders.

This commit is contained in:
Arty Bishop committed 2020-02-03 19:00:55 +00:00
1 parent 94e4b5fb31
commit 6ead302634
16 files changed
+209 -59

No files matched your search

+3 -3
View File
@@ -28,10 +28,10 @@ android {
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.rtbishop.look4sat"
minSdkVersion 24
minSdkVersion 21
targetSdkVersion 29
versionCode 2
versionName '1.1'
versionCode 3
versionName '1.2'
}
buildTypes {
release {
@@ -103,18 +103,49 @@ class PassPredictor(private val tle: TLE, private val qth: GroundStationPosition
var lastAOS: Date
var count = 0
do {
if (count > 0) windBackTime = false
val pass = nextSatPass(trackStartDate, windBackTime)
lastAOS = pass.startTime
passes.add(pass)
trackStartDate = Date(pass.endTime.time + threeQuarterOrbitMinutes() * 60L * 1000L)
count++
} while (lastAOS < trackEndDate)
if (tle.isDeepspace) {
passes.add(nextGeoSatPass(start))
} else {
do {
if (count > 0) windBackTime = false
val pass = nextSatPass(trackStartDate, windBackTime)
lastAOS = pass.startTime
passes.add(pass)
trackStartDate = Date(pass.endTime.time + threeQuarterOrbitMinutes() * 60L * 1000L)
count++
} while (lastAOS < trackEndDate)
}
return passes
}
private fun nextGeoSatPass(date: Date): SatPassTime {
val aosAzimuth: Int
val losAzimuth: Int
val tca: Date
val polePassed: String
val cal = Calendar.getInstance(timeZone).apply {
clear()
timeInMillis = date.time
}
val satPos = getSatPos(cal.time)
aosAzimuth = (satPos.azimuth / (2.0 * Math.PI) * 360.0).toInt()
losAzimuth = (satPos.azimuth / (2.0 * Math.PI) * 360.0).toInt()
tca = satPos.time
polePassed = getPolePassed(satPos, satPos)
cal.add(Calendar.HOUR, -12)
val startDate = cal.time
cal.add(Calendar.HOUR, 24)
val endDate = cal.time
return SatPassTime(
startDate, endDate, tca, polePassed, aosAzimuth,
losAzimuth, satPos.elevation / (2.0 * Math.PI) * 360.0
)
}
private fun nextSatPass(date: Date, windBack: Boolean = false): SatPassTime {
val aosAzimuth: Int
val losAzimuth: Int
@@ -187,14 +187,4 @@ class MainActivity : AppCompatActivity() {
val navController = findNavController(R.id.nav_host)
return navController.navigateUp(appBarConfig) || super.onSupportNavigateUp()
}
//
// private fun ImageButton.enable() {
// this.isEnabled = true
// this.alpha = 1.0f
// }
//
// private fun ImageButton.disable() {
// this.isEnabled = false
// this.alpha = 0.25f
// }
}
@@ -29,6 +29,7 @@ import android.widget.FrameLayout
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.github.amsacode.predict4java.GroundStationPosition
@@ -146,19 +147,19 @@ class MapViewFragment : Fragment() {
private val scale = resources.displayMetrics.density
private val groundTrackPaint = Paint().apply {
isAntiAlias = true
color = resources.getColor(R.color.satTrack, mainActivity.theme)
color = ContextCompat.getColor(mainActivity, R.color.satTrack)
style = Paint.Style.STROKE
strokeWidth = scale
}
private val footprintPaint = Paint().apply {
isAntiAlias = true
color = resources.getColor(R.color.satFootprint, mainActivity.theme)
color = ContextCompat.getColor(mainActivity, R.color.satFootprint)
style = Paint.Style.STROKE
strokeWidth = scale
}
private val txtPaint = Paint().apply {
isAntiAlias = true
color = resources.getColor(R.color.satFootprint, mainActivity.theme)
color = ContextCompat.getColor(mainActivity, R.color.satFootprint)
style = Paint.Style.FILL
strokeWidth = scale
textSize = 16f
@@ -245,7 +245,7 @@ class PassListFragment : Fragment() {
override fun onTick(millisUntilFinished: Long) {
aosTimerText.text = String.format(
mainActivity.getString(R.string.pat_timer_aos),
mainActivity.getString(R.string.pat_timer),
TimeUnit.MILLISECONDS.toHours(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60
@@ -265,7 +265,7 @@ class PassListFragment : Fragment() {
override fun onTick(millisUntilFinished: Long) {
aosTimerText.text = String.format(
mainActivity.getString(R.string.pat_timer_los),
mainActivity.getString(R.string.pat_timer),
TimeUnit.MILLISECONDS.toHours(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60
@@ -281,6 +281,6 @@ class PassListFragment : Fragment() {
isTimerSet = false
}
if (resetToNull) aosTimerText.text =
String.format(getString(R.string.pat_timer_aos), 0, 0, 0)
String.format(getString(R.string.pat_timer), 0, 0, 0)
}
}
@@ -29,6 +29,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
@@ -132,24 +133,24 @@ class PolarViewFragment : Fragment() {
private val radarPaint = Paint().apply {
isAntiAlias = true
color = resources.getColor(R.color.themeLight, mainActivity.theme)
color = ContextCompat.getColor(mainActivity, R.color.themeLight)
style = Paint.Style.STROKE
strokeWidth = scale
}
private val txtPaint = Paint().apply {
isAntiAlias = true
color = resources.getColor(R.color.themeAccent, mainActivity.theme)
color = ContextCompat.getColor(mainActivity, R.color.themeAccent)
textSize = txtSize
}
private val trackPaint = Paint().apply {
isAntiAlias = true
color = resources.getColor(R.color.satTrack, mainActivity.theme)
color = ContextCompat.getColor(mainActivity, R.color.satTrack)
style = Paint.Style.STROKE
strokeWidth = scale
}
private val satPaint = Paint().apply {
isAntiAlias = true
color = resources.getColor(R.color.themeAccent, mainActivity.theme)
color = ContextCompat.getColor(mainActivity, R.color.themeAccent)
style = Paint.Style.FILL
}
private val path: Path = Path()
@@ -163,7 +164,7 @@ class PolarViewFragment : Fragment() {
setPassText()
drawRadarView(canvas)
drawRadarText(canvas)
drawPassTrajectory(canvas)
if (!satPass.tle.isDeepspace) drawPassTrajectory(canvas)
drawSatellite(canvas)
}
@@ -34,7 +34,7 @@ import com.rtbishop.look4sat.ui.PassListFragmentDirections
import java.text.SimpleDateFormat
import java.util.*
class SatPassAdapter : RecyclerView.Adapter<SatPassAdapter.SatPassHolder>() {
class SatPassAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var satPassList = mutableListOf<SatPass>()
@@ -71,15 +71,31 @@ class SatPassAdapter : RecyclerView.Adapter<SatPassAdapter.SatPassHolder>() {
return satPassList.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SatPassHolder {
val itemView = LayoutInflater
.from(parent.context)
.inflate(R.layout.card_pass, parent, false)
return SatPassHolder(itemView)
override fun getItemViewType(position: Int): Int {
return if (satPassList[position].tle.isDeepspace) 1
else 0
}
override fun onBindViewHolder(holder: SatPassHolder, position: Int) {
holder.bind(satPassList[position])
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == 0) {
val itemView = LayoutInflater
.from(parent.context)
.inflate(R.layout.card_pass, parent, false)
return SatPassHolder(itemView)
} else {
val itemView = LayoutInflater
.from(parent.context)
.inflate(R.layout.card_pass_geo, parent, false)
SatPassGeoHolder(itemView)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder.itemViewType == 0) {
(holder as SatPassHolder).bind(satPassList[position])
} else {
(holder as SatPassGeoHolder).bind(satPassList[position])
}
}
inner class SatPassHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
@@ -123,4 +139,29 @@ class SatPassAdapter : RecyclerView.Adapter<SatPassAdapter.SatPassHolder>() {
}
}
}
inner class SatPassGeoHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val context: Context = itemView.context
private val satName = itemView.findViewById<TextView>(R.id.pass_geo_name)
private val satId = itemView.findViewById<TextView>(R.id.pass_geo_id)
private val satAz = itemView.findViewById<TextView>(R.id.pass_geo_az)
private val satEl = itemView.findViewById<TextView>(R.id.pass_geo_el)
fun bind(satPass: SatPass) {
val satPos = satPass.predictor.getSatPos(satPass.pass.startTime)
val azimuth = satPos.azimuth * 180 / Math.PI
satName.text = satPass.tle.name
satId.text = String.format(context.getString(R.string.pass_satId), satPass.tle.catnum)
satAz.text = String.format(context.getString(R.string.pat_azimuth), azimuth)
satEl.text =
String.format(context.getString(R.string.pat_elevation), satPass.pass.maxEl)
itemView.setOnClickListener {
val action = PassListFragmentDirections.actionPassToPolar(satPass)
itemView.findNavController().navigate(action)
}
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

@@ -2,9 +2,9 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque">
<item android:drawable="@drawable/ic_launcher_background" />
<item
android:width="240dp"
android:height="240dp"
android:drawable="@drawable/splash_foreground"
android:gravity="center" />
<item>
<bitmap
android:gravity="center"
android:src="@drawable/splash_front" />
</item>
</layer-list>
+1 -1
View File
@@ -26,7 +26,7 @@
style="@style/ToolbarText"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="16dp"
android:layout_marginEnd="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/toolbar_filter"
app:layout_constraintStart_toStartOf="parent"
+13 -2
View File
@@ -29,8 +29,19 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/card_pass_bg">
android:layout_height="wrap_content">
<ImageView
android:id="@+id/pass_background"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@string/placeholder"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/card_pass_bg" />
<TextView
android:id="@+id/pass_losAz"
+79
View File
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_pass_geo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
app:cardElevation="4dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/pass_geo_background"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@string/placeholder"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/card_pass_bg" />
<ImageView
android:id="@+id/pass_geo_img"
android:layout_width="20dp"
android:layout_height="20dp"
android:contentDescription="@string/placeholder"
app:layout_constraintBottom_toBottomOf="@+id/pass_geo_name"
app:layout_constraintStart_toStartOf="@+id/pass_geo_az"
app:layout_constraintTop_toTopOf="@+id/pass_geo_name"
app:srcCompat="@drawable/ic_pass_active" />
<TextView
android:id="@+id/pass_geo_name"
style="@style/CardPassName"
android:text="@string/pass_satName"
app:layout_constraintBaseline_toBaselineOf="@+id/pass_geo_id"
app:layout_constraintEnd_toStartOf="@+id/pass_geo_id"
app:layout_constraintHorizontal_bias="0.02"
app:layout_constraintStart_toEndOf="@+id/pass_geo_img" />
<TextView
android:id="@+id/pass_geo_id"
style="@style/CardPassName"
android:layout_marginTop="4dp"
android:text="@string/pass_satId"
app:layout_constraintEnd_toEndOf="@+id/pass_geo_el"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/pass_geo_az"
style="@style/CardPassText"
android:layout_marginStart="6dp"
android:text="@string/pat_azimuth"
app:layout_constraintBaseline_toBaselineOf="@+id/pass_geo_el"
app:layout_constraintEnd_toStartOf="@+id/pass_geo_el"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/pass_geo_el"
style="@style/CardPassText"
android:layout_marginTop="4dp"
android:layout_marginEnd="6dp"
android:layout_marginBottom="4dp"
android:text="@string/pat_elevation"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/pass_geo_az"
app:layout_constraintTop_toBottomOf="@+id/pass_geo_id" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
+4 -6
View File
@@ -90,15 +90,13 @@
<string name="pat_longitude">Долгота: %.1f°</string>
<string name="pat_range">Расст.: %.0f км</string>
<string name="pat_altitude">Высота: %.0f км</string>
<string name="pat_timer_aos">НПС -%02d:%02d:%02d</string>
<string name="pat_timer_los">КПС -%02d:%02d:%02d</string>
<string name="trans_mode">Модуляция: %s</string>
<string name="trans_inverted">Инверсия: %s</string>
<string name="trans_up_low">Исход. канал: %.4f MHz</string>
<string name="trans_up_lowHigh">Исход. канал: %.4f - %.4f MHz</string>
<string name="trans_down_low">Вход. канал: %.4f MHz</string>
<string name="trans_down_lowHigh">Вход. канал: %.4f - %.4f MHz</string>
<string name="trans_up_low">Исходящий: %.4f MHz</string>
<string name="trans_up_lowHigh">Исходящий: %.4f - %.4f MHz</string>
<string name="trans_down_low">Входящий: %.4f MHz</string>
<string name="trans_down_lowHigh">Входящий: %.4f - %.4f MHz</string>
<string name="info_swipe_text">Проведите по экрану вниз, чтобы обновить список пролетов
для выбранных спутников</string>
+2 -4
View File
@@ -102,8 +102,7 @@
<string name="pat_longitude">Longitude: %.1f°</string>
<string name="pat_range">Distance: %.0f km</string>
<string name="pat_altitude">Altitude: %.0f km</string>
<string name="pat_timer_aos">AOS -%02d:%02d:%02d</string>
<string name="pat_timer_los">LOS -%02d:%02d:%02d</string>
<string name="pat_timer" translatable="false">%02d:%02d:%02d</string>
<string name="trans_description" translatable="false">%s</string>
<string name="trans_mode">Mode: %s</string>
@@ -125,8 +124,7 @@
<string name="about_subtitle">
Amateur radio and weather satellites passes calculator for Android</string>
<string name="about_thanks_to">Big thanks:</string>
<string name="about_thanks_list">— To you for installing and using this app!
\nMay your sky always be clear!\n
<string name="about_thanks_list">— To you for installing and using this app! May your sky always be clear!\n
\n— To David A. B. Johnson, <a href="https://github.com/g4dpz">G4DPZ</a>, the author of
predict4java library which this app is using for all the SGP4 model calculations.\n
+1 -1
View File
@@ -70,7 +70,7 @@
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">center</item>
<item name="android:textSize">28sp</item>
<item name="android:textSize">36sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/themeAccent</item>
</style>