From fc0a0de452fb49bde2c4b78b13c1c95deddc1343 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Aug 2025 11:26:06 -0500 Subject: [PATCH 01/14] chore(deps): update dd.sdk.android to v2.26.0 (#2871) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d6542b5e7..f81c22923 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ core-location-altitude = "1.0.0-alpha03" core-splashscreen = "1.0.1" crashlytics = "3.0.6" datastore = "1.1.7" -dd-sdk-android = "2.25.0" +dd-sdk-android = "2.26.0" dd-sdk-android-gradle-plugin = "1.19.0" detekt = "1.23.8" devtools-ksp = "2.2.10-2.0.2" From a30fef2538fde6ad1c49fa1faff7babf24c9aa44 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Aug 2025 20:09:19 -0500 Subject: [PATCH 02/14] chore(deps): update androidx.compose:compose-bom to v2025.08.01 (#2880) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f81c22923..e1035faef 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ agp = "8.12.1" appcompat = "1.7.1" awesome-app-rating = "2.8.0" coil = "3.3.0" -compose-bom = "2025.08.00" +compose-bom = "2025.08.01" constraintlayout = "2.2.1" core-ktx = "1.17.0" core-location-altitude = "1.0.0-alpha03" From df9d443e9e521df71eb1adfbd5fcc7a57a5b206e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Aug 2025 20:09:30 -0500 Subject: [PATCH 03/14] chore(deps): update adaptive to v1.2.0-beta01 (#2879) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e1035faef..dee69e4bd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ #[allow(unused)] [versions] accompanistPermissions = "0.37.3" -adaptive = "1.2.0-alpha11" +adaptive = "1.2.0-beta01" adaptive-navigation-suite = "1.3.2" agp = "8.12.1" appcompat = "1.7.1" From 4377ba2a04c40225e2e77572330b24f9fb69c176 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Wed, 27 Aug 2025 20:09:42 -0500 Subject: [PATCH 04/14] New Crowdin updates (#2874) --- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index b58753d16..823151ee2 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -739,7 +739,7 @@ Berechtigung erteilen. Bitte aktivieren Sie dies in den Benachrichtigungseinstellungen. Kritische Warnungen konfigurieren - Meshtastic verwendet Benachrichtigungen, um Sie über neue Nachrichten und andere wichtige Ereignisse auf dem Laufenden zu halten. Sie können Ihre Benachrichtigungsrechte jederzeit in den Einstellungen aktualisieren. + Meshtastic nutzt Benachrichtigungen, um Sie über neue Nachrichten und andere wichtige Ereignisse auf dem Laufenden zu halten. Sie können Ihre Benachrichtigungsrechte jederzeit in den Einstellungen aktualisieren. Weiter Berechtigungen erteilen %d Knoten in der Warteschlange zum Löschen: diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index dece5cc0b..8e705991e 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -625,14 +625,14 @@ Heure Date Filtre de carte\n - Seuls les favoris + Juste les favoris Afficher les points de repère Afficher les cercles de précision Notification client Clés compromises détectées, sélectionnez OK pour régénérer. Régénérer la clé privée Êtes-vous sûr de vouloir régénérer votre clé privée ?\n\nLes nœuds qui peuvent avoir précédemment échangé des clés avec ce nœud devront supprimer ce nœud et ré-échanger des clés afin de reprendre une communication sécurisée. - Exporter des clés + Exporter les clés Exporte les clés publiques et privées vers un fichier. Veuillez stocker quelque part en toute sécurité. Modules déverrouillés Distant @@ -664,14 +664,14 @@ Cela supprimera les %1$d nœuds de votre base de données. Cette action ne peut pas être annulée. Un cadenas vert signifie que le canal est chiffré de façon sécurisée avec une clé AES 128 ou 256 bits. - Canal non sécurisé, non précisé - Un cadenas ouvert jaune signifie que le canal n\'est pas crypté de manière sécurisée, n\'est pas utilisé pour des données de localisation précises, et n\'utilise ni une clé du tout, ni une clé connue de 1 octet. + Canal non sécurisé, localisation non précise + Un cadenas ouvert jaune signifie que le canal n\'est pas crypté de manière sécurisée, n\'est pas utilisé pour des données de localisation précises, et n\'utilise aucune clé, ou une clé connue de 1 octet. Canal non sécurisé, localisation précise - Un cadenas rouge ouvert signifie que le canal n\'est pas crypté de manière sécurisée, est utilisé pour des données de localisation précises, et n\'utilise aucune clé du tout, ou une clé connue de 1 octet. + Un cadenas rouge ouvert signifie que le canal n\'est pas crypté de manière sécurisée, est utilisé pour des données de localisation précises, et n\'utilise aucune clé, ou une clé connue de 1 octet. Attention : Localisation précise & MQTT non sécurisée - Un cadenas rouge ouvert avec un avertissement signifie que le canal n\'est pas crypté de manière sécurisée, est utilisé pour des données de localisation précises qui sont placées sur Internet via MQTT, et n\'utilise aucune clé du tout, ou une clé connue de 1 octet. + Un cadenas rouge ouvert avec un avertissement signifie que le canal n\'est pas crypté de manière sécurisée, est utilisé pour des données de localisation précises qui sont diffusées sur Internet via MQTT, et n\'utilise aucune clé, ou une clé connue de 1 octet. Sécurité du canal Signification de la sécurité des canaux From 86ce659bc6fbb1c1f3cd827719d0b001f9ac2f52 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 Aug 2025 01:30:06 +0000 Subject: [PATCH 05/14] chore(deps): update lifecycle to v2.9.3 (#2882) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dee69e4bd..f15f5ce80 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -30,7 +30,7 @@ kotlin = "2.2.10" kotlinx-collections-immutable = "0.4.0" kotlinx-coroutines-android = "1.10.2" kotlinx-serialization-json = "1.9.0" -lifecycle = "2.9.2" +lifecycle = "2.9.3" location-services = "21.3.0" maps-compose = "6.7.2" markdownRenderer = "0.35.0" From ad736116a75628d53b232746760f7ba79392b766 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Wed, 27 Aug 2025 21:21:06 -0500 Subject: [PATCH 06/14] refactor(analytics): consolidate consent logic, move to Settings (#2885) Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- .../mesh/android/GeeksvilleApplication.kt | 27 +---- .../geeksville/mesh/MeshUtilApplication.kt | 53 --------- .../mesh/android/GeeksvilleApplication.kt | 108 ++++++++++++------ .../mesh/repository/radio/StreamInterface.kt | 30 +++-- .../ui/common/components/SwitchPreference.kt | 62 +++++----- .../mesh/ui/connections/Connections.kt | 43 ------- .../ui/settings/components/SettingsItem.kt | 31 ++--- .../mesh/ui/settings/radio/RadioConfig.kt | 16 +++ .../ui/settings/radio/RadioConfigViewModel.kt | 13 +++ app/src/main/res/values/strings.xml | 3 +- 10 files changed, 172 insertions(+), 214 deletions(-) diff --git a/app/src/fdroid/java/com/geeksville/mesh/android/GeeksvilleApplication.kt b/app/src/fdroid/java/com/geeksville/mesh/android/GeeksvilleApplication.kt index 876630f43..936f1d379 100644 --- a/app/src/fdroid/java/com/geeksville/mesh/android/GeeksvilleApplication.kt +++ b/app/src/fdroid/java/com/geeksville/mesh/android/GeeksvilleApplication.kt @@ -40,11 +40,6 @@ abstract class GeeksvilleApplication : lateinit var analytics: AnalyticsProvider } - val isGooglePlayAvailable: Boolean - get() { - return false - } - // / Are we running inside the testlab? val isInTestLab: Boolean get() { @@ -57,19 +52,8 @@ abstract class GeeksvilleApplication : abstract val analyticsPrefs: AnalyticsPrefs - var isAnalyticsAllowed: Boolean - get() = analyticsPrefs.analyticsAllowed - set(value) { - analyticsPrefs.analyticsAllowed = value - - // Change the flag with the providers - analytics.setEnabled(value && !isInTestLab) // Never do analytics in the test lab - } - - @Suppress("UnusedParameter") - fun askToRate(activity: AppCompatActivity) { - // No-op for F-Droid version - } + @Suppress("EmptyFunctionBlock", "UnusedParameter") + fun askToRate(application: AppCompatActivity) {} override fun onCreate() { super.onCreate() @@ -80,13 +64,9 @@ abstract class GeeksvilleApplication : val nopAnalytics = NopAnalytics(this) analytics = nopAnalytics - isAnalyticsAllowed = false } } -val Context.isGooglePlayAvailable: Boolean - get() = false - @Suppress("UnusedParameter") fun setAttributes(deviceVersion: String, deviceHardware: DeviceHardware) { // No-op for F-Droid version @@ -100,3 +80,6 @@ fun AddNavigationTracking(navController: NavHostController) { debug("Navigation changed to: ${destination.route}") } } + +val Context.isAnalyticsAvailable: Boolean + get() = false diff --git a/app/src/google/java/com/geeksville/mesh/MeshUtilApplication.kt b/app/src/google/java/com/geeksville/mesh/MeshUtilApplication.kt index ff6ce2f30..997df57a0 100644 --- a/app/src/google/java/com/geeksville/mesh/MeshUtilApplication.kt +++ b/app/src/google/java/com/geeksville/mesh/MeshUtilApplication.kt @@ -17,69 +17,16 @@ package com.geeksville.mesh -import android.os.Debug -import com.geeksville.mesh.android.BuildUtils.isEmulator import com.geeksville.mesh.android.GeeksvilleApplication import com.geeksville.mesh.android.prefs.AnalyticsPrefs -import com.geeksville.mesh.util.Exceptions -import com.google.firebase.crashlytics.FirebaseCrashlytics -import com.google.firebase.crashlytics.setCustomKeys import dagger.hilt.android.HiltAndroidApp -import timber.log.Timber import javax.inject.Inject @HiltAndroidApp class MeshUtilApplication : GeeksvilleApplication() { - @Inject override lateinit var analyticsPrefs: AnalyticsPrefs override fun onCreate() { super.onCreate() - - // We default to off in the manifest - we turn on here if the user approves - // leave off when running in the debugger - if (!isEmulator && (!BuildConfig.DEBUG || !Debug.isDebuggerConnected())) { - val crashlytics = FirebaseCrashlytics.getInstance() - crashlytics.setUserId(analyticsPrefs.installId) // be able to group all bugs per anonymous user - - fun sendCrashReports() { - if (isAnalyticsAllowed) { - crashlytics.sendUnsentReports() - } - } - - // Send any old reports if user approves - sendCrashReports() - - // Attach to our exception wrapper - Exceptions.reporter = { exception, _, _ -> - crashlytics.recordException(exception) - sendCrashReports() // Send the new report - } - Timber.plant(CrashlyticsTree()) - } - } -} - -class CrashlyticsTree : Timber.Tree() { - - companion object { - private const val KEY_PRIORITY = "priority" - private const val KEY_TAG = "tag" - private const val KEY_MESSAGE = "message" - } - - override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { - FirebaseCrashlytics.getInstance().setCustomKeys { - key(KEY_PRIORITY, priority) - key(KEY_TAG, tag ?: "No Tag") - key(KEY_MESSAGE, message) - } - - if (t == null) { - FirebaseCrashlytics.getInstance().recordException(Exception(message)) - } else { - FirebaseCrashlytics.getInstance().recordException(t) - } } } diff --git a/app/src/google/java/com/geeksville/mesh/android/GeeksvilleApplication.kt b/app/src/google/java/com/geeksville/mesh/android/GeeksvilleApplication.kt index 83b4163b4..513c27328 100644 --- a/app/src/google/java/com/geeksville/mesh/android/GeeksvilleApplication.kt +++ b/app/src/google/java/com/geeksville/mesh/android/GeeksvilleApplication.kt @@ -19,6 +19,7 @@ package com.geeksville.mesh.android import android.app.Application import android.content.Context +import android.content.SharedPreferences import android.provider.Settings import androidx.appcompat.app.AppCompatActivity import androidx.compose.runtime.Composable @@ -52,6 +53,11 @@ import com.geeksville.mesh.model.DeviceHardware import com.geeksville.mesh.util.exceptionReporter import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.GoogleApiAvailabilityLight +import com.google.firebase.Firebase +import com.google.firebase.analytics.analytics +import com.google.firebase.crashlytics.crashlytics +import com.google.firebase.crashlytics.setCustomKeys +import com.google.firebase.initialize import com.suddenh4x.ratingdialog.AppRating import io.opentracing.util.GlobalTracer import timber.log.Timber @@ -76,29 +82,6 @@ abstract class GeeksvilleApplication : abstract val analyticsPrefs: AnalyticsPrefs - var isAnalyticsAllowed: Boolean - get() = analyticsPrefs.analyticsAllowed - set(value) { - analyticsPrefs.analyticsAllowed = value - val newConsent = - if (value && !isInTestLab) { - TrackingConsent.GRANTED - } else { - TrackingConsent.NOT_GRANTED - } - - info(if (value) "Analytics enabled" else "Analytics disabled") - - if (Datadog.isInitialized()) { - Datadog.setTrackingConsent(newConsent) - } else { - initDatadog() - } - - // Change the flag with the providers - analytics.setEnabled(value && !isInTestLab) // Never do analytics in the test lab - } - private val minimumLaunchTimes: Int = 10 private val minimumDays: Int = 10 private val minimumLaunchTimesToShowAgain: Int = 5 @@ -130,19 +113,71 @@ abstract class GeeksvilleApplication : } } + lateinit var analyticsPrefsChangedListener: SharedPreferences.OnSharedPreferenceChangeListener + override fun onCreate() { super.onCreate() - - val firebaseAnalytics = FirebaseAnalytics(analyticsPrefs.installId) - analytics = firebaseAnalytics - - // Set analytics per prefs - isAnalyticsAllowed = isAnalyticsAllowed initDatadog() + initCrashlytics() + updateAnalyticsConsent() + // listen for changes to analytics prefs + analyticsPrefsChangedListener = + SharedPreferences.OnSharedPreferenceChangeListener { _, key -> + if (key == "allowed") { + updateAnalyticsConsent() + } + } + getSharedPreferences("analytics-prefs", MODE_PRIVATE) + .registerOnSharedPreferenceChangeListener(analyticsPrefsChangedListener) } private val sampleRate = 100f + private fun initCrashlytics() { + analytics = FirebaseAnalytics(analyticsPrefs.installId) + Firebase.initialize(this) + Firebase.crashlytics.setUserId(analyticsPrefs.installId) + Timber.plant(CrashlyticsTree()) + } + + private fun updateAnalyticsConsent() { + if (!isAnalyticsAvailable || isInTestLab) { + info("Analytics not available") + return + } + val isAnalyticsAllowed = analyticsPrefs.analyticsAllowed + info(if (isAnalyticsAllowed) "Analytics enabled" else "Analytics disabled") + Datadog.setTrackingConsent(if (isAnalyticsAllowed) TrackingConsent.GRANTED else TrackingConsent.NOT_GRANTED) + + analytics.setEnabled(isAnalyticsAllowed) + Firebase.crashlytics.isCrashlyticsCollectionEnabled = isAnalyticsAllowed + Firebase.analytics.setAnalyticsCollectionEnabled(isAnalyticsAllowed) + Firebase.crashlytics.sendUnsentReports() + } + + private class CrashlyticsTree : Timber.Tree() { + + companion object { + private const val KEY_PRIORITY = "priority" + private const val KEY_TAG = "tag" + private const val KEY_MESSAGE = "message" + } + + override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { + Firebase.crashlytics.setCustomKeys { + key(KEY_PRIORITY, priority) + key(KEY_TAG, tag ?: "No Tag") + key(KEY_MESSAGE, message) + } + + if (t == null) { + Firebase.crashlytics.recordException(Exception(message)) + } else { + Firebase.crashlytics.recordException(t) + } + } + } + private fun initDatadog() { val logger = Logger.Builder() @@ -161,13 +196,9 @@ abstract class GeeksvilleApplication : .setCrashReportsEnabled(true) .setUseDeveloperModeWhenDebuggable(true) .build() - val consent = - if (isAnalyticsAllowed && !isInTestLab) { - TrackingConsent.GRANTED - } else { - TrackingConsent.NOT_GRANTED - } + val consent = TrackingConsent.PENDING Datadog.initialize(this, configuration, consent) + Datadog.setUserInfo(analyticsPrefs.installId) val rumConfiguration = RumConfiguration.Builder(BuildConfig.datadogApplicationId) @@ -207,12 +238,17 @@ fun setAttributes(firmwareVersion: String, deviceHardware: DeviceHardware) { GlobalRumMonitor.get().addAttribute("device_hardware", deviceHardware.hwModelSlug) } -val Context.isGooglePlayAvailable: Boolean +private val Context.isGooglePlayAvailable: Boolean get() = GoogleApiAvailabilityLight.getInstance().isGooglePlayServicesAvailable(this).let { it != ConnectionResult.SERVICE_MISSING && it != ConnectionResult.SERVICE_INVALID } +private val isDatadogAvailable: Boolean = Datadog.isInitialized() + +val Context.isAnalyticsAvailable: Boolean + get() = isDatadogAvailable && isGooglePlayAvailable + @OptIn(ExperimentalTrackingApi::class) @Composable fun AddNavigationTracking(navController: NavHostController) { diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt index bbd169372..1afeeb1cd 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt @@ -20,7 +20,8 @@ package com.geeksville.mesh.repository.radio import com.geeksville.mesh.android.Logging /** - * An interface that assumes we are talking to a meshtastic device over some sort of stream connection (serial or TCP probably) + * An interface that assumes we are talking to a meshtastic device over some sort of stream connection (serial or TCP + * probably) */ abstract class StreamInterface(protected val service: RadioInterfaceService) : Logging, @@ -46,12 +47,16 @@ abstract class StreamInterface(protected val service: RadioInterfaceService) : onDeviceDisconnect(true) } - /** Tell MeshService our device has gone away, but wait for it to come back + /** + * Tell MeshService our device has gone away, but wait for it to come back * - * @param waitForStopped if true we should wait for the manager to finish - must be false if called from inside the manager callbacks - * */ + * @param waitForStopped if true we should wait for the manager to finish - must be false if called from inside the + * manager callbacks + */ protected open fun onDeviceDisconnect(waitForStopped: Boolean) { - service.onDisconnect(isPermanent = true) // if USB device disconnects it is definitely permanently gone, not sleeping) + service.onDisconnect( + isPermanent = true, + ) // if USB device disconnects it is definitely permanently gone, not sleeping) } protected open fun connect() { @@ -85,14 +90,12 @@ abstract class StreamInterface(protected val service: RadioInterfaceService) : /** Print device serial debug output somewhere */ private fun debugOut(b: Byte) { when (val c = b.toChar()) { - '\r' -> { - } // ignore + '\r' -> {} // ignore '\n' -> { debug("DeviceLog: $debugLineBuf") debugLineBuf.clear() } - else -> - debugLineBuf.append(c) + else -> debugLineBuf.append(c) } } @@ -133,16 +136,19 @@ abstract class StreamInterface(protected val service: RadioInterfaceService) : // We've read our header, do one big read for the packet itself packetLen = (msb shl 8) or lsb if (packetLen > MAX_TO_FROM_RADIO_SIZE) { - lostSync() // If packet len is too long, the bytes must have been corrupted, start looking for START1 again + lostSync() // If packet len is too long, the bytes must have been corrupted, start looking for + // START1 again } else if (packetLen == 0) { - deliverPacket() // zero length packets are valid and should be delivered immediately (because there won't be a next byte of payload) + deliverPacket() // zero length packets are valid and should be delivered immediately (because there + // won't be a next byte of payload) } } else -> { // We are looking at the packet bytes now rxPacket[ptr - 4] = c - // Note: we have to check if ptr +1 is equal to packet length (for example, for a 1 byte packetlen, this code will be run with ptr of4 + // Note: we have to check if ptr +1 is equal to packet length (for example, for a 1 byte packetlen, this + // code will be run with ptr of4 if (ptr - 4 + 1 == packetLen) { deliverPacket() } diff --git a/app/src/main/java/com/geeksville/mesh/ui/common/components/SwitchPreference.kt b/app/src/main/java/com/geeksville/mesh/ui/common/components/SwitchPreference.kt index 2c016c183..26445b48a 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/common/components/SwitchPreference.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/common/components/SwitchPreference.kt @@ -17,9 +17,13 @@ package com.geeksville.mesh.ui.common.components +import androidx.compose.animation.AnimatedContent import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.selection.toggleable +import androidx.compose.material3.CircularWavyProgressIndicator +import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ListItem import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.Switch @@ -30,6 +34,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +@OptIn(ExperimentalMaterial3ExpressiveApi::class) @Composable fun SwitchPreference( modifier: Modifier = Modifier, @@ -40,46 +45,47 @@ fun SwitchPreference( onCheckedChange: (Boolean) -> Unit, padding: PaddingValues? = null, containerColor: Color? = null, + loading: Boolean = false, ) { ListItem( - colors = ListItemDefaults.colors().copy( - headlineColor = if (enabled) { - ListItemDefaults.colors().headlineColor - } else { - ListItemDefaults.colors().headlineColor.copy(alpha = 0.5f) - }, - supportingTextColor = if (enabled) { - ListItemDefaults.colors().supportingTextColor - } else { - ListItemDefaults.colors().supportingTextColor.copy(alpha = 0.5f) - }, - containerColor = containerColor ?: ListItemDefaults.colors().containerColor, - ), - modifier = (padding?.let { Modifier.padding(it) } ?: modifier).toggleable( + colors = + ListItemDefaults.colors() + .copy( + headlineColor = + if (enabled) { + ListItemDefaults.colors().headlineColor + } else { + ListItemDefaults.colors().headlineColor.copy(alpha = 0.5f) + }, + supportingTextColor = + if (enabled) { + ListItemDefaults.colors().supportingTextColor + } else { + ListItemDefaults.colors().supportingTextColor.copy(alpha = 0.5f) + }, + containerColor = containerColor ?: ListItemDefaults.colors().containerColor, + ), + modifier = + (padding?.let { Modifier.padding(it) } ?: modifier).toggleable( value = checked, enabled = enabled, onValueChange = onCheckedChange, ), trailingContent = { - Switch( - enabled = enabled, - checked = checked, - onCheckedChange = null, - ) + AnimatedContent(targetState = loading) { loading -> + if (loading) { + CircularWavyProgressIndicator(modifier = Modifier.size(24.dp)) + } else { + Switch(enabled = enabled, checked = checked, onCheckedChange = null) + } + } }, supportingContent = { if (summary.isNotEmpty()) { - Text( - text = summary, - modifier = Modifier.padding(bottom = 16.dp), - ) + Text(text = summary, modifier = Modifier.padding(bottom = 16.dp)) } }, - headlineContent = { - Text( - text = title, - ) - } + headlineContent = { Text(text = title) }, ) } diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/Connections.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/Connections.kt index 8827002bd..20a8f3ac6 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/Connections.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/Connections.kt @@ -39,7 +39,6 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.selection.selectableGroup -import androidx.compose.foundation.selection.toggleable import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Bluetooth @@ -49,7 +48,6 @@ import androidx.compose.material.icons.rounded.Bluetooth import androidx.compose.material.icons.rounded.Usb import androidx.compose.material.icons.rounded.Wifi import androidx.compose.material3.Card -import androidx.compose.material3.Checkbox import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SegmentedButton @@ -71,7 +69,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.Role import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview @@ -83,10 +80,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.BuildConfig import com.geeksville.mesh.ConfigProtos import com.geeksville.mesh.R -import com.geeksville.mesh.android.BuildUtils.debug -import com.geeksville.mesh.android.GeeksvilleApplication import com.geeksville.mesh.android.gpsDisabled -import com.geeksville.mesh.android.isGooglePlayAvailable import com.geeksville.mesh.model.BTScanModel import com.geeksville.mesh.model.BluetoothViewModel import com.geeksville.mesh.model.DeviceListEntry @@ -141,7 +135,6 @@ fun ConnectionsScreen( val connectionState by uiViewModel.connectionState.collectAsStateWithLifecycle(ConnectionState.DISCONNECTED) val scanning by scanModel.spinner.collectAsStateWithLifecycle(false) val context = LocalContext.current - val app = (context.applicationContext as GeeksvilleApplication) val info by uiViewModel.myNodeInfo.collectAsStateWithLifecycle() val selectedDevice by scanModel.selectedNotNullFlow.collectAsStateWithLifecycle() val bluetoothEnabled by bluetoothViewModel.enabled.collectAsStateWithLifecycle(false) @@ -425,42 +418,6 @@ fun ConnectionsScreen( LaunchedEffect(Unit) { uiViewModel.suppressNoPairedWarning() } } - - // Analytics Okay Checkbox - - val isGooglePlayAvailable = context.isGooglePlayAvailable - val isAnalyticsAllowed = app.isAnalyticsAllowed && isGooglePlayAvailable - if (isGooglePlayAvailable) { - var loading by remember { mutableStateOf(false) } - LaunchedEffect(isAnalyticsAllowed) { loading = false } - Row( - modifier = - Modifier.fillMaxWidth() - .toggleable( - value = isAnalyticsAllowed, - onValueChange = { - debug("User changed analytics to $it") - app.isAnalyticsAllowed = it - loading = true - }, - role = Role.Checkbox, - enabled = isGooglePlayAvailable && !loading, - ) - .padding(horizontal = 16.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Checkbox( - enabled = isGooglePlayAvailable, - checked = isAnalyticsAllowed, - onCheckedChange = null, - ) - Text( - text = stringResource(R.string.analytics_okay), - style = MaterialTheme.typography.bodyLarge, - modifier = Modifier.padding(start = 16.dp), - ) - } - } } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/components/SettingsItem.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/components/SettingsItem.kt index c410377ab..5617cfb7a 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/components/SettingsItem.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/components/SettingsItem.kt @@ -17,28 +17,23 @@ package com.geeksville.mesh.ui.settings.components -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.RowScope -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.rounded.KeyboardArrowRight import androidx.compose.material.icons.rounded.Android import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults +import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.Icon +import androidx.compose.material3.ListItem +import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.LocalContentColor -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector @@ -67,6 +62,7 @@ fun SettingsItem( } /** A toggleable settings switch item. */ +@OptIn(ExperimentalMaterial3ExpressiveApi::class) @Composable fun SettingsItemSwitch( checked: Boolean, @@ -120,17 +116,14 @@ private fun ClickableWrapper(enabled: Boolean, onClick: () -> Unit, content: @Co /** The row content to display for a settings item. */ @Composable -private fun Content(leading: @Composable () -> Unit, text: String, trailing: @Composable RowScope.() -> Unit) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(16.dp), - modifier = Modifier.fillMaxWidth().padding(vertical = 12.dp, horizontal = 16.dp), - ) { - leading() - Text(text = text, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.wrapContentWidth()) - Spacer(modifier = Modifier.weight(1f)) - trailing() - } +private fun Content(leading: @Composable () -> Unit, text: String, trailing: @Composable () -> Unit) { + ListItem( + modifier = Modifier.padding(horizontal = 8.dp), + colors = ListItemDefaults.colors(containerColor = Color.Transparent), + headlineContent = { Text(text) }, + leadingContent = { leading() }, + trailingContent = { trailing() }, + ) } @Composable diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfig.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfig.kt index 2e95605b2..d7ef8119a 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfig.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfig.kt @@ -39,6 +39,7 @@ import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.twotone.KeyboardArrowRight +import androidx.compose.material.icons.filled.BugReport import androidx.compose.material.icons.filled.Download import androidx.compose.material.icons.filled.Upload import androidx.compose.material.icons.twotone.Warning @@ -79,6 +80,7 @@ import com.geeksville.mesh.ui.common.components.TitledCard import com.geeksville.mesh.ui.common.theme.AppTheme import com.geeksville.mesh.ui.common.theme.StatusColors.StatusRed import com.geeksville.mesh.ui.settings.components.SettingsItem +import com.geeksville.mesh.ui.settings.components.SettingsItemSwitch import com.geeksville.mesh.ui.settings.radio.components.EditDeviceProfileDialog import com.geeksville.mesh.ui.settings.radio.components.PacketResponseStateDialog import kotlinx.coroutines.delay @@ -201,6 +203,7 @@ fun RadioConfigScreen( deviceProfile = null showEditDeviceProfileDialog = true }, + onToggleAnalytics = { viewModel.toggleAnalytics() }, onNavigate = onNavigate, ) } @@ -286,6 +289,7 @@ private fun RadioConfigItemList( onRouteClick: (Enum<*>) -> Unit = {}, onImport: () -> Unit = {}, onExport: () -> Unit = {}, + onToggleAnalytics: () -> Unit = {}, onNavigate: (Route) -> Unit, ) { val enabled = state.connected && !state.responseState.isWaiting() && !isManaged @@ -364,6 +368,18 @@ private fun RadioConfigItemList( ) } } + item { + if (state.analyticsAvailable) { + TitledCard(title = stringResource(R.string.phone_settings), modifier = Modifier.padding(top = 16.dp)) { + SettingsItemSwitch( + text = stringResource(R.string.analytics_okay), + checked = state.analyticsEnabled, + leadingIcon = Icons.Default.BugReport, + onClick = onToggleAnalytics, + ) + } + } + } } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt index 158da8568..e9ac7234a 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt @@ -43,7 +43,10 @@ import com.geeksville.mesh.ModuleConfigProtos import com.geeksville.mesh.Portnums import com.geeksville.mesh.Position import com.geeksville.mesh.R +import com.geeksville.mesh.android.GeeksvilleApplication import com.geeksville.mesh.android.Logging +import com.geeksville.mesh.android.isAnalyticsAvailable +import com.geeksville.mesh.android.prefs.AnalyticsPrefs import com.geeksville.mesh.android.prefs.MapConsentPrefs import com.geeksville.mesh.config import com.geeksville.mesh.database.entity.MyNodeEntity @@ -92,6 +95,8 @@ data class RadioConfigState( val ringtone: String = "", val cannedMessageMessages: String = "", val responseState: ResponseState = ResponseState.Empty, + val analyticsAvailable: Boolean = true, + val analyticsEnabled: Boolean = false, ) @HiltViewModel @@ -103,6 +108,7 @@ constructor( private val radioConfigRepository: RadioConfigRepository, private val locationRepository: LocationRepository, private val mapConsentPrefs: MapConsentPrefs, + private val analyticsPrefs: AnalyticsPrefs, ) : ViewModel(), Logging { private val meshService: IMeshService? @@ -159,6 +165,8 @@ constructor( } .launchIn(viewModelScope) + _radioConfigState.update { it.copy(analyticsAvailable = (app as GeeksvilleApplication).isAnalyticsAvailable) } + debug("RadioConfigViewModel created") } @@ -695,4 +703,9 @@ constructor( requestIds.update { it.apply { remove(data.requestId) } } } } + + fun toggleAnalytics() { + analyticsPrefs.analyticsAllowed = !analyticsPrefs.analyticsAllowed + _radioConfigState.update { it.copy(analyticsEnabled = analyticsPrefs.analyticsAllowed) } + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5381e7cff..a5907036b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -100,7 +100,7 @@ Send You haven\'t yet paired a Meshtastic compatible radio with this phone. Please pair a device and set your username.\n\nThis open-source application is in development, if you find problems please post on our forum: https://github.com/orgs/meshtastic/discussions.\n\nFor more information see our web page - www.meshtastic.org. You - Anonymous usage statistics and crash reports. + Allow analytics and crash reporting. Accept Cancel Clear changes @@ -798,4 +798,5 @@ URL Template https://a.tile.openstreetmap.org/{z}/{x}/{y}.png track point + Phone Settings From 20530874b41959ae3d6ed5636923c18903959dbf Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Wed, 27 Aug 2025 21:25:02 -0500 Subject: [PATCH 07/14] chore: Scheduled updates (Firmware, Hardware) (#2883) Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com> --- app/src/main/assets/device_hardware.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/assets/device_hardware.json b/app/src/main/assets/device_hardware.json index 5aa79d24a..8ce583ee7 100644 --- a/app/src/main/assets/device_hardware.json +++ b/app/src/main/assets/device_hardware.json @@ -1032,7 +1032,7 @@ "hwModelSlug": "T_DECK_PRO", "platformioTarget": "t-deck-pro", "architecture": "esp32-s3", - "activelySupported": false, + "activelySupported": true, "supportLevel": 1, "displayName": "LILYGO T-Deck Pro", "tags": [ From 3f55d0f225445166e102648d34c4045f041cf96c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Aug 2025 21:25:17 -0500 Subject: [PATCH 08/14] chore(deps): update androidx.compose.material3:material3 to v1.5.0-alpha03 (#2881) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f15f5ce80..259d58fee 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -35,7 +35,7 @@ location-services = "21.3.0" maps-compose = "6.7.2" markdownRenderer = "0.35.0" material = "1.12.0" -material3 = "1.5.0-alpha02" +material3 = "1.5.0-alpha03" mgrs = "2.1.3" navigation = "2.9.3" okhttp = "5.1.0" From 61d45367a2bd5a23533f957ab66c1e72b01550cb Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Wed, 27 Aug 2025 22:01:30 -0500 Subject: [PATCH 09/14] chore(datadog): Disable automatic compose instrumentation (#2884) Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- app/build.gradle.kts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a2b6360b2..dad29ebbb 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -15,7 +15,6 @@ * along with this program. If not, see . */ -import com.datadog.gradle.plugin.InstrumentationMode import io.gitlab.arturbosch.detekt.Detekt import java.io.FileInputStream import java.util.Properties @@ -182,9 +181,9 @@ secrets { } datadog { - if (!gradle.startParameter.taskNames.any { it.contains("fdroid", ignoreCase = true) }) { - composeInstrumentation = InstrumentationMode.AUTO - } + // if (!gradle.startParameter.taskNames.any { it.contains("fdroid", ignoreCase = true) }) { + // composeInstrumentation = InstrumentationMode.AUTO + // } } // per protobuf-gradle-plugin docs, this is recommended for android From 2a2696314a4c708be16ba4534d08482fdc4b12e0 Mon Sep 17 00:00:00 2001 From: DaneEvans Date: Thu, 28 Aug 2025 13:21:44 +1000 Subject: [PATCH 10/14] #2711 move map controls up (#2886) --- app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt b/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt index b81b0192d..a73ecf0ef 100644 --- a/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt +++ b/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt @@ -42,7 +42,6 @@ import androidx.compose.material3.Card import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.FloatingToolbarDefaults -import androidx.compose.material3.FloatingToolbarDefaults.ScreenOffset import androidx.compose.material3.FloatingToolbarExitDirection.Companion.End import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme @@ -539,7 +538,7 @@ fun MapView( } MapControlsOverlay( - modifier = Modifier.align(Alignment.CenterEnd).offset(x = -ScreenOffset), + modifier = Modifier.align(Alignment.TopEnd).padding(top = 50.dp), mapFilterMenuExpanded = mapFilterMenuExpanded, onMapFilterMenuDismissRequest = { mapFilterMenuExpanded = false }, onToggleMapFilterMenu = { mapFilterMenuExpanded = true }, From 99c016c7e92021d1942957fb5b4e7fc43965a267 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Wed, 27 Aug 2025 22:24:03 -0500 Subject: [PATCH 11/14] New Crowdin updates (#2888) --- app/src/main/res/values-ar/strings.xml | 1 - app/src/main/res/values-b+sr+Latn/strings.xml | 1 - app/src/main/res/values-bg/strings.xml | 1 - app/src/main/res/values-ca/strings.xml | 1 - app/src/main/res/values-cs/strings.xml | 1 - app/src/main/res/values-de/strings.xml | 1 - app/src/main/res/values-el/strings.xml | 1 - app/src/main/res/values-es/strings.xml | 1 - app/src/main/res/values-et/strings.xml | 1 - app/src/main/res/values-fi/strings.xml | 1 - app/src/main/res/values-fr-rHT/strings.xml | 1 - app/src/main/res/values-fr/strings.xml | 1 - app/src/main/res/values-ga/strings.xml | 1 - app/src/main/res/values-gl/strings.xml | 1 - app/src/main/res/values-hr/strings.xml | 1 - app/src/main/res/values-hu/strings.xml | 1 - app/src/main/res/values-is/strings.xml | 1 - app/src/main/res/values-it/strings.xml | 1 - app/src/main/res/values-iw/strings.xml | 1 - app/src/main/res/values-ja/strings.xml | 1 - app/src/main/res/values-ko/strings.xml | 1 - app/src/main/res/values-lt/strings.xml | 1 - app/src/main/res/values-nb/strings.xml | 1 - app/src/main/res/values-nl/strings.xml | 1 - app/src/main/res/values-pl/strings.xml | 1 - app/src/main/res/values-pt-rBR/strings.xml | 1 - app/src/main/res/values-pt/strings.xml | 1 - app/src/main/res/values-ro/strings.xml | 1 - app/src/main/res/values-ru/strings.xml | 1 - app/src/main/res/values-sk/strings.xml | 1 - app/src/main/res/values-sl/strings.xml | 1 - app/src/main/res/values-sq/strings.xml | 1 - app/src/main/res/values-sr/strings.xml | 1 - app/src/main/res/values-sv/strings.xml | 1 - app/src/main/res/values-tr/strings.xml | 1 - app/src/main/res/values-uk/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - app/src/main/res/values-zh-rTW/strings.xml | 2 +- mesh_service_example/src/main/res/values-zh-rTW/strings.xml | 1 + 39 files changed, 2 insertions(+), 38 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 03f23eeb8..01d3bf5a9 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -32,7 +32,6 @@ اسم المستخدم غير معروف ارسل أنت - إحصاءات الاستخدام المجهولة الهُوِيَّة وتقارير الأعطال. قبول إلغاء تم تلقي رابط القناة الجديدة diff --git a/app/src/main/res/values-b+sr+Latn/strings.xml b/app/src/main/res/values-b+sr+Latn/strings.xml index 4c287e471..0647d15f4 100644 --- a/app/src/main/res/values-b+sr+Latn/strings.xml +++ b/app/src/main/res/values-b+sr+Latn/strings.xml @@ -76,7 +76,6 @@ Pošalji Још нисте упарили Мештастик компатибилан радио са овим телефоном. Молимо вас да упарите уређај и поставите своје корисничко име.\n\nОва апликација отвореног кода је у развоју, ако нађете проблеме, молимо вас да их објавите на нашем форуму: https://github.com/orgs/meshtastic/discussions\n\nЗа више информација посетите нашу веб страницу - www.meshtastic.org. Ti - Anonimne statistike korišćenja i izveštaji o greškama. Prihvati Otkaži Primljen novi link kanala diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 8926fa501..ebb62e388 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -68,7 +68,6 @@ Изпрати Все още не сте сдвоили радио, съвместимо с Meshtastic, с този телефон. Моля, сдвоете устройство и задайте вашето потребителско име.\n\nТова приложение с отворен код е в процес на разработка, ако откриете проблеми, моля, публикувайте в нашия форум: https://github.com/orgs/meshtastic/discussions\n\nЗа повече информация вижте нашата уеб страница на адрес www.meshtastic.org. Вие - Анонимна статистика за използване и доклади за сривове. Приеми Отказ Изчистване на промените diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index e0923f7b0..997996836 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -78,7 +78,6 @@ Enviar Encara no has emparellat una ràdio compatible amb Meshtastic amb aquest telèfon. Si us plau emparella un dispositiu i configura el teu nom d\'usuari. \n\nAquesta aplicació de codi obert està en desenvolupament. Si hi trobes problemes publica-ho en el nostre fòrum https://github.com/orgs/meshtastic/discussions\n\nPer a més informació visita la nostra pàgina web - www.meshtastic.org. Tu - Estadístiques anònimes d\'ús i informes de fallades. Acceptar Cancel·lar Nova URL de canal rebuda diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 72af43b79..31b02f9ab 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -80,7 +80,6 @@ Odeslat Ještě jste s tímto telefonem nespárovali rádio kompatibilní s Meshtastic. Spárujte prosím zařízení a nastavte své uživatelské jméno.\n\nTato open-source aplikace je ve vývoji, pokud narazíte na problémy, napište na naše fórum: https://github.com/orgs/meshtastic/discussions\n\nDalší informace naleznete na naší webové stránce - www. meshtastic.org. Vy - Anonymní hlášení o používání aplikace a jejích chybách. Přijmout Zrušit Nová URL kanálu přijata diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 823151ee2..2f582cdc5 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -83,7 +83,6 @@ Senden Sie haben noch kein zu Meshtastic kompatibles Funkgerät mit diesem Telefon gekoppelt. Bitte koppeln Sie ein Gerät und legen Sie Ihren Benutzernamen fest.\n\nDiese quelloffene App befindet sich im Test. Wenn Sie Probleme finden, veröffentlichen Sie diese bitte auf unserer Website im Chat.\n\nWeitere Informationen finden Sie auf unserer Webseite - www.meshtastic.org. Du - Anonyme Nutzungsstatistiken und Absturzberichte. Akzeptieren Abbrechen Änderungen löschen diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 67bf737e3..1eff56bf7 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -33,7 +33,6 @@ Αποστολή Δεν έχετε κάνει ακόμη pair μια συσκευή συμβατή με Meshtastic με το τηλέφωνο. Παρακαλώ κάντε pair μια συσκευή και ορίστε το όνομα χρήστη.\n\nΗ εφαρμογή ανοιχτού κώδικα βρίσκεται σε alpha-testing, αν εντοπίσετε προβλήματα παρακαλώ δημοσιεύστε τα στο forum: https://github.com/orgs/meshtastic/discussions\n\nΠερισσότερες πληροφορίες στην ιστοσελίδα - www.meshtastic.org. Εσύ - Ανώνυμα στατιστικά στοιχεία χρήσης και αναφορές κατάρρευσης. Αποδοχή Ακύρωση Λήψη URL νέου καναλιού diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index c9a284a14..499c7407a 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -79,7 +79,6 @@ Enviar Aún no ha emparejado una radio compatible con Meshtastic con este teléfono. Empareje un dispositivo y configure su nombre de usuario. \n\nEsta aplicación de código abierto es una prueba alfa; si encuentra un problema publiquelo en el foro: https://github.com/orgs/meshtastic/discussions\n\nPara obtener más información visite nuestra página web - www.meshtastic.org. Usted - Estadísticas de uso anónimo e informes de fallos. Aceptar Cancelar Borrar cambios diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 278ebf47c..93cac2475 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -83,7 +83,6 @@ Saada Ei ole veel ühendanud Meshtastic -kokku sobivat raadiot telefoniga. Seo seade selle telefoniga ja määra kasutajanimi.\n\nSee avatud lähtekoodiga programm on alpha-testi staatuses. Kui märkad vigu, saada palun sõnum meie foorumisse: https://github.com/orgs/meshtastic/discussions\n\nLisateave kodulehel - www.meshtastic.org. Sina - Anonüümne kasutus statistika ja krahhiaruanded. Nõustu Tühista Võta tagasi diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 7e6cd3154..882c77694 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -83,7 +83,6 @@ Lähetä Et ole vielä yhdistänyt Meshtastic -yhteensopivaa radiota tähän puhelimeen. Muodosta laitepari puhelimen kanssa ja aseta käyttäjänimesi.\n\nTämä avoimen lähdekoodin sovellus on vielä kehitysvaiheessa. Jos löydät virheen, lähetä siitä viesti foorumillemme: https://github.com/orgs/meshtastic/discussions\n\nLisätietoja saat verkkosivuiltamme - www.meshtastic.org. Sinä - Nimettömät käyttötilastot ja kaatumisraportit. Hyväksy Peruuta Peru muutokset diff --git a/app/src/main/res/values-fr-rHT/strings.xml b/app/src/main/res/values-fr-rHT/strings.xml index 1c7ab3767..8baf7f676 100644 --- a/app/src/main/res/values-fr-rHT/strings.xml +++ b/app/src/main/res/values-fr-rHT/strings.xml @@ -69,7 +69,6 @@ Voye Ou poko konekte ak yon radyo ki konpatib ak Meshtastic sou telefòn sa a. Tanpri konekte yon aparèy epi mete non itilizatè w lan.\n\nSa a se yon aplikasyon piblik ki nan tès Alpha. Si ou gen pwoblèm, tanpri pataje sou fowòm nou an: https://github.com/orgs/meshtastic/discussions\n\nPou plis enfòmasyon, vizite sit wèb nou an - www.meshtastic.org. Ou - Statistik itilizasyon anonim ak rapò aksidantèl. Aksepte Anile Nouvo kanal URL resevwa diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 8e705991e..ae2a76fde 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -83,7 +83,6 @@ Envoyer Aucune radio Meshtastic compatible n\'a été jumelée à ce téléphone. Jumelez un appareil et spécifiez votre nom d\'utilisateur.\n\nL\'application open-source est en test alpha, si vous rencontrez des problèmes postez au chat sur notre site web.\n\nPour plus d\'information visitez notre site web - www.meshtastic.org. Vous - Statistiques et rapports d\'erreur anonymes. Accepter Annuler Annuler modifications diff --git a/app/src/main/res/values-ga/strings.xml b/app/src/main/res/values-ga/strings.xml index 0a67015f8..cc7e7b8bc 100644 --- a/app/src/main/res/values-ga/strings.xml +++ b/app/src/main/res/values-ga/strings.xml @@ -68,7 +68,6 @@ Seol Níl raidió comhoiriúnach Meshtastic péireáilte leis an bhfón seo agat fós. Péireáil gléas le do thoil agus socraigh d’ainm úsáideora.\n\nTá an feidhmchlár foinse oscailte seo faoi alfa-thástáil, má aimsíonn tú fadhbanna cuir iad ar ár bhfóram: https://github.com/orgs/meshtastic/discussions\n\nLe haghaidh tuilleadh faisnéise féach ar ár leathanach gréasáin - www.meshtastic.org. - Staitisticí úsáide gan ainm agus tuairiscí tuairteála. Glac Cealaigh URL Cainéal nua faighte diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 1327ebe07..4ce203746 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -35,7 +35,6 @@ Enviar Aínda non enlazaches unha radio compatible con Meshtástic neste teléfono. Por favor enlaza un dispositivo e coloca o teu nome de usuario. \n\n Esta aplicación de código aberto está en desenvolvemento. Se atopas problemas por favor publícaos no noso foro: https://github.com/orgs/meshtastic/discussions\n\nPara máis información visita a nosa páxina - www.meshtastic.org. Ti - Estadísticas de uso anónimo e informes de fallos. Aceptar Cancelar Novo enlace de canle recibida diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 805fba5f0..51ca89989 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -33,7 +33,6 @@ Potvrdi Još niste povezali Meshtastic radio uređaj s ovim telefonom. Povežite uređaj i postavite svoje korisničko ime.\n\nOva aplikacija otvorenog koda je u razvoju, ako naiđete na probleme, objavite na našem forumu: https://github.com/orgs/meshtastic/discussions\n\nZa više informacija pogledajte našu web stranicu - www.meshtastic.org. Vi - Anonimni statistički podaci o korištenju i izvješća o rušenju sustava. Prihvati Odustani Primljen je URL novog kanala diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index e0d7ab2e1..8b59b9dad 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -52,7 +52,6 @@ Küldeni Még nem párosított egyetlen Meshtastic rádiót sem ehhez a telefonhoz. Kérem pároztasson egyet és állítsa be a felhasználónevet.\n\nEz a szabad forráskódú alkalmazás fejlesztés alatt áll, ha hibát talál kérem írjon a projekt fórumába: https://github.com/orgs/meshtastic/discussions\n\nBővebb információért látogasson el a projekt weboldalára - www.meshtastic.org. Te - Névtelen felhasználási statisztikák és hibajelentések. Elfogadni Megszakítani Új csatorna URL érkezett diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index 9d8ffcb05..348abc2b0 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -23,7 +23,6 @@ Senda Þú hefur ekki parað Meshtastic radíó við þennan síma. Vinsamlegast paraðu búnað og veldu notendnafn.\n\nÞessi opni hugbúnaður er enn í þróun, finnir þú vandamál vinsamlegast búðu til þráð á spjallborðinu okkar: https://github.com/orgs/meshtastic/discussions\n\nFyrir frekari upplýsingar sjá vefsíðu - www.meshtastic.org. Þú - Ópersónurekjanleg gögn um notkun og villumeldingar. Samþykkja Hætta við Ný slóð fyrir rás móttekin diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index eb351e765..d8c5acfe4 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -81,7 +81,6 @@ Invia Non è ancora stato abbinato un dispositivo radio compatibile Meshtastic a questo telefono. È necessario abbinare un dispositivo e impostare il nome utente.\n\nQuesta applicazione open-source è ancora in via di sviluppo, se si riscontrano problemi, rivolgersi al forum: https://github.com/orgs/meshtastic/discussions\n\nPer maggiori informazioni visitare la pagina web - www.meshtastic.org. Tu - Invia statistiche di utilizzo anonime e rapporti sugli arresti anomali. Accetta Annulla Ricevuta URL del Nuovo Canale diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 923576ff6..2ae3e58f2 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -30,7 +30,6 @@ שלח עוד לא צימדת מכשיר תומך משטסטיק לטלפון זה. בבקשה צמד מכשיר והגדר שם משתמש.\n\nאפליקציית קוד פתוח זה נמצא בפיתוח, במקשר של בעיות בבקשה גש לפורום: https://github.com/orgs/meshtastic/discussions\n\n למידע נוסף בקרו באתר - www.meshtastic.org. אתה - שלח סטטיסטיקות שימוש אנונימיות ודוחות קריסה. אישור בטל התקבל כתובת ערוץ חדשה diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 97bdd1058..7f410f705 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -78,7 +78,6 @@ 送信 このスマートフォンはMeshtasticデバイスとペアリングされていません。デバイスとペアリングしてユーザー名を設定してください。\n\nこのオープンソースアプリケーションはアルファテスト中です。問題を発見した場合はBBSに書き込んでください。 https://github.com/orgs/meshtastic/discussions\n\n詳しくはWEBページをご覧ください。 www.meshtastic.org あなた - 匿名の診断情報と不具合報告 同意 キャンセル 新しいチャンネルURLを受信しました diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index c3fb474f5..bb1d298e6 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -81,7 +81,6 @@ 보내기 아직 스마트폰과 Meshtastic 장치와 연결하지 않았습니다. 장치와 연결하고 사용자 이름을 정하세요. \n\n이 오픈소스 응용 프로그램은 개발 중입니다. 문제가 발견되면 포럼: https://github.com/orgs/meshtastic/discussions 을 통해 알려주세요.\n\n 자세한 정보는 웹페이지 - www.meshtastic.org 를 참조하세요. - 익명의 진단보고와 오류 보고서 수락 취소 새로운 채널 URL 수신 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 78cea8aaf..f6f762e34 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -69,7 +69,6 @@ Siųsti Su šiuo telefonu dar nėra susietas joks Meshtastic įtaisais. Prašome suporuoti įrenginį ir nustatyti savo vartotojo vardą.\n\nŠi atvirojo kodo programa yra kūrimo stadijoje, jei pastebėsite problemas, prašome pranešti mūsų forume: https://github.com/orgs/meshtastic/discussions\n\nDaugiau informacijos rasite mūsų interneto svetainėje - www.meshtastic.org. Tu - Siųsti anoniminę naudojimo statistika ir klaidų ataskaitas. Priimti Atšaukti Gautas naujo kanalo URL diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index ce21eaefe..8621d89d8 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -76,7 +76,6 @@ Send Du har ikke paret en Meshtastic kompatibel radio med denne telefonen. Vennligst parr en enhet, og sett ditt brukernavn.\n\nDenne åpen kildekode applikasjonen er i alfa-testing, Hvis du finner problemer, vennligst post på vårt forum: https://github.com/orgs/meshtastic/discussions\n\nFor mer informasjon, se vår nettside - www.meshtastic.org. Deg - Anonym brukerstatistikk og kræsjrapporter. Godta Avbryt Ny kanal URL mottatt diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 8e074eee2..6ea74792b 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -77,7 +77,6 @@ Verzend Je hebt nog geen Meshtastic compatibele radio met deze telefoon gekoppeld. Paar alstublieft een apparaat en voer je gebruikersnaam in.\n\nDeze open-source applicatie is in alpha-test, indien je een probleem vaststelt, kan je het posten op onze forum: https://github.com/orgs/meshtastic/discussions\n\nVoor meer informatie bezoek onze web pagina - www.meshtastic.org. Jij - Anonieme gebruiksstatistieken en crashmeldingen. Accepteer Annuleer Nieuw kanaal URL ontvangen diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 5e93cebed..1228302c0 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -78,7 +78,6 @@ Wyślij Nie sparowałeś jeszcze urządzenia Meshtastic z tym telefonem. Proszę sparować urządzenie i ustawić swoją nazwę użytkownika.\n\nTa aplikacja open-source jest w fazie rozwoju, jeśli znajdziesz problemy, napisz na naszym forum: https://github.com/orgs/meshtastic/discussions\n\nWięcej informacji znajdziesz na naszej stronie internetowej - www.meshtastic.org. Ty - Anonimowe statystyki użycia i raporty o błędach. Akceptuj Anuluj Otrzymano nowy URL kanału diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 3efdbc9eb..9d2a78829 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -83,7 +83,6 @@ Enviar Você ainda não pareou um rádio compatível ao Meshtastic com este smartphone. Por favor pareie um dispositivo e configure seu nome de usuário.\n\nEste aplicativo open source está em desenvolvimento, caso encontre algum problema por favor publique em nosso fórum: https://github.com/orgs/meshtastic/discussions\n\nPara mais informações acesse nossa página: www.meshtastic.org. Você - Estatísticas de uso anônimas e relatórios de falhas. Aceitar Cancelar Limpar mudanças diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 884e1c5c7..6b2039ac8 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -79,7 +79,6 @@ Enviar Ainda não emparelhou um rádio compatível com Meshtastic com este telefone. Emparelhe um dispositivo e defina seu nome de usuário.\n\nEste aplicativo de código aberto está em teste alfa, se encontrar problemas, por favor reporte através do nosso forum em: https://github.com/orgs/meshtastic/discussions\n\nPara obter mais informações, consulte a nossa página web - www.meshtastic.org. Você - Estatísticas de uso anônimas e relatórios de falhas. Aceitar Cancelar Novo Link Recebido do Canal diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 8977ec7b8..c9b583d40 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -25,7 +25,6 @@ Trimite Încă nu ai asociat un radio compatibil cu Meshtastic cu acest telefon. Te rugăm să asociezi un dispozitiv și să îți setezi numele de utilizator.\n\nAceastă aplicaţie open-source este în dezvoltare, dacă întâmpinaţi probleme, vă rugăm să postaţi pe forumul nostru: https://github.com/orgs/meshtastic/discussions\n\nPentru mai multe informații, consultați pagina noastră de internet - www.meshtastic.org. Tu - Trimite în mod anonim statistici de utilizare și raporturi de crash. Accept Renunta Am primit un nou URL de canal diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index a871d4db2..46fff52b7 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -83,7 +83,6 @@ Отправить Вы еще не подключили к телефону устройство, совместимое с Meshtastic радио. Пожалуйста, подключите устройство и задайте имя пользователя.\n\nЭто приложение с открытым исходным кодом находится в альфа-тестировании, если вы обнаружите проблемы, пожалуйста, напишите в чате на нашем сайте.\n\nДля получения дополнительной информации посетите нашу веб-страницу - www.meshtastic.org. Вы - Анонимная статистика использования и отчеты о сбоях. Принять Отмена Отменить изменения diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 813980eda..4396b9698 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -78,7 +78,6 @@ Odoslať K tomuto telefónu ste ešte nespárovali žiadne zariadenie kompatibilné s Meshtastic. Prosím spárujte zariadenie a nastavte svoje užívateľské meno.\n\nTáto open-source aplikácia je v alpha testovacej fáze, ak nájdete chybu, prosím popíšte ju na fóre: https://github.com/orgs/meshtastic/discussions\n\n Pre viac informácií navštívte web stránku - www.meshtastic.org. Vy - Anonymné štatistiky používania a správy o zlyhaní. Prijať Odmietnuť Prijatá nová URL kanálu diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 8256986c3..175176e82 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -76,7 +76,6 @@ Pošlji S tem telefonom še niste seznanili združljivega Meshtastic radia. Prosimo povežite napravo in nastavite svoje uporabniško ime. \n\nTa odprtokodna aplikacija je v alfa testiranju, če imate težave, objavite na našem spletnem klepetu.\n\nZa več informacij glejte našo spletno stran - www.meshtastic.org. Jaz - Anonimna statistika uporabe in poročila o zrušitvah. Sprejmi Prekliči/zavrzi Prejet je bil novi URL kanala diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index 441635966..c6927b81e 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -69,7 +69,6 @@ Dërgo Ju ende nuk keni lidhur një paisje radio Meshtastic me këtë telefon. Ju lutem lidhni një paisje radio dhe vendosni emrin e përdoruesit.\n\nKy aplikacion është software i lire \"open-source\" dhe në variantin Alpha për testim. Nëse hasni probleme, ju lutem shkruani në çatin e faqes tonë të internetit: https://github.com/orgs/meshtastic/discussions\n\nPër më shumë informacione vizitoni faqen tonë në internet - www.meshtastic.org. Ju - Statistikat e përdorimit dhe raportet e keq funksionimit mblidhen në mënyrë krejtësisht anonime Prano Anullo Ju keni një kanal radio të ri URL diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 0c39909f2..32a9e9b0c 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -76,7 +76,6 @@ Пошаљи Још нисте упарили Мештастик компатибилан радио са овим телефоном. Молимо вас да упарите уређај и поставите своје корисничко име.\n\nОва апликација отвореног кода је у развоју, ако нађете проблеме, молимо вас да их објавите на нашем форуму: https://github.com/orgs/meshtastic/discussions\n\nЗа више информација посетите нашу веб страницу - www.meshtastic.org. Ти - Анонимне статистике коришћења и извештаји о падовима апликације. Прихвати Откажи Примљен нови линк канала diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 1af53b28e..9b1e06bb8 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -76,7 +76,6 @@ Skicka Du har ännu inte parat en Meshtastic-kompatibel radio med den här telefonen. Koppla ihop en enhet och ange ditt användarnamn.\n\nDetta öppna källkodsprogram (open source) är under utveckling, om du hittar problem, vänligen publicera det på vårt forum: https://github.com/orgs/meshtastic/discussions\n\nFör mer information se vår webbsida - www.meshtastic.org. Du - Anonym användningsstatistik och kraschrapporter. Acceptera Avbryt Ny kanal-länk mottagen diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index a4c53177e..5d0cdf03e 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -78,7 +78,6 @@ Gönder Telefonu, Meshtastic uyumlu bir cihaz ile eşleştirmediniz. Bir cihazla eşleştirin ve kullanıcı adınızı belirleyin.\n\nAçık kaynaklı bu uygulama şu an alfa-test aşamasında, problem fark ederseniz forumda lütfen paylaşın: https://github.com/orgs/meshtastic/discussions\n\nDaha fazla bilgi için, sitemiz: www.meshtastic.org. Siz - Anonim kullanim istatistikleri ve hata raporları. Kabul et İptal Değişiklikleri Temizle diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 6f0bef8a5..45b69a1ea 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -38,7 +38,6 @@ Надіслати Ви ще не підєднали пристрій, сумісний з Meshtastic. Будьласка приєднайте пристрій і введіть ім’я користувача.\n\nЦя програма з відкритим вихідним кодом знаходиться в розробці, якщо ви виявите проблеми, опублікуйте їх на нашому форумі: https://github.com/orgs/meshtastic/discussions\n\nДля отримання додаткової інформації відвідайте нашу веб-сторінку - www.meshtastic.org. Ви - Анонімна статистика використання та звіти про збої. Прийняти Скасувати Отримано URL-адресу нового каналу diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 04f50b552..72efc7d97 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -83,7 +83,6 @@ 传送 您尚未将手机与 Meshtastic 兼容的装置配对。请先配对装置并设置您的用户名称。\n\n此开源应用程序仍在开发中,如有问题,请在我们的论坛 https://github.com/orgs/meshtastic/discussions 上面发文询问。\n\n 也可参阅我们的网页 - www.meshtastic.org。 - 匿名使用统计信息和故障报告 接受 取消 清除更改 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 06d6c17aa..c66cc1db5 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -81,7 +81,6 @@ 傳送 您尚未將手機與 Meshtastic 相容的裝置配對。請先配對裝置並設置您的使用者名稱。\n\n此開源應用程式仍在開發中,如有問題,請在我們的論壇 https://github.com/orgs/meshtastic/discussions 上面發文詢問。\n\n 也可參閱我們的網頁 - www.meshtastic.org。 - 匿名使用統計資訊和故障報告 接受 取消 清除變更 @@ -336,6 +335,7 @@ 紅色 綠色 藍色 + 允許輸入來源 發送振鈴 訊息 diff --git a/mesh_service_example/src/main/res/values-zh-rTW/strings.xml b/mesh_service_example/src/main/res/values-zh-rTW/strings.xml index 962638357..4d0f79dec 100644 --- a/mesh_service_example/src/main/res/values-zh-rTW/strings.xml +++ b/mesh_service_example/src/main/res/values-zh-rTW/strings.xml @@ -16,5 +16,6 @@ ~ along with this program. If not, see . --> + Mesh服務範例 發送打招呼訊息 From 161582141ac97df29f47765c390bdf5802794584 Mon Sep 17 00:00:00 2001 From: DaneEvans Date: Thu, 28 Aug 2025 19:43:56 +1000 Subject: [PATCH 12/14] 2712 add format types note to custom layers (#2891) --- .../mesh/ui/map/components/CustomMapLayersSheet.kt | 7 +++++++ app/src/main/res/values/strings.xml | 1 + 2 files changed, 8 insertions(+) diff --git a/app/src/google/java/com/geeksville/mesh/ui/map/components/CustomMapLayersSheet.kt b/app/src/google/java/com/geeksville/mesh/ui/map/components/CustomMapLayersSheet.kt index c86613e00..6f6908c93 100644 --- a/app/src/google/java/com/geeksville/mesh/ui/map/components/CustomMapLayersSheet.kt +++ b/app/src/google/java/com/geeksville/mesh/ui/map/components/CustomMapLayersSheet.kt @@ -60,6 +60,13 @@ fun CustomMapLayersSheet( ) HorizontalDivider() } + item { + Text( + modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 8.dp, bottom = 0.dp), + text = stringResource(R.string.map_layer_formats), + style = MaterialTheme.typography.bodySmall, + ) + } if (mapLayers.isEmpty()) { item { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a5907036b..6939fe358 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -777,6 +777,7 @@ Terrain Hybrid Manage Map Layers + Custom layers support .kml or .kmz files. Map Layers No custom layers loaded. Add Layer From 908fd4a26358251347bf73f2db31c9ea120fdbca Mon Sep 17 00:00:00 2001 From: DaneEvans Date: Thu, 28 Aug 2025 19:52:38 +1000 Subject: [PATCH 13/14] #2894 - add responsiveness to the map scalebar (#2895) --- app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt b/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt index a73ecf0ef..bd426fd5e 100644 --- a/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt +++ b/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt @@ -508,8 +508,12 @@ fun MapView( } } - DisappearingScaleBar(cameraPositionState = cameraPositionState) + val currentCameraPosition = cameraPositionState.position + var displayedZoom by remember { mutableStateOf(currentCameraPosition.zoom) } + if (displayedZoom != 0f) { + DisappearingScaleBar(cameraPositionState = cameraPositionState) + } editingWaypoint?.let { waypointToEdit -> EditWaypointDialog( waypoint = waypointToEdit, From 008593acb7b994fb2f9d0ad05ae8fca0ee4a608d Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Thu, 28 Aug 2025 06:05:12 -0500 Subject: [PATCH 14/14] New Crowdin updates (#2892) --- app/src/main/res/values-fi/strings.xml | 2 + app/src/main/res/values-sv/strings.xml | 1 + app/src/main/res/values-zh-rTW/strings.xml | 324 +++++++++++++++++- .../src/main/res/values-sv/strings.xml | 4 +- .../src/main/res/values-zh-rTW/strings.xml | 2 +- 5 files changed, 318 insertions(+), 15 deletions(-) diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 882c77694..1616ecaea 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -83,6 +83,7 @@ Lähetä Et ole vielä yhdistänyt Meshtastic -yhteensopivaa radiota tähän puhelimeen. Muodosta laitepari puhelimen kanssa ja aseta käyttäjänimesi.\n\nTämä avoimen lähdekoodin sovellus on vielä kehitysvaiheessa. Jos löydät virheen, lähetä siitä viesti foorumillemme: https://github.com/orgs/meshtastic/discussions\n\nLisätietoja saat verkkosivuiltamme - www.meshtastic.org. Sinä + Salli analytiikka ja virheraportit. Hyväksy Peruuta Peru muutokset @@ -769,4 +770,5 @@ URL-osoitteessa on oltava paikkamerkkejä. URL-mallipohja seurantapiste + Puhelimen asetukset diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 9b1e06bb8..02c45f4af 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -27,6 +27,7 @@ Senast hörd via MQTT via MQTT + Ignorerade noder Okänd Inväntar kvittens Kvittens köad diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index c66cc1db5..201019d90 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -16,12 +16,13 @@ ~ along with this program. If not, see . --> - 鏈網%s + Meshtastic %s 過濾器 清除節點過濾器 顯示未知節點 隱藏離線節點 只顯示直連節點 + 您正在檢視已忽略的節點\n請返回到節點列表。 顯示詳細資料 節點排序選項 依名字排序 @@ -32,6 +33,7 @@ 有節點MQTT排序 有節點MQTT排序 通過喜好 + 已忽略節點 無法識別 正在等待確認 發送佇列中 @@ -81,10 +83,12 @@ 傳送 您尚未將手機與 Meshtastic 相容的裝置配對。請先配對裝置並設置您的使用者名稱。\n\n此開源應用程式仍在開發中,如有問題,請在我們的論壇 https://github.com/orgs/meshtastic/discussions 上面發文詢問。\n\n 也可參閱我們的網頁 - www.meshtastic.org。 + 允許傳送分析及崩潰報告。 接受 取消 清除變更 收到新的頻道 URL + Meshtastic需要啟用定位及藍芽才能尋找新裝置,可以選擇在不使用時停用。 回報BUG 回報問題 您確定要報告錯誤嗎?報告後,請在 https://github.com/orgs/meshtastic/discussions 上貼文,以便我們可以將報告與您發現的問題匹配。 @@ -93,6 +97,7 @@ 配對失敗,請重新選擇 位置訪問已關閉,無法向設備提供位置. 分享 + 發現新節點: %s 已中斷連線 設備休眠中 已連接:%1$s 在線 @@ -109,21 +114,24 @@ 關於 此頻道 URL 無效,無法使用 除錯面板 + 解析封包: 匯出日誌 篩選 啟動篩選功能 在日誌中搜尋… - 下個符合的 - 上個符合的 + 下一個符合的 + 上一個符合的 清除搜尋結果 增加篩選條件 - 已包含了篩選 + 包含篩選器 清除所有篩選 清除所有日誌 - 這將從您的裝置中刪除所有日誌包和資料庫條目 - 這是永久完全重置。 + 符合任一條件 + 符合全部條件 + 這將完全移除裝置上的所有日誌封包與資料庫記錄 - 這是一個完整的重設,且無法復原。 清除 訊息傳遞狀態 - 直接訊息通知 + 私訊通知 廣播訊息通知 警告信息 需要更新韌體。 @@ -151,6 +159,8 @@ 也從所有人的聊天紀錄中刪除 從我的聊天紀錄中刪除 選擇全部 + 關閉選取 + 刪除選取項目 樣式選擇 下載區域 名稱 @@ -171,7 +181,13 @@ 編輯快速聊天 附加到訊息 即時發送 + 顯示快速聊天選單 + 隱藏快速聊天選單 恢復出廠設置 + 藍芽已關閉,請至手機設定內開啟藍芽功能。 + 開啟設定 + 韌體版本: %1$s + Meshtastic 應用程式需要啟用「鄰近裝置」權限,才能透過藍牙尋找並連接到裝置,可以選擇在不使用時停用。 直接發訊息 重設節點資料庫 已確認送達 @@ -221,8 +237,11 @@ 無線通道利用率 溫度 濕度 + 環境溫度 + 環境濕度 系統記錄 節點距 + 經過節點數:%1$d 資訊 目前頻道的使用情況,包括格式正確的傳輸(TX)、接收(RX)和格式錯誤的接收(也稱為雜訊)。 過去一小時内傳輸所使用的通話時間(airtime)百分比。 @@ -244,6 +263,7 @@ 裝置指標日誌 節點地圖 定位日誌 + 最後位置更新 環境監測讀數日誌 訊號指標日誌 管理 @@ -283,11 +303,14 @@ 你確定嗎? 設備角色檔案和關於選擇正確的設備角色的博客文章 。]]> 我知道我在做什麼。 + 節點 %1$s 電量過低 (%2$d%%) 低電量通知 低電量:%s + 低電量通知(收藏節點) 氣壓 通过 UDP 的Mesh UDP設置 + 最後接收: %2$s
最後位置: %3$s
電量: %4$s]]>
切換我的位置 用戶 頻道 @@ -313,9 +336,12 @@ 檢測傳感器 客流量計數 音頻設置 - 啟動CODEC2 + 啟用 CODEC2 PTT針腳 - CODEC2取樣率 + CODEC2 取樣率 + I2S WS 訊號選擇 + I2S 數據輸入 + I2S 數據輸出 I2S 時鐘 藍牙配置 藍牙已啟用 @@ -325,22 +351,47 @@ 已啓用下行 默認 位置已啟用 + 精確位置 GPIO 引脚 類別 隱藏密碼 顯示密碼 詳情 環境 + 裝置燈光設定 LED狀態 紅色 綠色 藍色 - + 罐頭訊息設定 + 啟用罐頭訊息 + 啟用旋轉編碼器#1 + 旋轉編碼器 A 端 GPIO 腳位 + 旋轉編碼器 B 端 GPIO 腳位 + 旋轉編碼器 按鈕 GPIO 腳位 + 按下時產生輸入事件 + 順時針旋轉時產生輸入事件 + 逆時針旋轉時產生輸入事件 + 啟用上下選擇輸入 允許輸入來源 發送振鈴 訊息 + 偵測感測器設定 + 啟用偵測感測器 + 最短廣播間隔 (秒) + 狀態廣播間隔 (秒) + 告警訊息發送提示音 + 顯示名稱 + 螢幕的 GPIO 腳位 + 偵測觸發類型 + 使用輸入上拉模式 設備設置 角色 + 重新定義按鈕腳位 + 重新定義蜂鳴器腳位 + 轉發模式 + 節點資訊廣播間隔(秒) + 雙擊視為按鈕操作 禁用三擊 POSIX時區 禁用LED心跳 @@ -372,11 +423,25 @@ 使用PWM調製的蜂鳴 輸出振動(GPIO) 輸出持續時間(毫秒) + 通知逾時時間(秒) 鈴聲 + 使用 I2S 控制蜂鳴器 LoRa 設定 + 使用 Modem 預設集 + Modem 預設集 帶寬 + 展頻因數 (SF) + 編碼率(CR) + 頻率偏移量 (MHz) + 區域(頻段劃分) + 最大轉發限制 TX已啟用 TX功率 (dBm) + 頻率槽位 + 覆蓋工作週期/佔空比 + 忽略來訊 + SX126X 接收增益提升 + 複寫頻率(MHz) 不使用PA风扇 無視MQTT 將消息轉發至MQTT @@ -414,10 +479,13 @@ 位置設定 位置廣播間隔(秒) 啟用智慧位置 + 智慧廣播最小距離(公尺) + 智慧廣播最小間隔(秒) 使用固定位置 緯度 經度 高度(米) + 使用手機目前定位 GPS模式 GPS更新間隔(秒) 重定義 GPS_RX_PIN @@ -429,47 +497,277 @@ 電池延時關閉(秒) ADC乘數修正比率 等待藍牙持續時間(秒) + 深度睡眠時間(秒) + 輕度睡眠時間(秒) + 最短喚醒時間(秒) + 電池 INA_2XX I2C 地址 + 範圍測試設定 + 啟用範圍測試 + 訊息發送間隔(秒) + 將 .CSV 保存到內部儲存空間(僅限ESP32) + 遠端硬體設定 + 啟動遠端硬體 + 允許未定義腳位連接 + 可用腳位 + 安全性設定 公鑰 私鑰 + 管理員金鑰 + 託管模式 + 序列控制台 + 啟用調適日誌 API + 舊版管理頻道 + 序列埠設定 + 啟用序列埠 + 啟用 Echo + 序列埠鮑率 逾時 + 序列埠模式 + 覆蓋控制台序列埠 + 心跳 + 紀錄數目 + 歴史紀錄最大返回值 + 歴史紀錄返回視窗 伺服器 + 遙測設定 + 裝置資訊更新週期(秒) + 環境資訊更新週期(秒) + 啟用環境資訊模組 + 在螢幕上顯示環境資訊 + 環境指標以華氏溫度顯示 + 啟用空氣品質模組 + 空氣品質更新週期(秒) + 空氣品質圖示 + 啟用電池資訊模組 + 電量資訊更新週期(秒) + 在螢幕上顯示電量資訊 使用者設定 節點 ID + 節點長名稱 + 節點短名稱 硬體型號 + 業餘無線電模式 (HAM) + 啟用此選項將停用訊息加密,並與預設的 Meshtastic 網路不相容。 + 露點 + 氣壓 + 氣體感測器 距離 + 照度 + 風速 + 重量 + 輻射 + + 室內空氣品質 (IAQ) + 網址 + + 匯入設定 + 匯出設定 硬體 + 已支援 + 節點編號 使用者 ID - 在線時間 + 運行時間 + 負載:%1$d + 硬碟可用空間:%1$d + 時間戳記 + 航向 + 速度 + 衛星數 + 海拔 頻率 + 時隙 主要的 + 定期廣播位置與遙測資料 次要的 + 停用定期廣播遙測資料 + 需要手動定位位置 + 長按後可拖曳排列順序 取消靜音 動態 掃描 QR Code 分享聯絡人 + 是否匯入聯絡人? 不接收訊息 無監控裝置或基礎設施 + 警告:聯絡人已存在,匯入將會覆蓋先前的聯絡人資訊。 + 公鑰已變更 + 匯入 + 請求詮釋資料 (Metadata) + 動作 韌體 + 使用12小時制 + 啟用後,裝置將在螢幕上以12小時制顯示時間。 + 裝置效能紀錄 + 裝置 + 可用記憶體 + 可用儲存空間 載入 + 使用者設定 + 導航至 + 連線 + Mesh 地圖 + 訊息 節點 設定 - 設定你的地區 - 回復 + 設定您的地區 + 回覆 + 您的節點將定期發送未加密的地圖回報封包至已設定的 MQTT 伺服器,包含 ID、長名稱與短名稱、大約位置、硬體型號、角色、韌體版本、LoRa 區域、數據機預設值以及主要頻道名稱。 + 同意透過 MQTT 分享未加密的節點資料 + 啟用此功能即表示您認知並明確同意透過 MQTT 協議傳輸您裝置的即時地理位置,且不進行加密。此位置資料可能用於即時地圖回報、裝置追蹤及相關遙測功能等用途。 + 我已閱讀並理解上述內容。我同意透過 MQTT 傳輸未加密的節點資料 我同意。 + 建議更新韌體。 + 為享受最新功能及所修復的問題,請更新您的節點韌體。\n\n最新穩定韌體版本為:%1$s + 到期時間 時間 日期 + 地圖選項\n + 僅顯示收藏 + 顯示路徑 + 顯示定位精準度 + 客户端通知 + 偵測到金鑰已洩漏,點選確定後重新產生金鑰。 + 重新產生私鑰 + 您確定要重新產生密鑰嗎?\n\n連線過的其他節點需要刪除並重新交換金鑰後才能恢復加密通訊連線。 + 匯出金鑰 + 請將匯出後的私鑰及公鑰妥善保存。 + 模組已解鎖 遠端 + (%1$d 個上線 / 共計 %2$d 個) + 回應 中斷連線 + 正在尋找藍牙裝置… + 沒有已配對的藍牙裝置。 找不到網路裝置。 找不到 USB 序列裝置。 - 捲動至底部 + 移至最底部 Meshtastic 掃描中 + 安全性狀態 + 安全性 + 警告標誌 + 未知頻道 + 警告 + 溢出選單 + 紫外線強度 (UV Lux) + 不明 + 該裝置已受託管理,並只能由遠端管理員進行變更。 + 清除節點資料庫 + 清除最後出現時間超過 %1$d 日的節點 + 僅清除不明節點 + 清理低互動的節點 + 清除已忽略的節點 + 立即清理 + 此操作將刪除資料庫內的%1$d個節點,並且無法恢復。 + 綠色鎖頭表示該頻道已使用 128 位元或 256 位元 AES 金鑰安全加密。 + 未加密頻道,模糊定位 + 黃色開鎖表示該頻道未進行安全加密,未啟用精確定位資訊,且未使用任何金鑰或使用 1 位元組已知金鑰。 + 未加密頻道,精確定位 + 紅色開鎖表示該頻道未進行安全加密,啟用了精確定位資訊,且未使用任何金鑰或使用 1 位元組已知金鑰。 + 警告:未加密頻道,精確定位 & MQTT Uplink + 帶有警告的紅色開鎖表示該頻道未進行安全加密,啟用了精確定位資訊,且正在透過MQTT上傳資料至網路,以及未使用任何金鑰或使用 1 位元組已知金鑰。 + 頻道安全性 + 頻道安全性説明 + 顯示全部狀態 + 顯示目前狀態 + 關閉 + 您確定要刪除此節點嗎? + 回覆 %1$s + 取消回覆 + 確認刪除訊息? + 清除所選 訊息: + 請輸入訊息 + PAX 指標日誌 + PAX + 沒有可用的 PAX 指標日誌。 + WiFi 裝置 + 藍牙裝置 + 配對裝置 + 連接裝置 + + 超過速率限制,請稍後再嘗試。 + 查看版本資訊 + 下載 + 目前已安裝 + 最新穩定版韌體 + 最新測試版韌體 + 由 Meshtastic 社群協作 + 韌體版本 + 最近的網路裝置 + 發現的網路裝置 + 開始使用 + 歡迎來到 + 隨時隨地保持連線 + 無需手機訊號,也能與您的朋友和社群離線通訊。 + 建立您自己的網路 + 輕鬆設定私有網狀網絡,以實現偏遠地區安全可靠的通訊。 + 位置追蹤和分享 + 透過整合的 GPS 功能,即時分享你的位置,並保持團隊協調一致。 + 應用程式通知 + 收到的訊息 + 頻道訊息與私訊通知。 + 新的節點 + 發現新節點的通知。 + 電量不足 + 已連線裝置的低電量通知。 + 將選取的封包以『關鍵』優先等級送出時,其通知會忽略作業系統通知中心的靜音與『請勿打擾』設定。 + 設定通知權限 + 手機定位 + Meshtastic 會使用您手機的定位資訊來啟用多項功能。您隨時可以在設定中修改定位權限。 + 分享位置 + 使用您手機的 GPS 來向節點發送位置,而不是使用節點上的 GPS 模組。 + 距離量測 + 顯示您手機與其他有定位資訊的 Meshtastic 節點之間的距離。 + 距離篩選器 + 根據您手機的距離,篩選節點列表和 Mesh 網路地圖。 + Mesh Map 地圖位置 + 在 Mesh 地圖上,為您的手機啟用藍色的定位點。 + 設定定位權限 跳過 + 設定 + 緊急警示 + 為了確保您能接收緊急警示,例如 + SOS 警報,即便裝置正處於「請勿打擾」模式亦同,您需要授予 + 特殊權限。請在通知設定中啟用此功能。 + + 設定緊急警示 + Meshtastic 使用通知功能讓您隨時了解新訊息和其他重要事件。您可以隨時在設定中更新通知權限。 + 繼續 + 授予權限 + %d 個節點已排定移除: + 注意:這會將節點從應用程式和裝置資料庫中移除。\n所選的項目將會加入待處理中。 + 正在連線至裝置 + 標準 + 衛星 + 地形 + 混合 + 管理地圖圖層 + 自定義圖層支援 .kml 或 .kmz 格式檔案。 + 地圖圖層 + 未載入自訂圖層。 + 添加圖層 + 隱藏圖層 + 顯示圖層 + 移除圖層 + 添加圖層 + 位於此處的節點 + 已選擇的地圖類型 + 管理自定義圖磚來源 + 加入自定義圖磚來源 + 沒有自定義圖專來源 + 編輯自定義圖磚來源 + 刪除自定義圖磚來源 + 名稱不得空白。 + 服務供應商名稱已存在。 + URL 不得空白。 + 網址必須包含佔位符。 + URL 範本 + 軌跡點 + 手機設定
diff --git a/mesh_service_example/src/main/res/values-sv/strings.xml b/mesh_service_example/src/main/res/values-sv/strings.xml index 090f7e390..10e8cb423 100644 --- a/mesh_service_example/src/main/res/values-sv/strings.xml +++ b/mesh_service_example/src/main/res/values-sv/strings.xml @@ -15,4 +15,6 @@ ~ You should have received a copy of the GNU General Public License ~ along with this program. If not, see . --> - + + Skicka Hej-meddelande + diff --git a/mesh_service_example/src/main/res/values-zh-rTW/strings.xml b/mesh_service_example/src/main/res/values-zh-rTW/strings.xml index 4d0f79dec..16c04c5d3 100644 --- a/mesh_service_example/src/main/res/values-zh-rTW/strings.xml +++ b/mesh_service_example/src/main/res/values-zh-rTW/strings.xml @@ -16,6 +16,6 @@ ~ along with this program. If not, see . --> - Mesh服務範例 + Mesh 服務範例 發送打招呼訊息