mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Minor fixes to strings and ui, crash fixed #63
This commit is contained in:
1 parent
a2f37e6b9f
commit
278c06170b
16 files changed
+157
-177
No files matched your search
+2
-2
@@ -43,7 +43,7 @@ android {
|
||||
}
|
||||
testOptions {
|
||||
animationsDisabled true
|
||||
unitTests.includeAndroidResources = true
|
||||
unitTests.includeAndroidResources true
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
@@ -56,7 +56,7 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation project(":base")
|
||||
implementation "androidx.core:core-splashscreen:1.0.0-beta01"
|
||||
implementation "androidx.core:core-splashscreen:1.0.0-beta02"
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.1.3"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1"
|
||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.1"
|
||||
|
||||
@@ -5,11 +5,10 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH"
|
||||
android:maxSdkVersion="30" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:name=".presentation.MainApplication"
|
||||
|
||||
@@ -39,8 +39,8 @@ class SettingsManager @Inject constructor(private val prefs: SharedPreferences)
|
||||
const val keyRotatorAddress = "rotatorAddress"
|
||||
const val keyRotatorPort = "rotatorPort"
|
||||
const val keyBTEnabled = "isBTEnabled"
|
||||
const val keyBTDeviceName = "BTDevice"
|
||||
const val keyBTDeviceAddr = "BTDevice"
|
||||
const val keyBTDeviceName = "BTDeviceName"
|
||||
const val keyBTDeviceAddr = "BTDeviceAddr"
|
||||
const val keyBTFormat = "BTFormat"
|
||||
const val keyLatitude = "stationLat"
|
||||
const val keyLongitude = "stationLon"
|
||||
@@ -153,7 +153,7 @@ class SettingsManager @Inject constructor(private val prefs: SharedPreferences)
|
||||
}
|
||||
|
||||
override fun getBTEnabled(): Boolean {
|
||||
return prefs.getBoolean(keyBTEnabled, true)
|
||||
return prefs.getBoolean(keyBTEnabled, false)
|
||||
}
|
||||
|
||||
override fun setBTEnabled(value: Boolean) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.rtbishop.look4sat.injection
|
||||
|
||||
import android.bluetooth.BluetoothManager
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.hardware.SensorManager
|
||||
@@ -32,6 +33,12 @@ import javax.inject.Singleton
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object AppModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideBluetoothManager(@ApplicationContext context: Context): BluetoothManager {
|
||||
return context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideLocationManager(@ApplicationContext context: Context): LocationManager {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.rtbishop.look4sat.injection
|
||||
|
||||
import android.bluetooth.BluetoothManager
|
||||
import android.content.Context
|
||||
import androidx.room.Room
|
||||
import com.rtbishop.look4sat.domain.IDataRepository
|
||||
@@ -65,7 +66,9 @@ object BaseModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideBTReporter(): BTReporter = BTReporter(CoroutineScope(Dispatchers.IO))
|
||||
fun provideBTReporter(manager: BluetoothManager): BTReporter {
|
||||
return BTReporter(manager, CoroutineScope(Dispatchers.IO))
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
|
||||
@@ -1,134 +1,83 @@
|
||||
package com.rtbishop.look4sat.presentation.radarScreen
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.bluetooth.BluetoothManager
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.test.core.app.ApplicationProvider.getApplicationContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancelAndJoin
|
||||
import kotlinx.coroutines.launch
|
||||
import java.net.InetSocketAddress
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.channels.SocketChannel
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.bluetooth.BluetoothManager
|
||||
import android.bluetooth.BluetoothSocket
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.core.app.ActivityCompat
|
||||
import java.io.OutputStream
|
||||
import java.util.*
|
||||
import kotlin.math.abs
|
||||
|
||||
class BTReporter(private val reporterScope: CoroutineScope) {
|
||||
class BTReporter(private val manager: BluetoothManager, private val reporterScope: CoroutineScope) {
|
||||
|
||||
private var rotationConnectBTJob: Job? = null
|
||||
private var rotationReportingBT: Job? = null
|
||||
private var satVisible=false
|
||||
private var CRchar:Char = '\r'
|
||||
private var NLchar:Char = '\n'
|
||||
private var TBchar:Char = '\t'
|
||||
private val bluetoothAdapter: BluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
|
||||
private lateinit var mmOutStream: OutputStream
|
||||
private val SPPID: UUID=UUID.fromString("00001101-0000-1000-8000-00805f9b34fb")
|
||||
private val tag = "BTReporter"
|
||||
private val sppid: UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb")
|
||||
private lateinit var outputStream: OutputStream
|
||||
private var rotationConnectionJob: Job? = null
|
||||
private var rotationReportingJob: Job? = null
|
||||
private var connected = false
|
||||
private var connectInProgress = false
|
||||
private var connecting = false
|
||||
|
||||
fun connectBTDevice(dev: String) {
|
||||
fun isConnected(): Boolean = connected
|
||||
|
||||
fun isConnecting(): Boolean = connecting
|
||||
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
fun connectBTDevice(deviceId: String) {
|
||||
if (!connected) {
|
||||
|
||||
rotationConnectBTJob = reporterScope.launch {
|
||||
runCatching {
|
||||
connectInProgress = true
|
||||
val rotationBTDevice = bluetoothAdapter.getRemoteDevice(dev)
|
||||
val sock = rotationBTDevice.createInsecureRfcommSocketToServiceRecord(SPPID)
|
||||
sock.connect()
|
||||
mmOutStream = sock.outputStream
|
||||
connected = true
|
||||
|
||||
connectInProgress = false
|
||||
Log.i("look4satBT", "Connected!")
|
||||
}.onFailure { error: Throwable ->
|
||||
Log.e("BT Error", "${error.message}")
|
||||
rotationConnectionJob = reporterScope.launch {
|
||||
try {
|
||||
manager.adapter.getRemoteDevice(deviceId)?.let { device ->
|
||||
device.createInsecureRfcommSocketToServiceRecord(sppid)?.let { socket ->
|
||||
connecting = true
|
||||
socket.connect()
|
||||
outputStream = socket.outputStream
|
||||
connected = true
|
||||
connecting = false
|
||||
Log.i(tag, "$tag: Connected!")
|
||||
}
|
||||
}
|
||||
} catch (e: SecurityException) {
|
||||
Log.e(tag, "$tag: ${e.message}")
|
||||
} catch (e: Exception) {
|
||||
Log.e(tag, "$tag: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun isBTConnected():Boolean
|
||||
{
|
||||
return connected
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
fun reportRotation(format: String, azimuth: Int, elevation: Int) {
|
||||
if (connected) {
|
||||
rotationReportingJob = reporterScope.launch {
|
||||
try {
|
||||
val azimuthString = intToStringWithLeadingZeroes(azimuth)
|
||||
val elevationString = intToStringWithLeadingZeroes(elevation)
|
||||
val crChar = '\r'
|
||||
val nlChar = '\n'
|
||||
val tbChar = '\t'
|
||||
var buffer = format.replace("\$AZ", azimuthString)
|
||||
buffer = buffer.replace("\$EL", elevationString)
|
||||
buffer = buffer.replace("\\r", crChar.toString())
|
||||
buffer = buffer.replace("\\n", nlChar.toString())
|
||||
buffer = buffer.replace("\\t", tbChar.toString())
|
||||
Log.i(tag, "$tag: Sending $buffer")
|
||||
if (connected) outputStream.write(buffer.toByteArray())
|
||||
} catch (e: Exception) {
|
||||
Log.e(tag, "$tag: ${e.message}")
|
||||
connected = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun connectInProg():Boolean
|
||||
{
|
||||
return connectInProgress
|
||||
}
|
||||
|
||||
|
||||
fun reportRotationBT(dev: String, fmt: String, AZ: Int, EL: Int) {
|
||||
|
||||
runCatching {
|
||||
var azStr:String
|
||||
var elStr:String
|
||||
satVisible=(EL>1)
|
||||
|
||||
//Need to add leading zeros to string to ensure always 3 digits.
|
||||
//Ideally this could be done via the format string but this will do for now.
|
||||
if(AZ<100){
|
||||
if(AZ<10){
|
||||
azStr="00"
|
||||
}
|
||||
else
|
||||
{
|
||||
azStr="0"
|
||||
}
|
||||
azStr=azStr.plus(AZ.toString())
|
||||
}
|
||||
else
|
||||
{
|
||||
azStr=AZ.toString()
|
||||
}
|
||||
|
||||
if(EL<100){
|
||||
if(EL<10){
|
||||
elStr="00"
|
||||
}
|
||||
else
|
||||
{
|
||||
elStr="0"
|
||||
}
|
||||
if(satVisible) {
|
||||
elStr = elStr.plus(EL.toString())
|
||||
}
|
||||
else {
|
||||
elStr="000"
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
elStr=EL.toString()
|
||||
}
|
||||
|
||||
var buffer = fmt.replace("\$AZ",azStr)
|
||||
buffer = buffer.replace("\$EL",elStr)
|
||||
buffer = buffer.replace("\\r",CRchar.toString())
|
||||
buffer = buffer.replace("\\n",NLchar.toString())
|
||||
buffer = buffer.replace("\\t",TBchar.toString())
|
||||
Log.i("Output is", buffer)
|
||||
if(connected) {
|
||||
Log.i("Sending BT", buffer)
|
||||
this.mmOutStream.write(buffer.toByteArray())
|
||||
Log.i("Sent", buffer)
|
||||
}
|
||||
}.onFailure { error: Throwable ->
|
||||
Log.e("BT Error","${error.message}")
|
||||
connected=false
|
||||
private fun intToStringWithLeadingZeroes(value: Int): String {
|
||||
return if (value > 0) {
|
||||
if (value < 10) "00$value" else if (value < 100) "0$value" else "$value"
|
||||
} else {
|
||||
val absValue = abs(value)
|
||||
if (value > -10) "-00$absValue" else if (value > -100) "-0$absValue" else "-$absValue"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-18
@@ -42,8 +42,8 @@ import javax.inject.Inject
|
||||
class RadarViewModel @Inject constructor(
|
||||
private val orientationManager: OrientationManager,
|
||||
private val reporter: DataReporter,
|
||||
private val BTreporter: BTReporter,
|
||||
private val satelliteManager: ISatelliteManager,
|
||||
private val btReporter: BTReporter,
|
||||
private val satManager: ISatelliteManager,
|
||||
private val repository: IDataRepository,
|
||||
private val settings: ISettingsManager
|
||||
) : ViewModel(), OrientationManager.OrientationListener {
|
||||
@@ -57,7 +57,7 @@ class RadarViewModel @Inject constructor(
|
||||
val orientation: LiveData<Triple<Float, Float, Float>> = _orientation
|
||||
|
||||
fun getPass(catNum: Int, aosTime: Long) = liveData {
|
||||
satelliteManager.calculatedPasses.collect { passes ->
|
||||
satManager.calculatedPasses.collect { passes ->
|
||||
val pass = passes.find { pass -> pass.catNum == catNum && pass.aosTime == aosTime }
|
||||
pass?.let { satPass ->
|
||||
emit(satPass)
|
||||
@@ -94,12 +94,11 @@ class RadarViewModel @Inject constructor(
|
||||
viewModelScope.launch {
|
||||
var satTrack: List<SatPos> = emptyList()
|
||||
if (!satPass.isDeepSpace) {
|
||||
val startDate = satPass.aosTime
|
||||
val endDate = satPass.losTime
|
||||
satTrack = satelliteManager.getTrack(satPass.satellite, stationPos, startDate, endDate)
|
||||
satTrack = satManager
|
||||
.getTrack(satPass.satellite, stationPos, satPass.aosTime, satPass.losTime)
|
||||
}
|
||||
while (isActive) {
|
||||
val satPos = satelliteManager.getPosition(satPass.satellite, stationPos, Date().time)
|
||||
val satPos = satManager.getPosition(satPass.satellite, stationPos, Date().time)
|
||||
if (settings.getRotatorEnabled()) {
|
||||
val server = settings.getRotatorServer()
|
||||
val port = settings.getRotatorPort().toInt()
|
||||
@@ -116,21 +115,20 @@ class RadarViewModel @Inject constructor(
|
||||
private fun sendPassDataBT(satPass: SatPass) {
|
||||
viewModelScope.launch {
|
||||
while (isActive) {
|
||||
val satPos = satelliteManager.getPosition(satPass.satellite, stationPos, Date().time)
|
||||
val satPos = satManager.getPosition(satPass.satellite, stationPos, Date().time)
|
||||
if (settings.getBTEnabled()) {
|
||||
val server = settings.getBTDeviceAddr()
|
||||
if(BTreporter.isBTConnected()) {
|
||||
val port = settings.getBTFormat()
|
||||
val btDevice = settings.getBTDeviceAddr()
|
||||
if (btReporter.isConnected()) {
|
||||
val format = settings.getBTFormat()
|
||||
val azimuth = satPos.azimuth.toDegrees().round(0).toInt()
|
||||
val elevation = satPos.elevation.toDegrees().round(0).toInt()
|
||||
BTreporter.reportRotationBT(server, port, azimuth, elevation)
|
||||
}
|
||||
else if(!BTreporter.connectInProg()) {
|
||||
Log.i("look4satBT", "Attempting to connect...")
|
||||
BTreporter.connectBTDevice(server)
|
||||
btReporter.reportRotation(format, azimuth, elevation)
|
||||
} else if (!btReporter.isConnecting()) {
|
||||
Log.i("BTReporter", "BTReporter: Attempting to connect...")
|
||||
btReporter.connectBTDevice(btDevice)
|
||||
}
|
||||
}
|
||||
delay(2000)
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,7 +139,7 @@ class RadarViewModel @Inject constructor(
|
||||
val transmitters = repository.getRadiosWithId(pass.catNum)
|
||||
while (isActive) {
|
||||
val time = System.currentTimeMillis()
|
||||
val list = satelliteManager.processRadios(pass.satellite, stationPos, transmitters, time)
|
||||
val list = satManager.processRadios(pass.satellite, stationPos, transmitters, time)
|
||||
_transmitters.postValue(list)
|
||||
delay(1000)
|
||||
}
|
||||
|
||||
+26
-15
@@ -17,15 +17,13 @@
|
||||
*/
|
||||
package com.rtbishop.look4sat.presentation.settingsScreen
|
||||
|
||||
//import com.rtbishop.look4sat.BuildConfig
|
||||
import android.Manifest
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.View
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.widget.NestedScrollView
|
||||
@@ -34,6 +32,7 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.rtbishop.look4sat.BuildConfig
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.databinding.FragmentSettingsBinding
|
||||
import com.rtbishop.look4sat.domain.model.DataState
|
||||
@@ -44,11 +43,21 @@ import com.rtbishop.look4sat.utility.isValidIPv4
|
||||
import com.rtbishop.look4sat.utility.isValidPort
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
|
||||
@AndroidEntryPoint
|
||||
class SettingsFragment : Fragment(R.layout.fragment_settings) {
|
||||
|
||||
private val viewModel: SettingsViewModel by viewModels()
|
||||
private val bluetooth = when {
|
||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.S -> Manifest.permission.BLUETOOTH
|
||||
else -> Manifest.permission.BLUETOOTH_CONNECT
|
||||
}
|
||||
private val bluetoothContract = ActivityResultContracts.RequestPermission()
|
||||
private val bluetoothRequest = registerForActivityResult(bluetoothContract) { isGranted ->
|
||||
if (!isGranted) {
|
||||
showToast(getString(R.string.BTremote_perm_error))
|
||||
toggleBTstate(isGranted)
|
||||
}
|
||||
}
|
||||
private val locationFine = Manifest.permission.ACCESS_FINE_LOCATION
|
||||
private val locationCoarse = Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
private val locationContract = ActivityResultContracts.RequestMultiplePermissions()
|
||||
@@ -73,7 +82,7 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
|
||||
if (y > newY) settingsFab.hide() else settingsFab.show()
|
||||
})
|
||||
settingsAbout.aboutVersion.text =
|
||||
String.format(getString(R.string.app_version), 0)
|
||||
String.format(getString(R.string.app_version), BuildConfig.VERSION_NAME)
|
||||
settingsBtnGithub.clickWithDebounce {
|
||||
gotoUrl("https://github.com/rt-bishop/Look4Sat/")
|
||||
}
|
||||
@@ -84,8 +93,6 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
|
||||
gotoUrl("https://f-droid.org/en/packages/com.rtbishop.look4sat/")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setupLocationCard()
|
||||
setupDataCard()
|
||||
setupRemoteCard()
|
||||
@@ -154,7 +161,6 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
|
||||
settingsRemote.remotePort.isEnabled = isChecked
|
||||
settingsRemote.remotePortEdit.setText(viewModel.getRotatorPort())
|
||||
setOnCheckedChangeListener { _, isChecked ->
|
||||
viewModel.setRotatorEnabled(isChecked)
|
||||
settingsRemote.remoteIp.isEnabled = isChecked
|
||||
settingsRemote.remotePort.isEnabled = isChecked
|
||||
}
|
||||
@@ -169,31 +175,36 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
|
||||
}
|
||||
|
||||
private fun setupBTCard() {
|
||||
|
||||
binding.run {
|
||||
settingsBtremote.BTremoteSwitch.apply {
|
||||
isChecked = viewModel.getBTEnabled()
|
||||
settingsBtremote.BTremoteAddress.isEnabled = isChecked
|
||||
settingsBtremote.BTremoteFormat.isEnabled = isChecked
|
||||
settingsBtremote.BTAddressEdit.setText(viewModel.getBTDeviceAddr())
|
||||
settingsBtremote.BTremoteFormat.isEnabled = isChecked
|
||||
settingsBtremote.BTFormatEdit.setText(viewModel.getBTFormat())
|
||||
setOnCheckedChangeListener { _, isChecked ->
|
||||
viewModel.setBTEnabled(isChecked)
|
||||
settingsBtremote.BTremoteAddress.isEnabled = isChecked
|
||||
settingsBtremote.BTremoteFormat.isEnabled = isChecked
|
||||
toggleBTstate(isChecked)
|
||||
bluetoothRequest.launch(bluetooth)
|
||||
}
|
||||
}
|
||||
|
||||
settingsBtremote.BTAddressEdit.doOnTextChanged { text, _, _, _ ->
|
||||
viewModel.setBTDeviceAddr(text.toString())
|
||||
}
|
||||
|
||||
settingsBtremote.BTFormatEdit.doOnTextChanged { text, _, _, _ ->
|
||||
viewModel.setBTFormat(text.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleBTstate(value: Boolean) {
|
||||
binding.run {
|
||||
viewModel.setBTEnabled(value)
|
||||
settingsBtremote.BTremoteSwitch.isChecked = value
|
||||
settingsBtremote.BTremoteAddress.isEnabled = value
|
||||
settingsBtremote.BTremoteFormat.isEnabled = value
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupOtherCard() {
|
||||
binding.run {
|
||||
settingsOther.otherSwitchUtc.apply {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/SurfaceCard">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
@@ -38,27 +37,28 @@
|
||||
android:id="@+id/BTremote_address"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/BTremote_switch"
|
||||
app:layout_constraintEnd_toEndOf="@+id/BTremote_title"
|
||||
app:layout_constraintStart_toStartOf="@+id/BTremote_title"
|
||||
tools:layout_editor_absoluteY="70dp">
|
||||
app:layout_constraintEnd_toEndOf="@+id/BTremote_switch"
|
||||
app:layout_constraintStart_toStartOf="@+id/BTremote_switch"
|
||||
app:layout_constraintTop_toBottomOf="@id/BTremote_switch">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/BT_address_edit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:hint="@string/BTremote_device_hint"
|
||||
android:textColorHint="@color/textMain" />
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/BT_address_edit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:hint="@string/BTremote_device_hint"
|
||||
android:textColorHint="@color/textMain" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/BTremote_format"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/BTremote_address"
|
||||
app:layout_constraintEnd_toEndOf="@+id/BTremote_title"
|
||||
app:layout_constraintStart_toStartOf="@+id/BTremote_title"
|
||||
tools:layout_editor_absoluteY="70dp">
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@+id/BTremote_address"
|
||||
app:layout_constraintStart_toStartOf="@+id/BTremote_address"
|
||||
app:layout_constraintTop_toBottomOf="@id/BTremote_address">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/BT_format_edit"
|
||||
|
||||
@@ -48,7 +48,9 @@
|
||||
android:id="@+id/remote_ip_edit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:digits="0123456789."
|
||||
android:hint="@string/remote_ip_hint"
|
||||
android:inputType="number"
|
||||
android:textColorHint="@color/textMain" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
@@ -67,6 +69,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/remote_port_hint"
|
||||
android:inputType="number"
|
||||
android:textColorHint="@color/textMain" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
@@ -57,7 +57,8 @@
|
||||
android:id="@+id/position_lat_edit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:inputType="textUri" />
|
||||
android:digits="0123456789."
|
||||
android:inputType="number" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
@@ -94,7 +95,8 @@
|
||||
android:id="@+id/position_lon_edit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:inputType="textUri" />
|
||||
android:digits="0123456789."
|
||||
android:inputType="number" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
@@ -138,6 +138,12 @@
|
||||
<string name="remote_ip_hint">IP адрес</string>
|
||||
<string name="remote_port_hint">Порт</string>
|
||||
|
||||
<string name="BTremote_title">Передача данных по Bluetooth</string>
|
||||
<string name="BTremote_switch">Включить передачу</string>
|
||||
<string name="BTremote_device_hint">Id устройства</string>
|
||||
<string name="BTremote_output_hint">Формат данных</string>
|
||||
<string name="BTremote_perm_error">Нет разрешения использовать bluetooth</string>
|
||||
|
||||
<string name="other_title">Другие настройки</string>
|
||||
<string name="other_switch_utc">Показывать время по UTC</string>
|
||||
<string name="other_switch_sweep">Показывать анимацию радара</string>
|
||||
|
||||
@@ -139,10 +139,11 @@
|
||||
<string name="remote_ip_hint">IP address</string>
|
||||
<string name="remote_port_hint">Port</string>
|
||||
|
||||
<string name="BTremote_title">Bluetooth Output</string>
|
||||
<string name="BTremote_switch">Enable Bluetooth</string>
|
||||
<string name="BTremote_device_hint">Device</string>
|
||||
<string name="BTremote_output_hint">Output format</string>
|
||||
<string name="BTremote_title">Bluetooth data output</string>
|
||||
<string name="BTremote_switch">Enable output</string>
|
||||
<string name="BTremote_device_hint">Device id</string>
|
||||
<string name="BTremote_output_hint">Data format</string>
|
||||
<string name="BTremote_perm_error">Check your bluetooth permission</string>
|
||||
|
||||
<string name="other_title">Other preferences</string>
|
||||
<string name="other_switch_utc">Show pass time in UTC</string>
|
||||
|
||||
+2
-2
@@ -13,9 +13,9 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0"
|
||||
implementation "org.json:json:20211205"
|
||||
implementation "org.json:json:20220320"
|
||||
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
testImplementation "org.mockito:mockito-core:4.3.1"
|
||||
testImplementation "org.mockito:mockito-core:4.4.0"
|
||||
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0"
|
||||
}
|
||||
@@ -67,7 +67,8 @@ fun String.isValidIPv4(): Boolean {
|
||||
}
|
||||
|
||||
fun String.isValidPort(): Boolean {
|
||||
return this.isNotEmpty() && this.toInt() in 1024..65535
|
||||
val port = "([1-9]|[1-9]\\d{1,3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])"
|
||||
return this.matches(port.toRegex()) && this.toInt() in 1024..65535
|
||||
}
|
||||
|
||||
fun ping(hostname: String, port: Int): Int {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath "com.google.dagger:hilt-android-gradle-plugin:2.40.5"
|
||||
classpath "com.google.dagger:hilt-android-gradle-plugin:2.41"
|
||||
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.4.1"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user