mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Extracted sensor listening logic from PolarFragment.kt to Orientation.kt
This commit is contained in:
1 parent
c2216e4917
commit
8c67ec4808
3 files changed
+130
-86
No files matched your search
@@ -20,7 +20,9 @@ package com.rtbishop.look4sat.di
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.hardware.SensorManager
|
||||
import android.location.LocationManager
|
||||
import android.view.WindowManager
|
||||
import androidx.preference.PreferenceManager
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
@@ -42,6 +44,16 @@ object ApplicationModule {
|
||||
return context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideSensorManager(@ApplicationContext context: Context): SensorManager {
|
||||
return context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideWindowManager(@ApplicationContext context: Context): WindowManager {
|
||||
return context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideSharedPreferences(@ApplicationContext context: Context): SharedPreferences {
|
||||
return PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Look4Sat. Amateur radio satellite tracker and pass predictor.
|
||||
* Copyright (C) 2019-2021 Arty Bishop (bishop.arty@gmail.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rtbishop.look4sat.ui.polarScreen
|
||||
|
||||
import android.hardware.Sensor
|
||||
import android.hardware.SensorEvent
|
||||
import android.hardware.SensorEventListener
|
||||
import android.hardware.SensorManager
|
||||
import android.view.Surface
|
||||
import android.view.WindowManager
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.atan2
|
||||
import kotlin.math.round
|
||||
|
||||
class Orientation @Inject constructor(
|
||||
private val mSensorManager: SensorManager,
|
||||
private val mWindowManager: WindowManager
|
||||
) : SensorEventListener {
|
||||
|
||||
interface OrientationListener {
|
||||
fun onOrientationChanged(azimuth: Float, pitch: Float, roll: Float)
|
||||
}
|
||||
|
||||
private val mRotationSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)
|
||||
private val mRotationMatrix = FloatArray(9)
|
||||
private val mOrientationValues = FloatArray(3)
|
||||
private val mOneRadDegrees = 57.295779513f
|
||||
private var mLastAccuracy: Int = SensorManager.SENSOR_STATUS_UNRELIABLE
|
||||
private var mListener: OrientationListener? = null
|
||||
|
||||
fun startListening(listener: OrientationListener) {
|
||||
when {
|
||||
mListener === listener -> return
|
||||
else -> {
|
||||
mListener = listener
|
||||
mSensorManager.registerListener(this, mRotationSensor, 16000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun stopListening() {
|
||||
mSensorManager.unregisterListener(this)
|
||||
mListener = null
|
||||
}
|
||||
|
||||
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
|
||||
mLastAccuracy = accuracy
|
||||
}
|
||||
|
||||
override fun onSensorChanged(event: SensorEvent) {
|
||||
when {
|
||||
mListener == null -> return
|
||||
mLastAccuracy == SensorManager.SENSOR_STATUS_UNRELIABLE -> return
|
||||
event.sensor == mRotationSensor -> updateOrientation(event.values)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
private fun updateOrientation(rotationVector: FloatArray) {
|
||||
SensorManager.getRotationMatrixFromVector(mRotationMatrix, rotationVector)
|
||||
val (matrixColumn, sense) = when (mWindowManager.defaultDisplay.rotation) {
|
||||
Surface.ROTATION_0 -> Pair(0, 1)
|
||||
Surface.ROTATION_90 -> Pair(1, -1)
|
||||
Surface.ROTATION_180 -> Pair(0, -1)
|
||||
Surface.ROTATION_270 -> Pair(1, 1)
|
||||
else -> error("Invalid screen rotation value")
|
||||
}
|
||||
val x = sense * mRotationMatrix[matrixColumn]
|
||||
val y = sense * mRotationMatrix[matrixColumn + 3]
|
||||
val azimuth = -atan2(y, x) * mOneRadDegrees
|
||||
// SensorManager.getOrientation(mRotationMatrix, mOrientationValues)
|
||||
// val azimuth = mOrientationValues[0] * mOneRadDegrees
|
||||
val pitch = mOrientationValues[1] * mOneRadDegrees
|
||||
val roll = mOrientationValues[2] * mOneRadDegrees
|
||||
val magneticAzimuth = (azimuth + 360f) % 360f
|
||||
val roundedAzimuth = round(magneticAzimuth * 10) / 10
|
||||
mListener?.onOrientationChanged(roundedAzimuth, pitch, roll)
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,7 @@
|
||||
*/
|
||||
package com.rtbishop.look4sat.ui.polarScreen
|
||||
|
||||
import android.content.Context
|
||||
import android.hardware.Sensor
|
||||
import android.hardware.SensorEvent
|
||||
import android.hardware.SensorEventListener
|
||||
import android.hardware.SensorManager
|
||||
import android.os.Bundle
|
||||
import android.view.Surface
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
@@ -37,100 +31,48 @@ import com.rtbishop.look4sat.utility.RecyclerDivider
|
||||
import com.rtbishop.look4sat.utility.formatForTimer
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import java.util.*
|
||||
import kotlin.math.atan2
|
||||
import kotlin.math.round
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
|
||||
class PolarFragment : Fragment(R.layout.fragment_polar), Orientation.OrientationListener {
|
||||
|
||||
@Inject
|
||||
lateinit var orientation: Orientation
|
||||
|
||||
private lateinit var transmitterAdapter: TransAdapter
|
||||
private lateinit var binding: FragmentPolarBinding
|
||||
private lateinit var satPass: SatPass
|
||||
private lateinit var sensorManager: SensorManager
|
||||
private val viewModel: PolarViewModel by viewModels()
|
||||
private val rotationMatrix = FloatArray(9)
|
||||
private val orientationValues = FloatArray(3)
|
||||
private var magneticDeclination = 0f
|
||||
private var polarView: PolarView? = null
|
||||
private var magneticDeclination = 0f
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding = FragmentPolarBinding.bind(view)
|
||||
sensorManager = requireContext().getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||
val binding = FragmentPolarBinding.bind(view)
|
||||
val catNum = requireArguments().getInt("catNum")
|
||||
val aosTime = requireArguments().getLong("aosTime")
|
||||
magneticDeclination = viewModel.getMagDeclination()
|
||||
observePass()
|
||||
viewModel.getPass(catNum, aosTime).observe(viewLifecycleOwner) { pass ->
|
||||
polarView = PolarView(requireContext()).apply { setPass(pass) }
|
||||
binding.frame.addView(polarView)
|
||||
observeTransmitters(pass, binding)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (viewModel.shouldUseCompass()) {
|
||||
sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR).also { sensor ->
|
||||
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME)
|
||||
}
|
||||
}
|
||||
if (viewModel.shouldUseCompass()) orientation.startListening(this)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (viewModel.shouldUseCompass()) {
|
||||
sensorManager.unregisterListener(this)
|
||||
}
|
||||
if (viewModel.shouldUseCompass()) orientation.stopListening()
|
||||
}
|
||||
|
||||
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
|
||||
|
||||
override fun onSensorChanged(event: SensorEvent?) {
|
||||
event?.let { calculateAzimuth(it) }
|
||||
override fun onOrientationChanged(azimuth: Float, pitch: Float, roll: Float) {
|
||||
polarView?.rotation = -(azimuth + magneticDeclination)
|
||||
}
|
||||
|
||||
private fun calculateAzimuth(event: SensorEvent) {
|
||||
// if (event.sensor.type == Sensor.TYPE_ROTATION_VECTOR) {
|
||||
// SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values)
|
||||
// SensorManager.getOrientation(rotationMatrix, orientationValues)
|
||||
// val magneticAzimuth = (Math.toDegrees(orientationValues[0].toDouble()) + 360f) % 360f
|
||||
// val roundedAzimuth = (round(magneticAzimuth * 10) / 10).toFloat()
|
||||
// polarView?.rotation = -(roundedAzimuth + magneticDeclination)
|
||||
// }
|
||||
|
||||
if (event.sensor.type == Sensor.TYPE_ROTATION_VECTOR) {
|
||||
SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values)
|
||||
val (matrixColumn, sense) = when (val rotation =
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
||||
requireContext().display?.rotation
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
requireActivity().windowManager.defaultDisplay.rotation
|
||||
}
|
||||
) {
|
||||
Surface.ROTATION_0 -> Pair(0, 1)
|
||||
Surface.ROTATION_90 -> Pair(1, -1)
|
||||
Surface.ROTATION_180 -> Pair(0, -1)
|
||||
Surface.ROTATION_270 -> Pair(1, 1)
|
||||
else -> error("Invalid screen rotation value: $rotation")
|
||||
}
|
||||
val x = sense * rotationMatrix[matrixColumn]
|
||||
val y = sense * rotationMatrix[matrixColumn + 3]
|
||||
val magneticAzimuth = (Math.toDegrees(-atan2(y, x).toDouble()) + 360f) % 360f
|
||||
val roundedAzimuth = (round(magneticAzimuth * 10) / 10).toFloat()
|
||||
polarView?.rotation = -(roundedAzimuth + magneticDeclination)
|
||||
}
|
||||
}
|
||||
|
||||
private fun observePass() {
|
||||
val catNum = requireArguments().getInt("catNum")
|
||||
val aosTime = requireArguments().getLong("aosTime")
|
||||
viewModel.getPass(catNum, aosTime).observe(viewLifecycleOwner) { pass ->
|
||||
satPass = pass
|
||||
polarView = PolarView(requireContext()).apply { setPass(pass) }
|
||||
binding.frame.addView(polarView)
|
||||
observeTransmitters()
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeTransmitters() {
|
||||
viewModel.getSatTransmitters(satPass.catNum)
|
||||
.observe(viewLifecycleOwner, { list ->
|
||||
transmitterAdapter = TransAdapter(satPass)
|
||||
private fun observeTransmitters(satPass: SatPass, binding: FragmentPolarBinding) {
|
||||
viewModel.getSatTransmitters(satPass.catNum).observe(viewLifecycleOwner, { list ->
|
||||
val transmitterAdapter = TransAdapter(satPass)
|
||||
if (list.isNotEmpty()) {
|
||||
transmitterAdapter.setData(list)
|
||||
binding.recycler.apply {
|
||||
@@ -147,19 +89,15 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
|
||||
binding.recycler.visibility = View.INVISIBLE
|
||||
binding.noTransMsg.visibility = View.VISIBLE
|
||||
}
|
||||
observeTimer()
|
||||
})
|
||||
}
|
||||
|
||||
private fun observeTimer() {
|
||||
viewModel.getAppTimer().observe(viewLifecycleOwner, {
|
||||
setPassText(it)
|
||||
setPassText(it, satPass, binding)
|
||||
polarView?.invalidate()
|
||||
transmitterAdapter.tickTransmitters()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
private fun setPassText(timeNow: Long) {
|
||||
private fun setPassText(timeNow: Long, satPass: SatPass, binding: FragmentPolarBinding) {
|
||||
val dateNow = Date(timeNow)
|
||||
val satPos = satPass.predictor.getSatPos(dateNow)
|
||||
val polarAz = getString(R.string.pat_azimuth)
|
||||
|
||||
Reference in new issue
Block a user