From dc62d660a836f51d727e5b6fc3d791a02e1dbdcb Mon Sep 17 00:00:00 2001 From: Arty Bishop Date: Wed, 30 Oct 2019 23:20:16 +0000 Subject: [PATCH] Moved the code from activity to ViewModel. Minor layout updates. --- .../rtbishop/lookingsat/repo/Repository.kt | 8 +- .../rtbishop/lookingsat/ui/MainActivity.kt | 138 +++++------------- .../rtbishop/lookingsat/vm/MainViewModel.kt | 69 ++++++++- app/src/main/res/drawable/ic_refresh.xml | 9 ++ app/src/main/res/layout/app_bar_main.xml | 6 +- app/src/main/res/menu/main_menu.xml | 24 +-- app/src/main/res/values/strings.xml | 7 +- 7 files changed, 124 insertions(+), 137 deletions(-) create mode 100644 app/src/main/res/drawable/ic_refresh.xml diff --git a/app/src/main/java/com/rtbishop/lookingsat/repo/Repository.kt b/app/src/main/java/com/rtbishop/lookingsat/repo/Repository.kt index 44e91d5e..d3e258bf 100644 --- a/app/src/main/java/com/rtbishop/lookingsat/repo/Repository.kt +++ b/app/src/main/java/com/rtbishop/lookingsat/repo/Repository.kt @@ -1,9 +1,7 @@ package com.rtbishop.lookingsat.repo -import android.util.Log import com.rtbishop.lookingsat.api.RemoteDataSource import com.rtbishop.lookingsat.db.LocalDataSource -import java.io.IOException import java.io.InputStream class Repository( @@ -15,11 +13,7 @@ class Repository( } suspend fun updateTransmittersDatabase() { - try { - localSource.insertTransmitters(remoteSource.fetchTransmittersList()) - } catch (exception: IOException) { - Log.d(this.javaClass.simpleName, exception.toString()) - } + localSource.insertTransmitters(remoteSource.fetchTransmittersList()) } suspend fun getTransmittersForSat(id: Int): List { diff --git a/app/src/main/java/com/rtbishop/lookingsat/ui/MainActivity.kt b/app/src/main/java/com/rtbishop/lookingsat/ui/MainActivity.kt index e604c188..720c936c 100644 --- a/app/src/main/java/com/rtbishop/lookingsat/ui/MainActivity.kt +++ b/app/src/main/java/com/rtbishop/lookingsat/ui/MainActivity.kt @@ -2,10 +2,8 @@ package com.rtbishop.lookingsat.ui import android.Manifest import android.content.Intent -import android.content.SharedPreferences import android.content.pm.ActivityInfo import android.content.pm.PackageManager -import android.location.Location import android.net.Uri import android.os.Bundle import android.os.CountDownTimer @@ -21,7 +19,6 @@ import androidx.appcompat.widget.Toolbar import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat -import androidx.core.content.edit import androidx.drawerlayout.widget.DrawerLayout import androidx.lifecycle.ViewModelProviders import androidx.navigation.findNavController @@ -29,28 +26,23 @@ import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.navigateUp import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupWithNavController -import androidx.preference.PreferenceManager -import com.google.android.gms.location.FusedLocationProviderClient -import com.google.android.gms.location.LocationServices import com.google.android.material.navigation.NavigationView import com.rtbishop.lookingsat.R import com.rtbishop.lookingsat.vm.MainViewModel import java.util.* import java.util.concurrent.TimeUnit -const val LOCATION_REQ = 101 -const val LOCATION_PERM = Manifest.permission.ACCESS_FINE_LOCATION -const val GRANTED = PackageManager.PERMISSION_GRANTED -const val GITHUB_URL = "https://github.com/rt-bishop/LookingSat" - class MainActivity : AppCompatActivity() { + private val permLocationCode = 101 + private val permLocation = Manifest.permission.ACCESS_FINE_LOCATION + private val permGranted = PackageManager.PERMISSION_GRANTED + private val githubUrl = "https://github.com/rt-bishop/LookingSat" + private lateinit var appBarConfig: AppBarConfiguration private lateinit var viewModel: MainViewModel private lateinit var timerLayout: ConstraintLayout private lateinit var timeToAos: TextView - private lateinit var fusedLocationClient: FusedLocationProviderClient - private lateinit var preferences: SharedPreferences private lateinit var drawerLat: TextView private lateinit var drawerLon: TextView private lateinit var drawerHeight: TextView @@ -61,39 +53,31 @@ class MainActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setupComponents() - setupNavigation() + setupDrawer() setupTimer() - updateDrawerValues() + updateLocation() } private fun setupComponents() { viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java) - fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) - preferences = PreferenceManager.getDefaultSharedPreferences(this) timerLayout = findViewById(R.id.timer_layout) timeToAos = findViewById(R.id.time_to_aos) - } - private fun setupNavigation() { val toolbar: Toolbar = findViewById(R.id.toolbar) setSupportActionBar(toolbar) val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout) val navView: NavigationView = findViewById(R.id.nav_view) val header = navView.getHeaderView(0) + drawerLat = header.findViewById(R.id.drawer_lat_value) drawerLon = header.findViewById(R.id.drawer_lon_value) drawerHeight = header.findViewById(R.id.drawer_height_value) drawerSubTitle = header.findViewById(R.id.drawer_link) drawerGetLocation = header.findViewById(R.id.drawer_get_location) - val navController = findNavController(R.id.nav_host) - appBarConfig = AppBarConfiguration( - setOf( - R.id.nav_sky, - R.id.nav_single_sat - ), drawerLayout - ) + val navController = findNavController(R.id.nav_host) + appBarConfig = AppBarConfiguration(setOf(R.id.nav_sky, R.id.nav_single_sat), drawerLayout) setupActionBarWithNavController(navController, appBarConfig) navView.setupWithNavController(navController) @@ -113,22 +97,23 @@ class MainActivity : AppCompatActivity() { } } } + } - drawerSubTitle.setOnClickListener { - openGitHub() - } + private fun setupDrawer() { + drawerSubTitle.setOnClickListener { goToGithub() } - drawerGetLocation.startAnimation( - AnimationUtils.loadAnimation( - this, - R.anim.pulse - ) - ) + drawerGetLocation.startAnimation(AnimationUtils.loadAnimation(this, R.anim.pulse)) drawerGetLocation.setOnClickListener { it.isEnabled = false updateLocation() it.postDelayed({ it.isEnabled = true }, 3600) } + + viewModel.gsp.observe(this, androidx.lifecycle.Observer { gsp -> + drawerLat.text = String.format("%.4f", gsp.latitude) + drawerLon.text = String.format("%.4f", gsp.longitude) + drawerHeight.text = String.format("%.1fm", gsp.heightAMSL) + }) } private fun setupTimer() { @@ -158,69 +143,31 @@ class MainActivity : AppCompatActivity() { } private fun updateLocation() { - if (ContextCompat.checkSelfPermission( - this, - LOCATION_PERM - ) != GRANTED - ) { - if (ActivityCompat.shouldShowRequestPermissionRationale( - this, - LOCATION_PERM - ) - ) { + if (ContextCompat.checkSelfPermission(this, permLocation) != permGranted) { + if (ActivityCompat.shouldShowRequestPermissionRationale(this, permLocation)) { Toast.makeText(this, "Missing permissions", Toast.LENGTH_LONG).show() } else { - ActivityCompat.requestPermissions( - this, arrayOf(LOCATION_PERM), - LOCATION_REQ - ) + ActivityCompat.requestPermissions(this, arrayOf(permLocation), permLocationCode) } } else { - getPreciseLocation() + viewModel.updateLocation() } } - private fun getPreciseLocation() { - fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? -> - val lat = location?.latitude ?: 51.5074 - val lon = location?.longitude ?: 0.1278 - val height = location?.altitude ?: 48.0 - - preferences.edit { - putDouble("LATITUDE", lat) - putDouble("LONGITUDE", lon) - putDouble("HEIGHT", height) - apply() - } - updateDrawerValues() - Toast.makeText(this, "Location was set", Toast.LENGTH_SHORT).show() - } - } - - private fun updateDrawerValues() { - val lat = preferences.getDouble("LATITUDE", 51.5074) - val lon = preferences.getDouble("LONGITUDE", 0.1278) - val height = preferences.getDouble("HEIGHT", 48.0) - - drawerLat.text = String.format("%.4f", lat) - drawerLon.text = String.format("%.4f", lon) - drawerHeight.text = String.format("%.1fm", height) - } - - private fun openGitHub() { - val intentGitHub = Intent(Intent.ACTION_VIEW, Uri.parse(GITHUB_URL)) + private fun goToGithub() { + val intentGitHub = Intent(Intent.ACTION_VIEW, Uri.parse(githubUrl)) startActivity(intentGitHub) } - override fun onRequestPermissionsResult( - requestCode: Int, - permissions: Array, - grantResults: IntArray - ) { - when (requestCode) { - LOCATION_REQ -> { - if (grantResults.isNotEmpty() && grantResults[0] == GRANTED) { - getPreciseLocation() + private fun exit() { + finish() + } + + override fun onRequestPermissionsResult(reqCode: Int, perms: Array, res: IntArray) { + when (reqCode) { + permLocationCode -> { + if (res.isNotEmpty() && res[0] == permGranted) { + viewModel.updateLocation() } } } @@ -238,19 +185,8 @@ class MainActivity : AppCompatActivity() { override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { - R.id.fetch_trans -> Toast.makeText(this, "Fetch transmit", Toast.LENGTH_SHORT).show() - R.id.save_to_db -> Toast.makeText(this, "Saving to DB", Toast.LENGTH_SHORT).show() - R.id.load_from_db -> Toast.makeText(this, "Loading from DB", Toast.LENGTH_SHORT).show() - R.id.fetch_tle -> Toast.makeText(this, "Fetching TLE", Toast.LENGTH_SHORT).show() - R.id.load_tle -> Toast.makeText(this, "Loading TLE", Toast.LENGTH_SHORT).show() - R.id.action_exit -> finish() + R.id.menu_refresh -> Toast.makeText(this, "Refresh", Toast.LENGTH_SHORT).show() } return super.onOptionsItemSelected(item) } -} - -fun SharedPreferences.Editor.putDouble(key: String, double: Double): SharedPreferences.Editor = - putLong(key, java.lang.Double.doubleToRawLongBits(double)) - -fun SharedPreferences.getDouble(key: String, default: Double) = - java.lang.Double.longBitsToDouble(getLong(key, java.lang.Double.doubleToRawLongBits(default))) \ No newline at end of file +} \ 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 58a431c0..e7327ac8 100644 --- a/app/src/main/java/com/rtbishop/lookingsat/vm/MainViewModel.kt +++ b/app/src/main/java/com/rtbishop/lookingsat/vm/MainViewModel.kt @@ -1,11 +1,76 @@ package com.rtbishop.lookingsat.vm import android.app.Application +import android.content.Context +import android.content.SharedPreferences +import android.location.Location +import android.widget.Toast +import androidx.core.content.edit import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope +import androidx.preference.PreferenceManager +import com.github.amsacode.predict4java.GroundStationPosition +import com.google.android.gms.location.LocationServices import com.rtbishop.lookingsat.Injector import com.rtbishop.lookingsat.repo.Repository +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import java.io.IOException class MainViewModel(application: Application) : AndroidViewModel(application) { - private var repository: Repository = Injector.provideRepository(application) -} \ No newline at end of file + private val repository: Repository = Injector.provideRepository(application) + private val preferences = PreferenceManager.getDefaultSharedPreferences(application) + private val fusedLocationClient = LocationServices.getFusedLocationProviderClient(application) + private val _gsp = MutableLiveData() + val gsp: LiveData = _gsp + + fun updateLocation() { + fusedLocationClient.lastLocation.addOnSuccessListener { location: Location? -> + val lat = location?.latitude ?: 51.5074 + val lon = location?.longitude ?: 0.1278 + val height = location?.altitude ?: 48.0 + + preferences.edit { + putDouble("LATITUDE", lat) + putDouble("LONGITUDE", lon) + putDouble("HEIGHT", height) + apply() + } + _gsp.postValue(GroundStationPosition(lat, lon, height)) + } + } + + fun updateTwoLineElementFile() { + val fileName = "tles.txt" + viewModelScope.launch(Dispatchers.IO) { + try { + getApplication().openFileOutput(fileName, Context.MODE_PRIVATE).use { + it.write(repository.fetchTleStream().readBytes()) + } + Toast.makeText(getApplication(), "TLE file was updated", Toast.LENGTH_SHORT).show() + } catch (exception: IOException) { + Toast.makeText(getApplication(), "Could not update TLE", Toast.LENGTH_SHORT).show() + } + } + } + + fun updateTransmittersDatabase() { + viewModelScope.launch(Dispatchers.IO) { + try { + repository.updateTransmittersDatabase() + Toast.makeText(getApplication(), "", Toast.LENGTH_SHORT).show() + } catch (exception: IOException) { + Toast.makeText(getApplication(), "", Toast.LENGTH_SHORT).show() + } + } + } +} + +fun SharedPreferences.Editor.putDouble(key: String, double: Double): SharedPreferences.Editor = + putLong(key, java.lang.Double.doubleToRawLongBits(double)) + +fun SharedPreferences.getDouble(key: String, default: Double) = + java.lang.Double.longBitsToDouble(getLong(key, java.lang.Double.doubleToRawLongBits(default))) \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_refresh.xml b/app/src/main/res/drawable/ic_refresh.xml new file mode 100644 index 00000000..6ff7a0cc --- /dev/null +++ b/app/src/main/res/drawable/ic_refresh.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/app_bar_main.xml b/app/src/main/res/layout/app_bar_main.xml index 8ab9f3c2..63dc4b58 100644 --- a/app/src/main/res/layout/app_bar_main.xml +++ b/app/src/main/res/layout/app_bar_main.xml @@ -18,16 +18,16 @@ + android:layout_height="wrap_content"> - + - - - - - + android:id="@+id/menu_refresh" + android:icon="@drawable/ic_refresh" + android:title="@string/menu_refresh" + app:showAsAction="always" /> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 63e25968..f561a911 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -19,12 +19,7 @@ Height AMSL: 48.0m - Fetch Transmitters - Save to DB - Load from DB - Fetch TLE - Load TLE - Exit + Refresh AOS in %02d:%02d:%02d Drawer Locator