mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
commit
9cd1856bb9
15 changed files with 116 additions and 108 deletions
|
|
@ -43,8 +43,8 @@ android {
|
|||
applicationId "com.geeksville.mesh"
|
||||
minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works)
|
||||
targetSdkVersion 30 // 30 can't work until an explicit location permissions dialog is added
|
||||
versionCode 20256 // format is Mmmss (where M is 1+the numeric major number
|
||||
versionName "1.2.56"
|
||||
versionCode 20257 // format is Mmmss (where M is 1+the numeric major number
|
||||
versionName "1.2.57"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
// per https://developer.android.com/studio/write/vector-asset-studio
|
||||
|
|
@ -127,7 +127,7 @@ dependencies {
|
|||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'androidx.core:core-ktx:1.7.0'
|
||||
implementation 'androidx.fragment:fragment-ktx:1.4.0'
|
||||
implementation 'androidx.fragment:fragment-ktx:1.4.1'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||
|
|
@ -177,7 +177,7 @@ dependencies {
|
|||
implementation 'com.google.android.gms:play-services-location:19.0.1'
|
||||
|
||||
// For Google Sign-In (owner name accesss)
|
||||
implementation 'com.google.android.gms:play-services-auth:20.0.1'
|
||||
implementation 'com.google.android.gms:play-services-auth:20.1.0'
|
||||
|
||||
// Add the Firebase SDK for Crashlytics.
|
||||
implementation 'com.google.firebase:firebase-crashlytics:18.2.6'
|
||||
|
|
@ -191,6 +191,7 @@ dependencies {
|
|||
// barcode support
|
||||
// per https://github.com/journeyapps/zxing-android-embedded#older-sdk-versions for minSdkVersion 21
|
||||
implementation('com.journeyapps:zxing-android-embedded:4.3.0') { transitive = false }
|
||||
//noinspection GradleDependency
|
||||
implementation 'com.google.zxing:core:3.3.0' // <-- don't update
|
||||
|
||||
def work_version = '2.7.1'
|
||||
|
|
|
|||
|
|
@ -4,11 +4,7 @@ import android.Manifest
|
|||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.bluetooth.BluetoothManager
|
||||
import android.companion.AssociationRequest
|
||||
import android.companion.BluetoothDeviceFilter
|
||||
import android.companion.CompanionDeviceManager
|
||||
import android.content.*
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
|
|
@ -27,7 +23,6 @@ import android.view.View
|
|||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
|
|
@ -70,8 +65,6 @@ import kotlinx.coroutines.cancel
|
|||
import java.nio.charset.Charset
|
||||
import java.text.DateFormat
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
|
||||
|
||||
/*
|
||||
UI design
|
||||
|
|
@ -198,48 +191,6 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
updateBluetoothEnabled()
|
||||
}
|
||||
|
||||
fun startCompanionScan() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val deviceManager: CompanionDeviceManager by lazy {
|
||||
getSystemService(Context.COMPANION_DEVICE_SERVICE) as CompanionDeviceManager
|
||||
}
|
||||
|
||||
// To skip filtering based on name and supported feature flags (UUIDs),
|
||||
// don't include calls to setNamePattern() and addServiceUuid(),
|
||||
// respectively. This example uses Bluetooth.
|
||||
// We only look for Mesh (rather than the full name) because NRF52 uses a very short name
|
||||
val deviceFilter: BluetoothDeviceFilter = BluetoothDeviceFilter.Builder()
|
||||
.setNamePattern(Pattern.compile("Mesh.*"))
|
||||
// .addServiceUuid(ParcelUuid(RadioInterfaceService.BTM_SERVICE_UUID), null)
|
||||
.build()
|
||||
|
||||
// The argument provided in setSingleDevice() determines whether a single
|
||||
// device name or a list of device names is presented to the user as
|
||||
// pairing options.
|
||||
val pairingRequest: AssociationRequest = AssociationRequest.Builder()
|
||||
.addDeviceFilter(deviceFilter)
|
||||
.setSingleDevice(false)
|
||||
.build()
|
||||
|
||||
// When the app tries to pair with the Bluetooth device, show the
|
||||
// appropriate pairing request dialog to the user.
|
||||
deviceManager.associate(pairingRequest,
|
||||
object : CompanionDeviceManager.Callback() {
|
||||
override fun onDeviceFound(chooserLauncher: IntentSender) {
|
||||
startIntentSenderForResult(chooserLauncher,
|
||||
SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0)
|
||||
}
|
||||
|
||||
override fun onFailure(error: CharSequence?) {
|
||||
warn("BLE selection service failed $error")
|
||||
// changeDeviceSelection(mainActivity, null) // deselect any device
|
||||
}
|
||||
}, null
|
||||
)
|
||||
}
|
||||
else warn("startCompanionScan should not run on SDK < 26")
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't tell our app we have bluetooth until we have bluetooth _and_ location access
|
||||
*/
|
||||
|
|
@ -502,8 +453,6 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
|
||||
/* not yet working
|
||||
// Configure sign-in to request the user's ID, email address, and basic
|
||||
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
|
||||
// Configure sign-in to request the user's ID, email address, and basic
|
||||
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
|
||||
val gso =
|
||||
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||
|
|
@ -629,7 +578,6 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
/**
|
||||
* Dispatch incoming result to the correct fragment.
|
||||
*/
|
||||
@SuppressLint("InlinedApi", "MissingPermission")
|
||||
override fun onActivityResult(
|
||||
requestCode: Int,
|
||||
resultCode: Int,
|
||||
|
|
@ -637,7 +585,6 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
// Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
|
||||
// Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
|
||||
when (requestCode) {
|
||||
RC_SIGN_IN -> {
|
||||
|
|
@ -647,19 +594,6 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
GoogleSignIn.getSignedInAccountFromIntent(data)
|
||||
handleSignInResult(task)
|
||||
}
|
||||
(SELECT_DEVICE_REQUEST_CODE) -> when (resultCode) {
|
||||
Activity.RESULT_OK -> {
|
||||
val deviceToPair: BluetoothDevice =
|
||||
data?.getParcelableExtra(CompanionDeviceManager.EXTRA_DEVICE)!!
|
||||
if (deviceToPair.bondState != BluetoothDevice.BOND_BONDED) {
|
||||
deviceToPair.createBond()
|
||||
}
|
||||
model.meshService?.let { service ->
|
||||
MeshService.changeDeviceAddress(this@MainActivity, service, "x${deviceToPair.address}")
|
||||
}
|
||||
}
|
||||
else -> warn("BLE device select intent failed")
|
||||
}
|
||||
CREATE_CSV_FILE -> {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
data?.data?.let { file_uri -> model.saveMessagesCSV(file_uri) }
|
||||
|
|
@ -1161,7 +1095,7 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = "application/csv"
|
||||
putExtra(Intent.EXTRA_TITLE, "messages.csv")
|
||||
putExtra(Intent.EXTRA_TITLE, "rangetest.csv")
|
||||
}
|
||||
startActivityForResult(intent, CREATE_CSV_FILE)
|
||||
return true
|
||||
|
|
@ -1189,7 +1123,7 @@ class MainActivity : AppCompatActivity(), Logging,
|
|||
private fun chooseThemeDialog() {
|
||||
|
||||
/// Prepare dialog and its items
|
||||
val builder = AlertDialog.Builder(this)
|
||||
val builder = MaterialAlertDialogBuilder(this)
|
||||
builder.setTitle(getString(R.string.choose_theme_title))
|
||||
|
||||
val styles = arrayOf(
|
||||
|
|
|
|||
|
|
@ -113,7 +113,9 @@ class BluetoothInterface(val service: RadioInterfaceService, val address: String
|
|||
@SuppressLint("NewApi", "MissingPermission")
|
||||
override fun addressValid(context: Context, rest: String): Boolean {
|
||||
val allPaired = if (hasCompanionDeviceApi(context)) {
|
||||
val deviceManager = context.getSystemService(CompanionDeviceManager::class.java)
|
||||
val deviceManager: CompanionDeviceManager by lazy {
|
||||
context.getSystemService(Context.COMPANION_DEVICE_SERVICE) as CompanionDeviceManager
|
||||
}
|
||||
deviceManager.associations.map { it }.toSet()
|
||||
} else {
|
||||
getBluetoothAdapter(context)?.bondedDevices.orEmpty()
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ class RadioInterfaceService : Service(), Logging {
|
|||
@SuppressLint("NewApi")
|
||||
private fun setBondedDeviceAddress(address: String?): Boolean {
|
||||
return if (getBondedDeviceAddress(this) == address && isStarted) {
|
||||
warn("Ignoring setBondedDevice $address, because we are already using that device")
|
||||
warn("Ignoring setBondedDevice ${address.anonymize}, because we are already using that device")
|
||||
false
|
||||
} else {
|
||||
// Record that this use has configured a new radio
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
|
|||
requireActivity().startActivity(shareIntent)
|
||||
} catch (ex: ActivityNotFoundException) {
|
||||
Snackbar.make(
|
||||
binding.shareButton,
|
||||
requireView(),
|
||||
R.string.no_app_found,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
|
|
@ -181,7 +181,7 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
|
|||
|
||||
// Tell the user to try again
|
||||
Snackbar.make(
|
||||
binding.editableCheckbox,
|
||||
requireView(),
|
||||
R.string.radio_sleeping,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
|
|
|
|||
|
|
@ -1,28 +1,26 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.app.PendingIntent
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.bluetooth.BluetoothDevice.BOND_BONDED
|
||||
import android.bluetooth.BluetoothDevice.BOND_BONDING
|
||||
import android.bluetooth.le.*
|
||||
import android.companion.AssociationRequest
|
||||
import android.companion.BluetoothDeviceFilter
|
||||
import android.companion.CompanionDeviceManager
|
||||
import android.content.*
|
||||
import android.content.pm.PackageManager
|
||||
import android.hardware.usb.UsbDevice
|
||||
import android.hardware.usb.UsbManager
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.RemoteException
|
||||
import android.os.*
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.RadioButton
|
||||
import android.widget.TextView
|
||||
import android.widget.*
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
|
|
@ -53,6 +51,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import java.util.regex.Pattern
|
||||
|
||||
object SLogging : Logging
|
||||
|
||||
|
|
@ -458,6 +457,10 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
BluetoothInterface.hasCompanionDeviceApi(requireContext())
|
||||
}
|
||||
|
||||
private val deviceManager: CompanionDeviceManager by lazy {
|
||||
requireContext().getSystemService(Context.COMPANION_DEVICE_SERVICE) as CompanionDeviceManager
|
||||
}
|
||||
|
||||
private val myActivity get() = requireActivity() as MainActivity
|
||||
|
||||
override fun onDestroy() {
|
||||
|
|
@ -656,12 +659,15 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
}
|
||||
}
|
||||
|
||||
scanModel.devices.observe(viewLifecycleOwner) { devices ->
|
||||
updateDevicesButtons(devices)
|
||||
}
|
||||
|
||||
binding.updateFirmwareButton.setOnClickListener {
|
||||
doFirmwareUpdate()
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setMessage("${getString(R.string.update_firmware)}?")
|
||||
.setNeutralButton(R.string.cancel) { _, _ ->
|
||||
}
|
||||
.setPositiveButton(getString(R.string.okay)) { _, _ ->
|
||||
doFirmwareUpdate()
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
binding.usernameEditText.on(EditorInfo.IME_ACTION_DONE) {
|
||||
|
|
@ -724,6 +730,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
}
|
||||
.setPositiveButton(getString(R.string.report)) { _, _ ->
|
||||
reportError("Clicked Report A Bug")
|
||||
Toast.makeText(requireContext(), "Bug report sent!", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
|
@ -814,6 +821,10 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
|
||||
private fun initClassicScan() {
|
||||
|
||||
scanModel.devices.observe(viewLifecycleOwner) { devices ->
|
||||
updateDevicesButtons(devices)
|
||||
}
|
||||
|
||||
binding.changeRadioButton.setOnClickListener {
|
||||
debug("User clicked changeRadioButton")
|
||||
if (!myActivity.hasScanPermission()) {
|
||||
|
|
@ -846,17 +857,65 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
}
|
||||
}
|
||||
|
||||
private fun startCompanionScan() {
|
||||
// Disable the change button until our scan has some results
|
||||
binding.changeRadioButton.isEnabled = false
|
||||
|
||||
// To skip filtering based on name and supported feature flags (UUIDs),
|
||||
// don't include calls to setNamePattern() and addServiceUuid(),
|
||||
// respectively. This example uses Bluetooth.
|
||||
// We only look for Mesh (rather than the full name) because NRF52 uses a very short name
|
||||
val deviceFilter: BluetoothDeviceFilter = BluetoothDeviceFilter.Builder()
|
||||
.setNamePattern(Pattern.compile("Mesh.*"))
|
||||
// .addServiceUuid(ParcelUuid(RadioInterfaceService.BTM_SERVICE_UUID), null)
|
||||
.build()
|
||||
|
||||
// The argument provided in setSingleDevice() determines whether a single
|
||||
// device name or a list of device names is presented to the user as
|
||||
// pairing options.
|
||||
val pairingRequest: AssociationRequest = AssociationRequest.Builder()
|
||||
.addDeviceFilter(deviceFilter)
|
||||
.setSingleDevice(false)
|
||||
.build()
|
||||
|
||||
// When the app tries to pair with the Bluetooth device, show the
|
||||
// appropriate pairing request dialog to the user.
|
||||
deviceManager.associate(
|
||||
pairingRequest,
|
||||
object : CompanionDeviceManager.Callback() {
|
||||
|
||||
override fun onDeviceFound(chooserLauncher: IntentSender) {
|
||||
debug("Found one device - enabling changeRadioButton")
|
||||
binding.changeRadioButton.isEnabled = true
|
||||
binding.changeRadioButton.setOnClickListener {
|
||||
debug("User clicked changeRadioButton")
|
||||
try {
|
||||
startIntentSenderForResult(
|
||||
chooserLauncher,
|
||||
MainActivity.SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0, null
|
||||
)
|
||||
} catch (ex: Throwable) {
|
||||
errormsg("CompanionDevice startIntentSenderForResult error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(error: CharSequence?) {
|
||||
warn("BLE selection service failed $error")
|
||||
// changeDeviceSelection(myActivity, null) // deselect any device
|
||||
}
|
||||
}, null
|
||||
)
|
||||
}
|
||||
|
||||
private fun initModernScan() {
|
||||
|
||||
binding.changeRadioButton.setOnClickListener {
|
||||
debug("User clicked changeRadioButton")
|
||||
if (!myActivity.hasScanPermission()) {
|
||||
myActivity.requestScanPermission()
|
||||
} else {
|
||||
// checkLocationEnabled() // ? some phones still need location turned on
|
||||
myActivity.startCompanionScan()
|
||||
}
|
||||
scanModel.devices.observe(viewLifecycleOwner) { devices ->
|
||||
updateDevicesButtons(devices)
|
||||
startCompanionScan()
|
||||
}
|
||||
|
||||
startCompanionScan()
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
|
@ -894,7 +953,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
fun weNeedAccess(warningReason: String) {
|
||||
warn("Telling user we need need location access")
|
||||
|
||||
Snackbar.make(binding.changeRadioButton, warningReason, Snackbar.LENGTH_INDEFINITE)
|
||||
Snackbar.make(requireView(), warningReason, Snackbar.LENGTH_INDEFINITE)
|
||||
.apply { view.findViewById<TextView>(R.id.snackbar_text).isSingleLine = false }
|
||||
.setAction(R.string.okay) {
|
||||
// dismiss
|
||||
|
|
@ -964,7 +1023,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
// Warn user if BLE is disabled
|
||||
if (scanModel.bluetoothAdapter?.isEnabled != true) {
|
||||
Snackbar.make(
|
||||
binding.changeRadioButton,
|
||||
requireView(),
|
||||
R.string.error_bluetooth,
|
||||
Snackbar.LENGTH_INDEFINITE
|
||||
)
|
||||
|
|
@ -978,4 +1037,20 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
||||
&& requestCode == MainActivity.SELECT_DEVICE_REQUEST_CODE
|
||||
&& resultCode == Activity.RESULT_OK
|
||||
) {
|
||||
val deviceToPair: BluetoothDevice =
|
||||
data?.getParcelableExtra(CompanionDeviceManager.EXTRA_DEVICE)!!
|
||||
if (deviceToPair.bondState != BOND_BONDED) {
|
||||
deviceToPair.createBond()
|
||||
}
|
||||
scanModel.changeScanSelection(myActivity, "x${deviceToPair.address}")
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@
|
|||
<string name="region">Región</string>
|
||||
<string name="cant_change_no_radio">No se puede cambiar de canal porque la radio aún no está conectada. Por favor inténtelo de nuevo.</string>
|
||||
<string name="sample_coords">55.332244 34.442211</string>
|
||||
<string name="save_messages">Guardar mensajes como csv...</string>
|
||||
<string name="save_messages">Guardar rangetest.csv</string>
|
||||
<string name="set_channel_options">Establecer las opciones de los canales</string>
|
||||
<string name="reset">Reiniciar</string>
|
||||
<string name="are_you_shure_change_default">¿Estás seguro de que quieres cambiar al canal por defecto?</string>
|
||||
|
|
|
|||
|
|
@ -91,7 +91,6 @@
|
|||
<string name="region">Régió</string>
|
||||
<string name="cant_change_no_radio">Nem lehet csatornát váltani, mert a rádió nincs csatlakoztatva. Kérem próbálja meg újra.</string>
|
||||
<string name="sample_coords">55.332244 34.442211</string>
|
||||
<string name="save_messages">Üzenetek mentése csv fájlba...</string>
|
||||
<string name="set_channel_options">Csatorna paraméterek beállítása</string>
|
||||
<string name="reset">Újraindítás</string>
|
||||
<string name="are_you_shure_change_default">Biztosan meg akarja változtatni az alapértelmezett csatornát?</string>
|
||||
|
|
|
|||
|
|
@ -97,7 +97,6 @@
|
|||
<string name="region">Region</string>
|
||||
<string name="cant_change_no_radio">Nie można zmienić kanału, ponieważ urządzenie nie jest jeszcze połączone. Proszę spróbuj jeszcze raz.</string>
|
||||
<string name="sample_coords">55.332244 34.442211</string>
|
||||
<string name="save_messages">Zapisz wiadomości jako csv...</string>
|
||||
<string name="set_channel_options">Ustaw właściwości kanału.</string>
|
||||
<string name="reset">Reset</string>
|
||||
<string name="are_you_shure_change_default">Na pewno chcesz zmienić na domyślny kanał?</string>
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@
|
|||
<string name="region">Região</string>
|
||||
<string name="cant_change_no_radio">Não foi possível mudar de canal, rádio não conectado. Tente novamente.</string>
|
||||
<string name="sample_coords">55.332244 34.442211</string>
|
||||
<string name="save_messages">Salvar mensagens como .CSV…</string>
|
||||
<string name="save_messages">Exportar rangetest.csv</string>
|
||||
<string name="set_channel_options">Configurar opções do canal</string>
|
||||
<string name="reset">Redefinir</string>
|
||||
<string name="are_you_shure_change_default">Tem certeza que quer mudar para o canal padrão?</string>
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@
|
|||
<string name="region">Região</string>
|
||||
<string name="cant_change_no_radio">Não foi possível mudar de canal, rádio não conectado. Tente novamente.</string>
|
||||
<string name="sample_coords">55.332244 34.442211</string>
|
||||
<string name="save_messages">Salvar mensagens como .CSV…</string>
|
||||
<string name="save_messages">Exportar rangetest.csv</string>
|
||||
<string name="set_channel_options">Configurar opções do canal</string>
|
||||
<string name="reset">Redefinir</string>
|
||||
<string name="are_you_shure_change_default">Tem certeza que quer mudar para o canal padrão?</string>
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@
|
|||
<string name="must_set_region">Musíte nastaviť región!</string>
|
||||
<string name="region">Región</string>
|
||||
<string name="sample_coords">48.14816 17.10674</string>
|
||||
<string name="save_messages">Ulož spávy ako CSV súbor</string>
|
||||
<string name="set_channel_options">Nastaviť kanál</string>
|
||||
<string name="reset">Resetovať</string>
|
||||
<string name="reset_to_defaults">Resetovať na základné (default) nastavenia</string>
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@
|
|||
<string name="region">地区</string>
|
||||
<string name="cant_change_no_radio">Couldn\'t change channel, because radio is not yet connected. Please try again.</string>
|
||||
<string name="sample_coords">55.332244 34.442211</string>
|
||||
<string name="save_messages">将消息另存为csv文件</string>
|
||||
<string name="set_channel_options">设置频道选项</string>
|
||||
<string name="reset">重置</string>
|
||||
<string name="are_you_shure_change_default">您确定要更改为默认频道吗?</string>
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@
|
|||
<string name="region">Region</string>
|
||||
<string name="cant_change_no_radio">Couldn\'t change channel, because radio is not yet connected. Please try again.</string>
|
||||
<string name="sample_coords">55.332244 34.442211</string>
|
||||
<string name="save_messages">Save messages as csv...</string>
|
||||
<string name="save_messages">Export rangetest.csv</string>
|
||||
<string name="set_channel_options">Set channel options</string>
|
||||
<string name="reset">Reset</string>
|
||||
<string name="are_you_shure_change_default">Are you sure you want to change to the default channel?</string>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ buildscript {
|
|||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.1.0'
|
||||
classpath 'com.android.tools.build:gradle:7.1.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue