diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 70fe2759..cf79f789 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -16,16 +16,6 @@ jobs: with: submodules: 'recursive' - - name: Load secrets - run: | - rm ./app/src/main/res/values/mapbox-token.xml - echo -e "\n $MAPBOX_ACCESS_TOKEN\n" > ./app/src/main/res/values/mapbox-token.xml - mkdir -p ~/.gradle - echo "MAPBOX_DOWNLOADS_TOKEN=$MAPBOX_DOWNLOADS_TOKEN" >>~/.gradle/gradle.properties - env: - MAPBOX_ACCESS_TOKEN: ${{ secrets.MAPBOX_ACCESS_TOKEN }} - MAPBOX_DOWNLOADS_TOKEN: ${{ secrets.MAPBOX_DOWNLOADS_TOKEN }} - - name: Mock files for CI run: | rm ./app/google-services.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7ff5c092..ae4072d6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,8 +29,6 @@ jobs: echo "$KEYSTORE_PROPERTIES" > ./keystore.properties env: GSERVICES: ${{ secrets.GSERVICES }} - MAPBOX_ACCESS_TOKEN: ${{ secrets.MAPBOX_ACCESS_TOKEN }} - MAPBOX_DOWNLOADS_TOKEN: ${{ secrets.MAPBOX_DOWNLOADS_TOKEN }} KEYSTORE: ${{ secrets.KEYSTORE }} KEYSTORE_FILENAME: ${{ secrets.KEYSTORE_FILENAME }} KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }} diff --git a/README.md b/README.md index 87f94d70..19927744 100644 --- a/README.md +++ b/README.md @@ -6,51 +6,50 @@ [![Fiscal Contributors](https://opencollective.com/meshtastic/tiers/badge.svg?label=Fiscal%20Contributors&color=deeppink)](https://opencollective.com/meshtastic/) [![Vercel](https://img.shields.io/static/v1?label=Powered%20by&message=Vercel&style=flat&logo=vercel&color=000000)](https://vercel.com?utm_source=meshtastic&utm_campaign=oss) -This is a tool for using Android with open-source mesh radios. For more information see our webpage: [meshtastic.org](https://www.meshtastic.org). If you are looking for the the device side code, see [here](https://github.com/meshtastic/Meshtastic-esp32). +This is a tool for using Android with open-source mesh radios. For more information see our +webpage: [meshtastic.org](https://www.meshtastic.org). If you are looking for the the device side +code, see [here](https://github.com/meshtastic/Meshtastic-esp32). -This project is currently beta testing, if you have questions or feedback please [Join our discussion forum](https://meshtastic.discourse.group/). We would love to hear from you! +This project is currently beta testing, if you have questions or feedback +please [Join our discussion forum](https://meshtastic.discourse.group/). We would love to hear from +you! The production version of our application is here: [![Download at https://play.google.com/store/apps/details?id=com.geeksville.mesh](https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png)](https://play.google.com/store/apps/details?id=com.geeksville.mesh&referrer=utm_source%3Dgithub-android-readme) -To join the beta program for the app go to this [URL](https://play.google.com/apps/testing/com.geeksville.mesh) to opt-in to the alpha/beta test. -If you encounter any problems or have questions, [post in the forum](https://meshtastic.discourse.group/) and we'll help. +To join the beta program for the app go to +this [URL](https://play.google.com/apps/testing/com.geeksville.mesh) to opt-in to the alpha/beta +test. If you encounter any problems or have +questions, [post in the forum](https://meshtastic.discourse.group/) and we'll help. -The app is also distributed via F-Droid repo: [https://mesh.tastic.app/fdroid/repo](https://mesh.tastic.app/fdroid/repo) +The app is also distributed via F-Droid +repo: [https://mesh.tastic.app/fdroid/repo](https://mesh.tastic.app/fdroid/repo) -However, if you must use 'raw' APKs you can get them from our [github releases](https://github.com/meshtastic/Meshtastic-Android/releases). This is not recommended because if you manually install an APK it will not automatically update. +However, if you must use 'raw' APKs you can get them from +our [github releases](https://github.com/meshtastic/Meshtastic-Android/releases). This is not +recommended because if you manually install an APK it will not automatically update. ## Build instructions -If you would like to develop this application we'd love your help! These build instructions are brief -and should be improved, please send a PR if you can. +If you would like to develop this application we'd love your help! These build instructions are +brief and should be improved, please send a PR if you can. - Use Android Studio to build/debug - Use "git submodule update --init --recursive" to pull in the various submodules we depend on -- There are a few config files which you'll need to copy from templates included in the project. - Run the following commands to do so: +- There are a few config files which you'll need to copy from templates included in the project. Run + the following commands to do so: ```bash rm ./app/google-services.json cp ./app/google-services-example.json ./app/google-services.json -rm ./app/src/main/res/values/mapbox-token.xml -cp ./app/special/mapbox-token.xml ./app/src/main/res/values/ rm ./app/src/main/res/values/curfirmwareversion.xml cp ./app/special/curfirmwareversion.xml ./app/src/main/res/values/ ``` -- (unfortunately) you need to get a (free) mapbox developer token [here](https://docs.mapbox.com/android/maps/guides/install/) and put that token in your user gradle.properties. - -```bash -cat ~/.gradle/gradle.properties -MAPBOX_DOWNLOADS_TOKEN=sk.yourtokenherexxx -``` -- (optional) to run CI tests on your fork: 1) allow GitHub Actions; 2) add your token at: Settings > Secrets > Actions > New repository secret: Name: MAPBOXTOKEN Value: sk.yourtokenherexxx - -- Now you should be able to select "Run / Run" in the IDE and it will happily start running on your phone - or the emulator. Note: The emulators don't support bluetooth, so some features can not be used in - that environment. +- Now you should be able to select "Run / Run" in the IDE and it will happily start running on your + phone or the emulator. Note: The emulators don't support bluetooth, so some features can not be + used in that environment. ## Analytics setup diff --git a/app/build.gradle b/app/build.gradle index 4ba547d0..d9fa7629 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -69,7 +69,6 @@ android { // doesn't like and we need to strip them (gr) resConfigs "cs", "de", "el", "en", "es", "fi", "fr", "ga", "ht", "it", "ja", "ko-rKR", "nl", "no", "pl", "pt", "pt-rBR", "ro", "ru", "sk", "sl", "sq", "sv", "tr", "zh" - // Needed to make mapbox work inside the firebase testlab - FIXME, alas, still doesn't work ndk { // abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64" } @@ -88,7 +87,7 @@ android { kotlinOptions { jvmTarget = "1.8" - freeCompilerArgs += [ '-opt-in=kotlin.RequiresOptIn' ] + freeCompilerArgs += ['-opt-in=kotlin.RequiresOptIn'] } lint { abortOnError false @@ -140,6 +139,9 @@ dependencies { kapt "androidx.room:room-compiler:$room_version" kapt "com.google.dagger:hilt-compiler:$hilt_version" + //OSMAND + implementation 'org.osmdroid:osmdroid-android:6.1.14' + // optional - Kotlin Extensions and Coroutines support for Room implementation "androidx.room:room-ktx:$room_version" @@ -166,9 +168,6 @@ dependencies { // implementation 'com.google.android.things:androidthings:1.0' implementation 'com.github.mik3y:usb-serial-for-android:3.4.6' - // mapbox - implementation 'com.mapbox.maps:android:10.2.0' - // location services implementation 'com.google.android.gms:play-services-location:19.0.1' // For Google Sign-In (owner name accesss) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 41240d9b..45e42cc0 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -30,9 +30,6 @@ -keep class com.geeksville.mesh.**{*;} -keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite { ; } -# Recommended by mapbox to prevent native crashes --dontwarn com.mapbox.** --keep class com.mapbox.** { *; } # for kotlinx.serialization -keepattributes *Annotation*, InnerClasses diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index 8f026350..ed14accb 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -126,6 +126,7 @@ class MainActivity : BaseActivity(), Logging, // const val REQUEST_ENABLE_BT = 10 const val DID_REQUEST_PERM = 11 const val RC_SIGN_IN = 12 // google signin completed + // const val SELECT_DEVICE_REQUEST_CODE = 13 const val CREATE_CSV_FILE = 14 } @@ -331,7 +332,7 @@ class MainActivity : BaseActivity(), Logging, DID_REQUEST_PERM -> { // If request is cancelled, the result arrays are empty. if ((grantResults.isNotEmpty() && - grantResults[0] == PackageManager.PERMISSION_GRANTED) + grantResults[0] == PackageManager.PERMISSION_GRANTED) ) { // Permission is granted. Continue the action or workflow // in your app. @@ -664,7 +665,13 @@ class MainActivity : BaseActivity(), Logging, // model.setLocalConfig(LocalOnlyProtos.LocalConfig.parseFrom(service.deviceConfig)) - model.setChannels(ChannelSet(AppOnlyProtos.ChannelSet.parseFrom(service.channels))) + model.setChannels( + ChannelSet( + AppOnlyProtos.ChannelSet.parseFrom( + service.channels + ) + ) + ) model.updateNodesFromDevice() @@ -1072,14 +1079,10 @@ class MainActivity : BaseActivity(), Logging, chooseLangDialog() return true } - R.id.preferences_map_style -> { - chooseMapStyle() - return true - } R.id.show_intro -> { startActivity(Intent(this, AppIntroduction::class.java)) return true - } + } R.id.preferences_quick_chat -> { val fragmentManager: FragmentManager = supportFragmentManager val fragmentTransaction: FragmentTransaction = fragmentManager.beginTransaction() @@ -1192,7 +1195,10 @@ class MainActivity : BaseActivity(), Logging, val lang = prefs.getString("lang", "zz") debug("Lang from prefs: $lang") - builder.setSingleChoiceItems(languageLabels, languageValues.indexOf(lang)) { dialog, which -> + builder.setSingleChoiceItems( + languageLabels, + languageValues.indexOf(lang) + ) { dialog, which -> val selectedLang = languageValues[which] debug("Set lang pref to $selectedLang") editor.putString("lang", selectedLang) @@ -1202,27 +1208,4 @@ class MainActivity : BaseActivity(), Logging, val dialog = builder.create() dialog.show() } - - private fun chooseMapStyle() { - /// Prepare dialog and its items - val builder = MaterialAlertDialogBuilder(this) - builder.setTitle(getString(R.string.preferences_map_style)) - val mapStyles by lazy { resources.getStringArray(R.array.map_styles) } - - /// Load preferences and its value - val prefs = UIViewModel.getPreferences(this) - val editor: SharedPreferences.Editor = prefs.edit() - val mapStyleId = prefs.getInt("map_style_id", 1) - debug("mapStyleId from prefs: $mapStyleId") - - builder.setSingleChoiceItems(mapStyles, mapStyleId) { dialog, which -> - debug("Set mapStyleId pref to $which") - editor.putInt("map_style_id", which) - editor.apply() - dialog.dismiss() - } - val dialog = builder.create() - dialog.show() - } - } diff --git a/app/src/main/java/com/geeksville/mesh/model/CustomTileSource.kt b/app/src/main/java/com/geeksville/mesh/model/CustomTileSource.kt new file mode 100644 index 00000000..e7b68011 --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/model/CustomTileSource.kt @@ -0,0 +1,55 @@ +package com.geeksville.mesh.model + +import org.osmdroid.tileprovider.tilesource.ITileSource +import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase +import org.osmdroid.tileprovider.tilesource.TileSourceFactory +import org.osmdroid.tileprovider.tilesource.TileSourcePolicy +import org.osmdroid.util.MapTileIndex + + +class CustomTileSource { + companion object { + + val ESRI_IMAGERY = object : OnlineTileSourceBase( + "ESRI World Overview", 0, 18, 256, "", arrayOf( + "https://wayback.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/WMTS/1.0.0/default028mm/MapServer/tile/" + ), "Esri, Maxar, Earthstar Geographics, and the GIS User Community" + + "URL\n" + + "View\n", + TileSourcePolicy( + 2, TileSourcePolicy.FLAG_NO_BULK + or TileSourcePolicy.FLAG_NO_PREVENTIVE + or TileSourcePolicy.FLAG_USER_AGENT_MEANINGFUL + or TileSourcePolicy.FLAG_USER_AGENT_NORMALIZED + ) + ) { + override fun getTileURLString(pMapTileIndex: Long): String { + return baseUrl + (MapTileIndex.getZoom(pMapTileIndex) + .toString() + "/" + MapTileIndex.getY(pMapTileIndex) + + "/" + MapTileIndex.getX(pMapTileIndex) + + mImageFilenameEnding) + } + } + val MAPNIK: OnlineTileSourceBase = TileSourceFactory.MAPNIK + val USGS_TOPO: OnlineTileSourceBase = TileSourceFactory.USGS_TOPO + val USGS_SAT: OnlineTileSourceBase = TileSourceFactory.USGS_SAT + val DEFAULT_TILE_SOURCE: OnlineTileSourceBase = TileSourceFactory.DEFAULT_TILE_SOURCE + + /** + * The order in this list must match that in the arrays.xml under map_styles + */ + val mTileSources: List = + listOf(MAPNIK, USGS_TOPO, USGS_SAT, ESRI_IMAGERY) + + + fun getTileSource(aName: String): ITileSource { + for (tileSource: ITileSource in mTileSources) { + if (tileSource.name().equals(aName)) { + return tileSource; + } + } + throw IllegalArgumentException("No such tile source: $aName") + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt index 22055480..fcfc5f9d 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt @@ -1,680 +1,251 @@ package com.geeksville.mesh.ui -import android.app.AlertDialog import android.content.Context import android.content.SharedPreferences +import android.graphics.Canvas import android.graphics.Color +import android.graphics.Paint import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.EditText -import android.widget.Toast import androidx.core.content.ContextCompat -import androidx.core.graphics.drawable.toBitmap -import androidx.core.view.isVisible import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Observer -import com.geeksville.android.GeeksvilleApplication import com.geeksville.android.Logging +import com.geeksville.mesh.BuildConfig import com.geeksville.mesh.NodeInfo import com.geeksville.mesh.R -import com.geeksville.mesh.databinding.MapNotAllowedBinding import com.geeksville.mesh.databinding.MapViewBinding +import com.geeksville.mesh.model.CustomTileSource import com.geeksville.mesh.model.UIViewModel import com.geeksville.util.formatAgo -import com.mapbox.bindgen.Value -import com.mapbox.common.* -import com.mapbox.geojson.* -import com.mapbox.maps.* -import com.mapbox.maps.dsl.cameraOptions -import com.mapbox.maps.extension.style.expressions.generated.Expression -import com.mapbox.maps.extension.style.layers.addLayer -import com.mapbox.maps.extension.style.layers.addPersistentLayer -import com.mapbox.maps.extension.style.layers.generated.LineLayer -import com.mapbox.maps.extension.style.layers.generated.SymbolLayer -import com.mapbox.maps.extension.style.layers.generated.lineLayer -import com.mapbox.maps.extension.style.layers.properties.generated.* -import com.mapbox.maps.extension.style.sources.addSource -import com.mapbox.maps.extension.style.sources.generated.GeoJsonSource -import com.mapbox.maps.extension.style.sources.generated.geoJsonSource -import com.mapbox.maps.plugin.animation.MapAnimationOptions -import com.mapbox.maps.plugin.animation.flyTo -import com.mapbox.maps.plugin.gestures.OnMapLongClickListener -import com.mapbox.maps.plugin.gestures.gestures +import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint -import kotlin.math.cos -import kotlin.math.sin - +import org.osmdroid.api.IMapController +import org.osmdroid.config.Configuration +import org.osmdroid.tileprovider.tilesource.ITileSource +import org.osmdroid.util.BoundingBox +import org.osmdroid.util.GeoPoint +import org.osmdroid.views.CustomZoomButtonsController +import org.osmdroid.views.MapView +import org.osmdroid.views.overlay.CopyrightOverlay +import org.osmdroid.views.overlay.Marker @AndroidEntryPoint class MapFragment : ScreenFragment("Map"), Logging { - - private val tileStore: TileStore by lazy { - TileStore.create().also { - // Set default access token for the created tile store instance - it.setOption( - TileStoreOptions.MAPBOX_ACCESS_TOKEN, - TileDataDomain.MAPS, - Value(getString(R.string.mapbox_access_token)) - ) - } - } - - /** - * DEVELOPER OPTION TO ENABLE OFFLINE MAPS - * Set this variable to true to enable offline maps - */ - //___________________________________________________ - private val offlineEnabled = false - //___________________________________________________ - - - private val resourceOptions: ResourceOptions by lazy { - ResourceOptions.Builder().applyDefaultParams(requireContext()).tileStore(tileStore).build() - } - private val offlineManager: OfflineManager by lazy { - OfflineManager(resourceOptions) - } - private lateinit var binding: MapViewBinding - private lateinit var mapNotAllowedBinding: MapNotAllowedBinding - private var userStyleURI: String? = null - - private lateinit var geoJsonSource: GeoJsonSource - private lateinit var lineLayer: LineLayer - - private var point: Point? = null - + private lateinit var map: MapView + private lateinit var mapController: IMapController + private lateinit var mPrefs: SharedPreferences private val model: UIViewModel by activityViewModels() - private val nodeSourceId = "node-positions" - private val nodeLayerId = "node-layer" - private val labelLayerId = "label-layer" - private val markerImageId = "my-marker-image" - private val userPointImageId = "user-image" - private val boundingBoxId = "bounding-box-id" - private val lineLayerId = "line-layer-id" + private val defaultMinZoom = 1.5 + private val nodeZoomLevel = 8.5 + private val defaultZoomSpeed = 3000L + private val prefsName = "org.andnav.osm.prefs" + private val mapStyleId = "map_style_id" + private val uiPrefs = "ui-prefs" + private var nodePositions = listOf() + private val nodeLayer = 1 - private var stylePackCancelable: Cancelable? = null - private var tilePackCancelable: Cancelable? = null - - private lateinit var squareRegion: Geometry - - private val userTouchPositionId = "user-touch-position" - private val userTouchLayerId = "user-touch-layer" - private var nodePositions = GeoJsonSource(GeoJsonSource.Builder(nodeSourceId)) - - private var tileRegionDownloadSuccess = false - private var stylePackDownloadSuccess = false - private val userTouchPosition = GeoJsonSource(GeoJsonSource.Builder(userTouchPositionId)) - - - private val nodeLayer = SymbolLayer(nodeLayerId, nodeSourceId) - .iconImage(markerImageId) - .iconAnchor(IconAnchor.BOTTOM) - .iconAllowOverlap(true) - - private val userTouchLayer = SymbolLayer(userTouchLayerId, userTouchPositionId) - .iconImage(userPointImageId) - .iconAnchor(IconAnchor.BOTTOM) - - private val labelLayer = SymbolLayer(labelLayerId, nodeSourceId) - .textField(Expression.get("name")) - .textSize(12.0) - .textColor(Color.RED) - .textAnchor(TextAnchor.TOP) - //.textVariableAnchor(TextAnchor.TOP) //TODO investigate need for variable anchor vs normal anchor - .textJustify(TextJustify.AUTO) - .textAllowOverlap(true) - - - private fun onNodesChanged(nodes: Collection) { - val nodesWithPosition = nodes.filter { it.validPosition != null } - - /** - * Using the latest nodedb, generate geojson features - */ - fun getCurrentNodes(): FeatureCollection { - // Find all nodes with valid locations - - val locations = nodesWithPosition.map { node -> - val p = node.position!! - debug("Showing on map: $node") - - val f = Feature.fromGeometry( - Point.fromLngLat( - p.longitude, - p.latitude - ) - ) - node.user?.let { - f.addStringProperty("name", it.longName + " " + formatAgo(p.time)) - } - f - } - - return FeatureCollection.fromFeatures(locations) - } - nodePositions.featureCollection(getCurrentNodes()) - } - - private fun zoomToNodes(map: MapboxMap) { - val points: MutableList = mutableListOf() - val nodesWithPosition = - model.nodeDB.nodes.value?.values?.filter { it.validPosition != null } - if (nodesWithPosition != null && nodesWithPosition.isNotEmpty()) { - val unit = if (nodesWithPosition.size >= 2) { - - // Multiple nodes, make them all fit on the map view - nodesWithPosition.forEach { - points.add( - Point.fromLngLat( - it.position!!.longitude, - it.position!!.latitude - ) - ) - } - map.cameraForCoordinates(points) - } else { - // Only one node, just zoom in on it - val it = nodesWithPosition[0].position!! - points.add(Point.fromLngLat(it.longitude, it.latitude)) - map.cameraForCoordinates(points) - cameraOptions { - this.zoom(9.0) - this.center(points[0]) - } - } - map.flyTo( - unit, - MapAnimationOptions.mapAnimationOptions { duration(1000) }) - } - } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { - // We can't allow mapbox if user doesn't want analytics - return if ((requireContext().applicationContext as GeeksvilleApplication).isAnalyticsAllowed) { - // Mapbox Access token - binding = MapViewBinding.inflate(inflater, container, false) - binding.root - } else { - mapNotAllowedBinding = MapNotAllowedBinding.inflate(inflater, container, false) - mapNotAllowedBinding.root - } + binding = MapViewBinding.inflate(inflater) + return binding.root } - var mapView: MapView? = null - - - private fun removeOfflineRegions() { - // Remove the tile region with the tile region ID. - // Note this will not remove the downloaded tile packs, instead, it will just mark the tileset - // not a part of a tile region. The tiles still exists as a predictive cache in TileStore. - tileStore.removeTileRegion(TILE_REGION_ID) - - // Set the disk quota to zero, so that tile regions are fully evicted - // when removed. The TileStore is also used when `ResourceOptions.isLoadTilePacksFromNetwork` - // is `true`, and also by the Navigation SDK. - // This removes the tiles that do not belong to any tile regions. - tileStore.setOption(TileStoreOptions.DISK_QUOTA, Value(0)) - - // Remove the style pack with the style url. - // Note this will not remove the downloaded style pack, instead, it will just mark the resources - // not a part of the existing style pack. The resources still exists as disk cache. - - if (userStyleURI != null) { - offlineManager.removeStylePack(userStyleURI!!) - mapView?.getMapboxMap()?.loadStyleUri(loadMapStyleFromPref()) - } else { - offlineManager.removeStylePack(mapView?.getMapboxMap()?.getStyle()?.styleURI.toString()) - mapView?.getMapboxMap()?.loadStyleUri(loadMapStyleFromPref()) - } - MapboxMap.clearData(resourceOptions) { - it.error?.let { error -> - debug(error) - } - } - updateStylePackDownloadProgress(0, 0) - updateTileRegionDownloadProgress(0, 0) - } - - /** - * Mapbox native code can crash painfully if you ever call a mapbox view function while the view is not actively being show - */ - private val isViewVisible: Boolean - get() = mapView?.isVisible == true - override fun onViewCreated(viewIn: View, savedInstanceState: Bundle?) { super.onViewCreated(viewIn, savedInstanceState) + Configuration.getInstance().userAgentValue = + BuildConfig.APPLICATION_ID // Required to get online tiles + map = viewIn.findViewById(R.id.map) + mPrefs = context!!.getSharedPreferences(prefsName, Context.MODE_PRIVATE) - // We might not have a real mapview if running with analytics - if ((requireContext().applicationContext as GeeksvilleApplication).isAnalyticsAllowed) { -// binding.fabStyleToggle.setOnClickListener { -// //TODO: Setup Style menu for satellite view, street view, & outdoor view -// } - binding.downloadRegion.setOnClickListener { - // Display menu for download region - this.downloadRegionDialogFragment() - } - - val vIn = viewIn.findViewById(R.id.mapView) - mapView = vIn - mapView?.let { v -> - - // Each time the pane is shown start fetching new map info (we do this here instead of - // onCreate because getMapAsync can die in native code if the view goes away) - - val map = v.getMapboxMap() - if (view != null) { // it might have gone away by now - val markerIcon = - ContextCompat.getDrawable( - requireActivity(), - R.drawable.ic_twotone_person_pin_24 - )!!.toBitmap() - - map.loadStyleUri(loadMapStyleFromPref()) { - if (it.isStyleLoaded) { - it.addSource(nodePositions) - it.addImage(markerImageId, markerIcon) - it.addPersistentLayer(nodeLayer) - it.addPersistentLayer(labelLayer) - } - } - - v.gestures.rotateEnabled = false - if (offlineEnabled) { - v.gestures.addOnMapLongClickListener(this.longClick) - } - - // Provide initial positions - model.nodeDB.nodes.value?.let { nodes -> - onNodesChanged(nodes.values) - } + setupMapProperties() + loadOnlineTileSourceBase() + map.let { + if (view != null) { + mapController = map.controller + binding.fabStyleToggle.setOnClickListener { + chooseMapStyle() + } + model.nodeDB.nodes.value?.let { nodes -> + onNodesChanged(nodes.values) + drawOverlays() } - // Any times nodes change update our map - model.nodeDB.nodes.observe(viewLifecycleOwner, Observer { nodes -> - if (isViewVisible) - onNodesChanged(nodes.values) - }) - //viewAnnotationManager = v.viewAnnotationManager - zoomToNodes(map) } + // Any times nodes change update our map + model.nodeDB.nodes.observe(viewLifecycleOwner) { nodes -> + onNodesChanged(nodes.values) + drawOverlays() + } + zoomToNodes(mapController) } } - private fun downloadOfflineRegion(styleURI: String = "") { + private fun chooseMapStyle() { + /// Prepare dialog and its items + val builder = MaterialAlertDialogBuilder(context!!) + builder.setTitle(getString(R.string.preferences_map_style)) + val mapStyles by lazy { resources.getStringArray(R.array.map_styles) } - val style = styleURI.ifEmpty { - mapView?.getMapboxMap() - ?.getStyle()?.styleURI.toString() + /// Load preferences and its value + val prefs = UIViewModel.getPreferences(context!!) + val editor: SharedPreferences.Editor = prefs.edit() + val mapStyleInt = prefs.getInt(mapStyleId, 1) + debug("mapStyleId from prefs: $mapStyleInt") + + builder.setSingleChoiceItems(mapStyles, mapStyleInt) { dialog, which -> + debug("Set mapStyleId pref to $which") + editor.putInt(mapStyleId, which) + editor.apply() + dialog.dismiss() + map.setTileSource(loadOnlineTileSourceBase()) } - - if (OfflineSwitch.getInstance().isMapboxStackConnected) { - - // By default, users may download up to 250MB of data for offline use without incurring - // additional charges. This limit is subject to change during the beta. - - // - - - - - - - - - - // 1. Create style package with loadStylePack() call. - - // A style pack (a Style offline package) contains the loaded style and its resources: loaded - // sources, fonts, sprites. Style packs are identified with their style URI. - - // Style packs are stored in the disk cache database, but their resources are not subject to - // the data eviction algorithm and are not considered when calculating the disk cache size. - - binding.stylePackDownloadProgress.visibility = View.VISIBLE - binding.stylePackText.visibility = View.VISIBLE - stylePackCancelable = offlineManager.loadStylePack( - style, - // Build Style pack load options - StylePackLoadOptions.Builder() - .glyphsRasterizationMode(GlyphsRasterizationMode.IDEOGRAPHS_RASTERIZED_LOCALLY) - .metadata(Value(STYLE_PACK_METADATA)) - .build(), - { progress -> - updateStylePackDownloadProgress( - progress.completedResourceCount, - progress.requiredResourceCount, - ) - }, - { expected -> - if (expected.isValue) { - expected.value?.let { stylePack -> - // Style pack download finishes successfully - debug("StylePack downloaded: $stylePack") - if (binding.stylePackDownloadProgress.progress == binding.stylePackDownloadProgress.max) { - debug("Style pack download complete") - binding.stylePackText.visibility = View.INVISIBLE - binding.stylePackDownloadProgress.visibility = View.INVISIBLE - stylePackDownloadSuccess = true - } else { - debug("Waiting for tile region download to be finished.") - } - } - } - expected.error?.let { - stylePackDownloadSuccess = false - // Handle error occurred during the style pack download. - binding.stylePackText.visibility = View.INVISIBLE - binding.stylePackDownloadProgress.visibility = View.INVISIBLE - debug("StylePackError: $it") - } - } - ) - - // - - - - - - - - - - // 2. Create a tile region with tiles for the outdoors style - - // A Tile Region represents an identifiable geographic tile region with metadata, consisting of - // a set of tiles packs that cover a given area (a polygon). Tile Regions allow caching tiles - // packs in an explicit way: By creating a Tile Region, developers can ensure that all tiles in - // that region will be downloaded and remain cached until explicitly deleted. - - // Creating a Tile Region requires supplying a description of the area geometry, the tilesets - // and zoom ranges of the tiles within the region. - - // The tileset descriptor encapsulates the tile-specific data, such as which tilesets, zoom ranges, - // pixel ratio etc. the cached tile packs should have. It is passed to the Tile Store along with - // the region area geometry to load a new Tile Region. - - // The OfflineManager is responsible for creating tileset descriptors for the given style and zoom range. - - val tilesetDescriptor = offlineManager.createTilesetDescriptor( - TilesetDescriptorOptions.Builder() - .styleURI(style) - .minZoom(0) - .maxZoom(10) - .build() - ) - // Use the the default TileStore to load this region. You can create custom TileStores are are - // unique for a particular file path, i.e. there is only ever one TileStore per unique path. - - // Note that the TileStore path must be the same with the TileStore used when initialise the MapView. - binding.tilePackText.visibility = View.VISIBLE - binding.tilePackDownloadProgress.visibility = View.VISIBLE - tilePackCancelable = tileStore.loadTileRegion( - TILE_REGION_ID, // Make this dynamic - TileRegionLoadOptions.Builder() - .geometry(squareRegion) - .descriptors(listOf(tilesetDescriptor)) - .metadata(Value(TILE_REGION_METADATA)) - .acceptExpired(true) - .networkRestriction(NetworkRestriction.NONE) - .build(), - { progress -> - updateTileRegionDownloadProgress( - progress.completedResourceCount, - progress.requiredResourceCount, - ) - } - ) { expected -> - if (expected.isValue) { - // Tile pack download finishes successfully - expected.value?.let { region -> - debug("TileRegion downloaded: $region") - if (binding.tilePackDownloadProgress.progress == binding.tilePackDownloadProgress.max) { - debug("Finished tilepack download") - binding.tilePackDownloadProgress.visibility = View.INVISIBLE - binding.tilePackText.visibility = View.INVISIBLE - tileRegionDownloadSuccess = true - - } else { - debug("Waiting for style pack download to be finished.") - } - } - } - expected.error?.let { - tileRegionDownloadSuccess = false - // Handle error occurred during the tile region download. - binding.tilePackDownloadProgress.visibility = View.INVISIBLE - binding.tilePackText.visibility = View.INVISIBLE - debug("TileRegionError: $it") - } - } - } else { - Toast.makeText( - requireContext(), - R.string.download_region_connection_alert, - Toast.LENGTH_LONG - ).show() - } - } - - /** - * OnLongClick of the map set a position marker. - * If a user long-clicks again, the position of the first marker will be updated - */ - private val longClick = OnMapLongClickListener { - val userDefinedPointImg = - ContextCompat.getDrawable( - requireActivity(), - R.drawable.baseline_location_on_white_24dp - )!! - .toBitmap() - point = Point.fromLngLat(it.longitude(), it.latitude()) - - - /* - Calculate region from user specified position. - 5 miles NE,NW,SE,SW from user center point. - 25 Sq Mile Region - */ - //____________________________________________________________________________________________ - val topRight = calculateCoordinate(45.0, point?.latitude()!!, point?.longitude()!!) - val topLeft = calculateCoordinate(135.0, point?.latitude()!!, point?.longitude()!!) - val bottomLeft = calculateCoordinate(225.0, point?.latitude()!!, point?.longitude()!!) - val bottomRight = calculateCoordinate(315.0, point?.latitude()!!, point?.longitude()!!) - //____________________________________________________________________________________________ - - val pointList = listOf(topRight, topLeft, bottomLeft, bottomRight, topRight) - - squareRegion = LineString.fromLngLats(pointList) - - geoJsonSource = geoJsonSource(boundingBoxId) { - geometry(squareRegion) - } - lineLayer = lineLayer(lineLayerId, boundingBoxId) { - lineCap(LineCap.ROUND) - lineJoin(LineJoin.MITER) - lineOpacity(0.7) - lineWidth(1.5) - lineColor("#888") - } - - if (point != null) { - binding.downloadRegion.visibility = View.VISIBLE - } - - mapView?.getMapboxMap()?.getStyle()?.let { style -> - userTouchPosition.geometry(point!!) - if (!style.styleLayerExists(userTouchLayerId)) { - style.addImage(userPointImageId, userDefinedPointImg) - style.addSource(userTouchPosition) - style.addSource(geoJsonSource) - style.addPersistentLayer(lineLayer) - style.addLayer(userTouchLayer) - } else { - style.removeStyleLayer(lineLayerId) - style.removeStyleSource(boundingBoxId) - style.addSource(geoJsonSource) - style.addLayer(lineLayer) - } - } - mapView?.getMapboxMap().also { mapboxMap -> - mapboxMap?.flyTo( - CameraOptions.Builder() - .zoom(ZOOM) - .center(point) - .build(), MapAnimationOptions.mapAnimationOptions { duration(1000) }) - } - return@OnMapLongClickListener true - } - - /** - * Find's coordinates (Lat,Lon) a specified distance from given (lat,lon) using degrees to determine direction - * @param degrees degree of desired position from current position. (center point is 0,0 and desired point, top right corner, is 45 degrees from 0,0) - * @param lat latitude position (current position lat) - * @param lon longitude position (current position lon) - * @return Point - */ - private fun calculateCoordinate(degrees: Double, lat: Double, lon: Double): Point { - val deg = Math.toRadians(degrees) - val distancesInMeters = - 1609.344 * 2.5 // 1609.344 is 1 mile in meters -> multiplier will be user specified up to a max of 10 - val radiusOfEarthInMeters = 6378137 - val x = - lon + (180 / Math.PI) * (distancesInMeters / radiusOfEarthInMeters) * cos( - deg - ) - val y = - lat + (180 / Math.PI) * (distancesInMeters / radiusOfEarthInMeters) * sin(deg) - return Point.fromLngLat(x, y) - } - - private fun updateStylePackDownloadProgress( - progress: Long, - max: Long, - ) { - binding.stylePackDownloadProgress.max = max.toInt() - binding.stylePackDownloadProgress.progress = progress.toInt() - } - - private fun updateTileRegionDownloadProgress( - progress: Long, - max: Long, - ) { - binding.tilePackDownloadProgress.max = max.toInt() - binding.tilePackDownloadProgress.progress = progress.toInt() - } - - companion object { - private const val ZOOM = 12.5 - private const val TILE_REGION_ID = "tile-region" - private const val STYLE_PACK_METADATA = "outdoor-style-pack" - private const val TILE_REGION_METADATA = "outdoor-tile-region" - } - - private fun downloadRegionDialogFragment() { - val mapDownloadView = layoutInflater.inflate(R.layout.dialog_map_download, null) - val uri = mapDownloadView.findViewById(R.id.uri) - val downloadRegionDialogFragment = AlertDialog.Builder(context) - - - downloadRegionDialogFragment.setView(mapDownloadView) - .setTitle(R.string.download_region_dialog_title) - .setMultiChoiceItems( - R.array.MapMenuCheckbox, - null, - ) { _, _, isChecked -> - if (isChecked) { - if (!uri.isVisible) { - uri.visibility = - View.VISIBLE - } - } else { - if (uri.isVisible) { - uri.visibility = - View.GONE - } - } - } - .setPositiveButton( - R.string.save_btn, null - ) - .setNeutralButton(R.string.view_region_btn) { _, _ -> - if (tileRegionDownloadSuccess && stylePackDownloadSuccess) { - mapView?.getMapboxMap().also { - it?.flyTo( - CameraOptions.Builder() - .zoom(ZOOM) - .center(point) - .build(), - MapAnimationOptions.mapAnimationOptions { duration(1000) }) - if (userStyleURI != null) { - it?.loadStyleUri(userStyleURI.toString()) - } else { - it?.getStyle().also { style -> - style?.removeStyleImage(userPointImageId) - } - } - } - } else { - Toast.makeText( - requireContext(), - R.string.no_download_region_alert, - Toast.LENGTH_SHORT - ).show() - } - } - .setNegativeButton( - R.string.cancel - ) { dialog, _ -> - mapView?.getMapboxMap()?.getStyle { style -> - point = null - userStyleURI = null - style.removeStyleLayer(lineLayerId) - style.removeStyleSource(boundingBoxId) - style.removeStyleLayer(userTouchLayerId) - style.removeStyleSource(userTouchPositionId) - style.removeStyleImage(userPointImageId) - } - binding.downloadRegion.visibility = View.INVISIBLE - - removeOfflineRegions() //TODO: Add to offline manager window - dialog.cancel() - } - - val dialog = downloadRegionDialogFragment.create() + val dialog = builder.create() dialog.show() - dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { - if (uri.isVisible) { - if (uri.text.isNotEmpty()) { - // Save URI - userStyleURI = uri.text.toString() - uri.setText("") // clear text + } - downloadOfflineRegion(userStyleURI!!) - dialog.dismiss() - } else { - Toast.makeText( - requireContext(), - R.string.style_uri_empty_alert, - Toast.LENGTH_SHORT - ).show() + private fun onNodesChanged(nodes: Collection) { + val nodesWithPosition = nodes.filter { it.validPosition != null } + + /** + * Using the latest nodedb, generate GeoPoint + */ + // Find all nodes with valid locations + fun getCurrentNodes(): List { + val mrkr = nodesWithPosition.map { node -> + val p = node.position!! + debug("Showing on map: $node") + val f = GeoPoint(p.latitude, p.longitude) + lateinit var marker: MarkerWithLabel + node.user?.let { + val label = it.longName + " " + formatAgo(p.time) + marker = MarkerWithLabel(map, label) + marker.title = label + marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER) + marker.position = f + marker.icon = ContextCompat.getDrawable( + requireActivity(), + R.drawable.ic_twotone_person_pin_24 + ) } + marker + } + return mrkr + } + nodePositions = getCurrentNodes() + } + + private fun drawOverlays() { + map.overlayManager.overlays().clear() + addCopyright() // Copyright is required for certain map sources + map.overlayManager.addAll(nodeLayer, nodePositions) + } + + /** + * Adds copyright to map depending on what source is showing + */ + private fun addCopyright() { + val copyrightNotice: String = + map.tileProvider.tileSource.copyrightNotice + val copyrightOverlay = CopyrightOverlay(context) + copyrightOverlay.setCopyrightNotice(copyrightNotice) + map.overlays.add(copyrightOverlay) + } + + private fun setupMapProperties() { + if (this::map.isInitialized) { + map.setDestroyMode(false) // keeps map instance alive when in the background. + map.isVerticalMapRepetitionEnabled = false // disables map repetition + map.setScrollableAreaLimitLatitude( + map.overlayManager.tilesOverlay.bounds.actualNorth, + map.overlayManager.tilesOverlay.bounds.actualSouth, + 0 + ) // bounds scrollable map + map.isTilesScaledToDpi = + true // scales the map tiles to the display density of the screen + map.minZoomLevel = + defaultMinZoom // sets the minimum zoom level (the furthest out you can zoom) + map.setMultiTouchControls(true) // Sets gesture controls to true. + map.zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER) // Disables default +/- button for zooming + } + } + + private fun zoomToNodes(controller: IMapController) { + val points: MutableList = mutableListOf() + val nodesWithPosition = + model.nodeDB.nodes.value?.values?.filter { it.validPosition != null } + if ((nodesWithPosition != null) && nodesWithPosition.isNotEmpty()) { + if (nodesWithPosition.size >= 2) { + // Multiple nodes, make them all fit on the map view + nodesWithPosition.forEach { + points.add( + GeoPoint( + it.position!!.latitude, + it.position!!.longitude + ) + ) + } + val box = BoundingBox.fromGeoPoints(points) + val point = GeoPoint(box.centerLatitude, box.centerLongitude) + controller.animateTo(point, nodeZoomLevel, defaultZoomSpeed) } else { - downloadOfflineRegion() - dialog.dismiss() + // Only one node, just zoom in on it + val it = nodesWithPosition[0].position!! + points.add(GeoPoint(it.latitude, it.longitude)) + controller.animateTo(points[0], nodeZoomLevel, defaultZoomSpeed) } } } - private fun loadMapStyleFromPref():String { - val prefs = context?.getSharedPreferences("ui-prefs", Context.MODE_PRIVATE) - val mapStyleId = prefs?.getInt("map_style_id", 1) - debug("mapStyleId from prefs: $mapStyleId") - val mapStyle = when (mapStyleId) { - 0 -> Style.MAPBOX_STREETS - 1 -> Style.OUTDOORS - 2 -> Style.LIGHT - 3 -> Style.DARK - 4 -> Style.SATELLITE - 5 -> Style.SATELLITE_STREETS - 6 -> Style.TRAFFIC_DAY - 7 -> Style.TRAFFIC_NIGHT - else -> Style.OUTDOORS - } - return mapStyle + private fun loadOnlineTileSourceBase(): ITileSource { + val prefs = context?.getSharedPreferences(uiPrefs, Context.MODE_PRIVATE) + val mapSourceId = prefs?.getInt(mapStyleId, 1) + debug("mapStyleId from prefs: $mapSourceId") + return CustomTileSource.mTileSources[mapSourceId!!] } + override fun onPause() { + map.onPause() + super.onPause() + } + + override fun onResume() { + super.onResume() + map.onResume() + } + + override fun onDestroy() { + super.onDestroyView() + map.onDetach() + } + + private inner class MarkerWithLabel(mapView: MapView?, label: String) : Marker(mapView) { + val mLabel = label + + override fun draw(c: Canvas, osmv: MapView?, shadow: Boolean) { + draw(c, osmv) + } + + fun draw(c: Canvas, osmv: MapView?) { + super.draw(c, osmv, false) + + val p = mPositionPixels + + val textPaint = Paint() + textPaint.textSize = 50f + textPaint.color = Color.RED + textPaint.isAntiAlias = true + textPaint.textAlign = Paint.Align.CENTER + + c.drawText(mLabel, (p.x - 0).toFloat(), (p.y - 60).toFloat(), textPaint) + } + } } diff --git a/app/src/main/res/drawable/baseline_download_white_24dp.xml b/app/src/main/res/drawable/baseline_download_white_24dp.xml deleted file mode 100644 index 41ed7875..00000000 --- a/app/src/main/res/drawable/baseline_download_white_24dp.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/baseline_location_on_white_24dp.xml b/app/src/main/res/drawable/baseline_location_on_white_24dp.xml deleted file mode 100644 index 8b4720d5..00000000 --- a/app/src/main/res/drawable/baseline_location_on_white_24dp.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/app/src/main/res/layout/dialog_map_download.xml b/app/src/main/res/layout/dialog_map_download.xml deleted file mode 100644 index 7c205e88..00000000 --- a/app/src/main/res/layout/dialog_map_download.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/item_gesture_alert.xml b/app/src/main/res/layout/item_gesture_alert.xml deleted file mode 100644 index 797354b1..00000000 --- a/app/src/main/res/layout/item_gesture_alert.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/map_not_allowed.xml b/app/src/main/res/layout/map_not_allowed.xml deleted file mode 100644 index b90ab120..00000000 --- a/app/src/main/res/layout/map_not_allowed.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/map_view.xml b/app/src/main/res/layout/map_view.xml index 7b1c190c..7ed1b0c4 100644 --- a/app/src/main/res/layout/map_view.xml +++ b/app/src/main/res/layout/map_view.xml @@ -5,93 +5,22 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="match_parent" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:visibility="visible" + app:layout_constraintEnd_toEndOf="parent" + tools:background="@color/design_default_color_secondary" /> \ No newline at end of file diff --git a/app/src/main/res/layout/offline_region_manager.xml b/app/src/main/res/layout/offline_region_manager.xml deleted file mode 100644 index 397e1a8c..00000000 --- a/app/src/main/res/layout/offline_region_manager.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/user_icon_menu.xml b/app/src/main/res/layout/user_icon_menu.xml deleted file mode 100644 index 88d8f5ec..00000000 --- a/app/src/main/res/layout/user_icon_menu.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index 12ba21d6..d7817540 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -32,10 +32,6 @@ android:id="@+id/preferences_language" android:title="@string/preferences_language" app:showAsAction="withText" /> - Jste si jistý, že chcete změnit kanál? Veškerá komunikace s ostatními vysílači přestane fungovat až do momentu distribuce stejného nastavení na ostatní vysílače. Nová URL kanálu přijata. Chcete se připojit ke kanálu \'%s\' ? - You have analytics disabled. Unfortunately our map provider (mapbox) requires analytics to be allowed for their \'free\' plan. So we have turned off the map view.\n\n - If you would like to see the map, you\'ll need to turn on analytics in the Settings pane (also, for the time being you might need to force restart the application).\n\n - If you are interested in us paying for mapbox (or switching to a different map provider), please post in meshtastic.discourse.group Chybí požadovaná oprávnění, Meshtastic nebude fungovat správně. Prosím změntě oprávnění pro aplikaci. Vysílač je uspaný, nepodařilo se změnit kanál. Nahlášení chyby diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index a2906600..0d2ac198 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -28,9 +28,6 @@ Είστε βέβαιοι ότι θέλετε να αλλάξετε κανάλι? Η επικοινωνία με άλλες συσκευές θα σταματήσεις μέχρι να μοιραστείτε τις ρυθμίσεις του νέου καναλιού. Λήψη URL νέου καναλιού Θέλετε να αλλάξετε ‘%s’ κανάλι? - Έχετε απενεργοποιήσει την ανάλυση δεδομένων. Δυστυχώς ο πάροχος χαρτών μας (mapbox) απαιτεί η ανάλυση δεδομένων να επιτρέπεται στο ‘δωρεάν’ πακέτο. Επομένως έχουμε απενεργοποιήσει το χάρτη.\n\n - Αν επιθυμείτε να δείτε το χάρτη, θα πρέπει να ενεργοποιήσετε την ανάλυση δεδομένων στις Ρυθμίσεις (επίσης - προσωρινά - θα πρέπει να επανεκκινήσετε την εφαρμογή).\n\n - Αν θεωρείτε ότι πρέπει να πληρώνουμε το mapbox (η να αλλάξουμε πάροχο χαρτών), παρακαλώ δημοσιεύστε στο meshtastic.discourse.group Λείπει μια απαιτούμενη άδεια, Meshtastic δεν θα λειτοργεί σωστά. Ενεργοποιήστε τις ρυθμίσεις εφαρμογής Android. Radio σε κατάσταση ύπνου, δεν γίνεται αλλαγή καναλιού Αναφορά Bug diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 82595b28..c3c32f31 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -28,9 +28,6 @@ Vous êtes sur de vouloir changer de canal? Toute communication aux autres nœuds va s\'arrêter jusqu\'à ce que vous partagez les nouveaux réglages. Nouveau URL canal reçu Voulez-vous changer vers canal \'%s\' ? - Vous avez désactivé les analytiques. Malheureusement notre fournisseur de carte (mapbox) a besoin d\'analytiques activés pour le plan \'gratuit\'. Désormais nous avons désactivé l\'apercu carte.\n\n - Si vous désirez voir la carte, vous avez besoin d\'activer les analytiques dans les Réglages (également, provisoirement, il peut être nécessaire de redémarrer l\'application).\n\n - Si vous trouvez que nous devons payer pour mapbox (ou changer de fournisseur de carte), veuillez poster dans meshtastic.discourse.group Une permission indispensable manque, Meshtastic ne peut pas fonctionner. Veuillez modifier dans Réglages. Radio en veille, change de Canal impossible Rapporter Bogue diff --git a/app/src/main/res/values-ga/strings.xml b/app/src/main/res/values-ga/strings.xml index 1b14b234..f61bc3c8 100644 --- a/app/src/main/res/values-ga/strings.xml +++ b/app/src/main/res/values-ga/strings.xml @@ -28,10 +28,6 @@ An bhfuil tú cinnte gur mhaith leat an cainéal a athrú? Stopfaidh gach cumarsáid le nóid eile go dtí go roinnfidh tú na socruithe nua cainéil. URL Cainéal nua faighte Ar mhaith leat aistriú go dtí an cainéal \'%s\'? - Tá anailísíocht díchumasaithe agat. Ar an drochuair, éilíonn ár soláthraí léarscáileanna (bosca léarscáileanna) go gceadófar anailísíocht dá phlean \'saor in aisce\'. - Mar sin, táimid tar éis an radharc léarscáile a mhúchadh. Más mian leat an léarscáil a fheiceáil, beidh ort anailísíocht a chur ar siúl sa phána Socruithe (freisin, faoi - láthair, b’fhéidir go mbeidh ort iallach a chur ar an bhfeidhmchlár atosú). Má tá suim agat muid a íoc as bosca léarscáileanna (nó aistriú chuig soláthraí léarscáileanna eile), - abair é le do thoil i meshtastic.discourse.group. Tá cead riachtanach ar iarraidh, ní bheidh Meshtastic in ann oibriú i gceart. Cumasaigh i socruithe feidhmchláir le do thoil. Bhí an raidió ina chodladh, ní raibh sé in ann an cainéal a athrú Tuairiscigh fabht diff --git a/app/src/main/res/values-ht/strings.xml b/app/src/main/res/values-ht/strings.xml index 5fb52dee..beb4ef76 100644 --- a/app/src/main/res/values-ht/strings.xml +++ b/app/src/main/res/values-ht/strings.xml @@ -28,7 +28,6 @@ Èske ou sèten ke ou vle chanje chènn nan? Tout kominikasyon ak lòt ne elektwonik yo ap kanpe jiskaske ou pataje nouvo paramèt chènn yo. Te resevwa nouvo Chènn URL Eke ou vle chanje a chènn \'%s\'? - Ou gen analitik ki enfim. Malerezman founisè kat jeyografik nou an (mapbox) mande pou analitik yo pèmèt plan gratis. Se konsa, nou te etènn kat la. Si ou ta renmen wè kat jeyografik la ou pral bezwen ouvri analytics nan Paramèt (si ou enterese pou nou peye pou mapbox (oswa pou nou chanje founisè kat jeyografik la) tanpri poste nan meshtastic.discourse.group Manke pèmisyon obligatwa, Meshtastic pap ka fonksyone byen. Tanpri ale bay pèmisyon an nan paramèt aplikasyon android. Radyo t\'ap dòmi, pat ka chanje chènn Report Bug diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index a63c8764..efe79a50 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -27,9 +27,6 @@ Biztosan csatornát akar váltani? Minden kommunikáció a többi állomással megszakad amíg nem osztja meg velük az új csatorna beállításokat. Új csatorna URL érkezett Átkapcsol a(z) \'%s\' csatornára? - Az analitikák küldése ki van kapcsolva. Sajnos a térkép szolgáltatónk (mapbox) megköveteli az analitikák küldését számukra az \'ingyenes\' előfizetéshez. Ezért a térkép nézetet ki kellett kapcsolnunk.\n\n - Ha szeretné látni a térképet, ahhoz be kell kapcsolja az analitikák küldését a program beállítások oldalán (és lehet, hogy az alkalmazást is újra kell indítani hozzá).\n\n - Ha érdeklődne az általunk történő fizetéses megoldás iránt a mapbox felé (vagy egy másik térkép szolgáltatóra váltásról), kérem írjon bejegyzést a meshtastic.discourse.group fórumba. Egy szükséges engedély hiányzik, ezért a Meshtastic nem fog tudni rendesen működni. Kérem engedélyezze az Android alkalmazások beállításai között. A rádió alvó üzemmódban volt, ezért nem lehetett csatornát váltani. Hiba jelentése diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 74cd6d8d..8c328c9e 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -28,10 +28,6 @@ Sei sicuro di voler cambiare canale ? Tutte le comunicazioni con gli altri nodi termineranno fino a quando non condividi le impostazioni del nuovo canale. Nuovo Canale URL ricevuto Vuoi passare al canale \'%s\' ? - YL\'analisi è disabilitata. Sfortunatamente il nostro fornitore di mappe (mapbox) richiede che le analisi siano consentite per il loro piano \'gratuito \'. - Quindi abbiamo disattivato la visualizzazione della mappa. \n\n - Se desideri visualizzare la mappa, dovrai attivare l\'analisi nel riquadro Impostazioni (inoltre, per il momento potresti dover forzare il riavvio dell\'applicazione). \n\n - Se sei interessato a pagare per mapbox (o passare ad un altro fornitore di mappe), scrivi in meshtastic.discourse.group Manca un\'autorizzazione richiesta, Meshtastic non sarà in grado di funzionare correttamente. Si prega di abilitarlo nelle impostazioni dell\'applicazione. La radio dormiva, non poteva cambiare canale. Segnala bug diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 78605295..ac3d65f7 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -28,9 +28,6 @@ チャンネルを変更しますか?新しいチャンネル設定をシェアするまで他のノードとの通信はすべて停止します。 新しいチャンネルURLを受信しました \'%s\チャンネルに変更しますか? - 解析が無効になっています。残念ながら地図プロバイダ(mapbox)は無料プランの場合、解析を有効にする必要があります。マップビューをオフにしました。\n\n -マップを表示したい場合は設定パネルで匿名の診断情報と不具合報告にチェックする必要があります(また当分の間アプリを強制停止して再起動する必要があります)。\n\n -mapboxの有償プラン(または代替地図プロバイダ)を検討される方は meshtastic.discourse.group に書き込んでください。 必要なアクセス権限が拒否されているため、アプリが正常に動作しません。設定により権限を許可してください。 Meshtasticデバイスはスリープ状態です。チャンネルを変更できませんでした。 バグ報告 diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 91c9047e..72c833ae 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -28,7 +28,6 @@ 채널 변경을 원하세요? 채널 설정이 공유되기 전까지 다른 노드와의 통신은 중단됩니다. 새로운 채널 URL 수신 \'%s\' 채널로 변경할 까요? - 분석이 비활성화 되었습니다. 현재 앱에서 사용하는 지도 제공자(mapbox)의 \'무료\' 계정을 사용하기 위해서는 분석을 활성화 해야합니다. 따라서 기본적으로 지도를 비활성화 시켰습니다. 만약 지도를 보길 원한다면 설정 창에서 분석 설정을 켜야합니다(또한, 앱을 강제 재부팅해야 할 수도 있습니다). 만약 mapbox 사용에 대해서 도움주길 원하거나 다른 지도 제공자로 바꾸길 원한다면 포럼에 글을 게시해주세요. 필요로 하는 권한을 얻지 못했습니다. Meshtastic는 정상적으로 작동하지 않을 수도 있습니다. 스마트폰 설정에서 권한을 설정해주세요. 메쉬태스틱기기가 절전모드 중 이므로 채널을 변경할 수 없습니다. 버그 보고 diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index b8f70c89..0938a939 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -28,9 +28,6 @@ Ben je zeker van kanaal te willen veranderen? Alle communicatie met andere nodes wordt gestopt tot je de nieuwe instellingen deelt. Nieuw kanaal URL ontvangen Wil je veranderen naar kanaal \'%s\' ? - Je hebt analytics uitgeschakeld. Spijtig want onze kaartprovider (mapbox) vereist ingeschakelde analytics voor het \'gratis\' plan. Daarom hebben we de kaartmodus uitgeschakeld.\n\n - Indien je de kaart wil zien, is het nodig analytics aan te zetten in de Instellingen (ook is het mogelijk, voorlopig, dat een herstart van de applicatie nodig is).\n\n - Indien je het nodig acht dat we betalen voor mapbox (of veranderen naar een andere kaartprovider), post dan een berichtje in de meshtastic.discourse.group Een vereiste toelating ontbreekt, Meshtastic kan niet goed werken. Graag aanzetten in Instellingen. Radio was in slaapmodus, kon het kanaal niet veranderen Rapporteer Bug diff --git a/app/src/main/res/values-no/strings.xml b/app/src/main/res/values-no/strings.xml index ab30033c..f206a8c6 100644 --- a/app/src/main/res/values-no/strings.xml +++ b/app/src/main/res/values-no/strings.xml @@ -28,9 +28,6 @@ Er du sikker på at du vil endre kanalen? All kommunikasjon med andre noder vil stanse, intill du deler de nye kanalinstillingene. Ny kanal URL mottatt Vil du bytte til \'%s\' kanal? - Du har slått av analytics. Desverre krever kartleverandøren vår (mapbox) at analytics er slått på for deres \'grtis\' plan. Så vi har slått av kartvisning.\n\n - Hvis du vil se kartet, må du slå på analytics i instillingspanelet (også, for øyeblikket, må du kanskje tvangsstoppe og restarte applikasjonen).\n\n - Hvis du er interessert i at vi betaler for mapbox(eller bytter kartleveradøt), vennligst post i meshtastic.discourse.group En påkrevet tilgang mangler, Meshtastic vil ikke fungere korrekt. Vennligst slå på i Android appliksjonsinstillinger. Radio sov.kunne ikke endre kanal Rapporter Feil diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index bf12b3bd..c499cbf5 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -28,9 +28,6 @@ Are you sure you want to change the channel? All communication with other nodes will stop until you share the new channel settings. Odebrano nowy URL kanału Chcesz przełączyć na \'%s\' kanał? - Masz wyłączone analizy. Niestety nasz dostawca map (mapbox) wymaga, aby analizy były dozwolone w ich planie \'free\'Dlatego wyłączyliśmy widok mapy.\n\n -Jeśli chcesz zobaczyć mapę, musisz włączyć analitykę w panelu Ustawienia (również na razie może być konieczne wymuszenie ponownego uruchomienia aplikacji).\n\n -Jeśli jesteś zainteresowany opłaceniem przez nas mapboxa (lub przejściem do innego dostawcy map), napisz na meshtastic.discourse.group Meshtastic potrzebuje %s zezwolenie i lokalizacja muszą być włączone, aby można było znaleźć nowe urządzenia przez Bluetooth. Możesz go później wyłączyć. Radio było w trybie uśpienia, nie mogło zmienić kanału Zgłoś bug diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 8f91e4f9..6261501a 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -28,9 +28,6 @@ Tem certeza que deseja mudar de canal? Toda comunicação com os outros dispositivos será interrompida até serem compartilhadas as novas configurações do canal. Novo link de canal recebido Deseja mudar para o canal \'%s\'? - O Google Analytics está desativado. Infelizmente a plataforma de mapas utilizada (Mapbox) requer este recurso ativado para uso do plano \’gratuito\’ . Tivemos que desativar a visualização do mapa.\n\n - Para poder visualizar o mapa será necessário ativar o Google Analytics na configuração do Android (pode ser necessário forçar o reinício do aplicativo).\n\n - Se tiver interesse em que o Meshtastic use um plano pago do Mapbox (ou mude para uma plataforma de mapas diferente), por favor envie uma mensagem em meshtastic.discourse.group Meshtastic precisa da permissão de %s e da localização ativada para encontrar novos dispositivos via bluetooth. Você pode desativar novamente depois. Rádio estava em suspensão (sleep), não foi possível mudar de canal Informar Bug diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 880878e9..0f46fff8 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -27,9 +27,6 @@ Tem certeza que deseja mudar de canal? Todas as comunicações com outros nós serão interrompidas até que partilhe as novas configurações do canal. Novo Link Recebido do Canal Pretende mudar para o canal \'%s\' ? - Tem os dados analícos desativados. Infelizmente o fornecedor do mapa (mapbox) requer dos dados analíticos estejam activados para o seu plano \'gratuito\' . Por isso a visualização do mapa esta desativado.\n\n - Se pretender visualizar o mapa, vai necessitar de ativar os dados anaíticos no painel Configurações (também pode ser necessário forçar o reinício do aplicativo). \n\n - Se estiver interessado em pagarmos pelo mapbox (ou mudar para um provedor de mapas diferente), contacte através de meshtastic.discourse.group Meshtastic precisa da permissão de %s e da localização ativada para encontrar novos dispositivos via bluetooth. Você pode desativar novamente depois. O rádio estava a dormir, não conseguia mudar de canal Reportar Bug diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 9906c35b..8c8424a0 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -28,9 +28,6 @@ Ești sigur că vrei să schimbi canalul? Toate comunicațiile cu alte noduri vor fi oprite până când setezi aceleași detalii pe alte noduri. Am primit un nou URL de canal Vrei să faci schimbul \'%s\' canalului? - Ai analiticele dezactivate. Din nefericire providerul hărților (mapbox) necesită analitice în planul \'gratuit\'. Așadar am dezactivat harta.\n\n - Dacă vrei să vezi harta, trebuie să pornești analiticele în panoul de setări (s-ar putea să fii nevoit să restartezi aplicația).\n\n - Dacă sugerezi să plătim pentru mapbox (sau să schimbăm providerul hărții), te rog, postează în meshtastic.discourse.group O permisiune necesară lipsește, Meshtastic nu o să funcționeze corespunzător. Te rugăm activează-o în setările Android. Nu am putut să schimb canalul deoarece dispozitivul era în sleep mode Raportează Bug diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 87ef9a60..2cbcdb3a 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -28,9 +28,6 @@ Вы уверены, что хотите изменить канал? Связь с другими устройствами будет прервана, пока вы не поделитесь новыми настройками канала. URL нового канала получен Вы хотите переключиться на \'%s\' канал? - У вас отключена аналитика. К сожалению, наш поставщик карт (mapbox) требует, чтобы аналитика была разрешена для «бесплатного» использования. Мы вынуждены отключить карту.\n\n - Если вы хотите использовать карту, вам нужно включить аналитику на панели настроек (также, на данный момент вам может потребоваться принудительный перезапуск приложения).\n\n - Если вы заинтересованы в том, чтобы мы платили за карту (или переходили на другого поставщика карт), отправьте сообщение по адресу meshtastic.discourse.group. Требуемое разрешение отсутствует, Meshtastic не сможет работать должным образом. Пожалуйста, включите в настройках приложения. Радиомодуль в режиме сна, смена канала невозможна Сообщить об ошибке diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 41ee01ff..6da0d954 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -28,9 +28,6 @@ Ste si istý, že chcete zmeniť kanál? Všetka komunikácia s ostatnými vysielačmi prestane fungovať až do momentu distribúcie rovnakého nastavenia na ostatné vysielače. Obdržaná nová URL kanálu. Chcete sa prpnúť na kanál \'%s\' ? - You have analytics disabled. Unfortunately our map provider (mapbox) requires analytics to be allowed for their \'free\' plan. So we have turned off the map view.\n\n - If you would like to see the map, you\'ll need to turn on analytics in the Settings pane (also, for the time being you might need to force restart the application).\n\n - If you are interested in us paying for mapbox (or switching to a different map provider), please post in meshtastic.discourse.group Aplikácia Meshtastic nemá pridelené požadované oprávnenie a pravdepodobne nebude fungovať správne. Prosím povoľte tieto oprávnenia v nastaveniach aplikácie. Vysielač je uspatý, nepodarilo sa zmeniť kanál Nahlásenie chyby diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 96340e38..4fa0e9f4 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -28,7 +28,6 @@ Ali ste prepričani, da želite spremeniti kanal? Vsa komunikacija z drugimi vozlišči se ustavi, dokler ne delite novih nastavitev kanala. Prejet je bil novi URL kanala Ali želite preklopiti na kanal \'%s\' ? - Vaša analitika je onemogočena. Na žalost naš ponudnik zemljevidov (mapbox) zahteva analitiko, ki je dovoljena za njihov "brezplačen" načrt. Torej smo izključili prikaz zemljevida. \n\nČe želite videti zemljevid, boste morali v podoknu z nastavitvami vklopiti analitiko (morda boste morali znova zagnati aplikacijo). \n\nČe vas zanima, kako plačujemo za karto (ali preklopiti na drugega ponudnika zemljevidov), pošljite sporočilo v meshtastic.discourse.group Manjka zahtevano dovoljenje: Meshtastic ne bo mogel pravilno delovati. Omogočite v nastavitvah aplikacije za Android. Radio je "spal", sprememba kanala ni bila izvedena. Prijavi napako diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 33d304a9..9d7d3178 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -28,9 +28,6 @@ Kanalı değiştirmek istediğinize emin misiniz? Yeni kanal ayarlarını paylaşana dek tüm node\'lar ile iletişim sonlanacak. Yeni Kanal Adresi alındı \'%s\' kanalına geçmek istiyor musunuz? - Analitik raporları kapattınız. Harita sağlayıcımız (mapbox) ücretsiz kullanım paketi için analitik raporları gerektiriyor maalesef. Bu yüzden harita görünümü pasif hale getirdik.\n\n - Haritayı görmek istiyorsanız, Ayarlar bölümünden analitik raporları aktif hale getirmeniz gerekiyor. (ayrıca, şu an bunun için uygulamayı tümüyle kapatıp yeniden açmanız gerekebilir).\n\n - Eğer mapbox için ödeme yapmamız (ya da başka bir harita sağlayıcıya geçme) konusunda ilgiliyseniz, lütfen meshtastic.discourse.group sayfasında paylaşınız. Gerekli bir izin eksik, Meshtastic düzgün çalışamayacak. Lütfen Android ayarlarından izni aktif hale getiriniz. Telsiz uyku durumundaydı, kanal değiştirilemedi Hata Bildir diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index ef65f535..1816ec78 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -28,9 +28,6 @@ 您确定要修改通信频道吗?这将会使你与其他节点断开通信. 收到新的频道URL 您是否要切换到\'%s\'频道? - 您已禁用分析。 不幸的是,我们的地图提供商 (mapbox) 要求允许分析 \“免费”\计划。 所以我们关闭了地图视图.\n\n - 如果您想查看地图,您将需要在“设置”窗格中打开分析(此外,您可能暂时需要强制重新启动应用程序).\n\n - 如果您对我们为 mapbox付费或切换到不同的地图提供商感兴趣,请在 meshtastic.discourse.group 中发帖 缺少所需的权限,Mesh网络将无法正常工作.请在应用程序设置中启用. 设备正在休眠,无法更改频道 报告BUG diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 38e18b01..38fea1c7 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -1,36 +1,60 @@ - - Use Custom URI? - - @string/preferences_system_default - English - Čeština - Chinese 中文 - Deutsch - Español - Français - Gaeilge - Greek ελληνικά - Haiti - Italiano - Japanese 日本語 - Korean 한국어 - Magyar - Nederlands - Norge - Polski - Português - Português do Brasil - Română - Russian Pусский - Shqip - Slovenský - Slovenščina - Suomi - Svenska - Türkçe + + @string/preferences_system_default + + English + + Čeština + + Chinese 中文 + + Deutsch + + Español + + Français + + Gaeilge + + Greek ελληνικά + + Haiti + + Italiano + + Japanese 日本語 + + Korean 한국어 + + Magyar + + Nederlands + + Norge + + Polski + + Português + + Português do Brasil + + Română + + Russian Pусский + + Shqip + + Slovenský + + Slovenščina + + Suomi + + Svenska + + Türkçe @@ -63,13 +87,9 @@ tr - Streets - Outdoors - Light - Dark - Satellite - Satellite Streets - Navigation Day - Navigation Night + OpenStreetMap + USGS TOPO + USGS Satellite + ESRI World Overview \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 69004fb2..7ca872e2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -32,9 +32,6 @@ Are you sure you want to change the channel? All communication with other nodes will stop until you share the new channel settings. New Channel URL received Do you want to switch to the \'%s\' channel? - You have analytics disabled. Unfortunately our map provider (mapbox) requires analytics to be allowed for their \'free\' plan. So we have turned off the map view.\n\n - If you would like to see the map, you\'ll need to turn on analytics in the Settings pane (also, for the time being you might need to force restart the application).\n\n - If you are interested in us paying for mapbox (or switching to a different map provider), please post in meshtastic.discourse.group Meshtastic needs %s permission and location must be turned on to find new devices via bluetooth. You can turn it off again afterwards. Radio was sleeping, could not change channel Report Bug @@ -140,7 +137,7 @@ Unable to download style pack Language (restart needed) System default - Map style + Map Source Resend Shutdown Reboot diff --git a/build.gradle b/build.gradle index fd085748..57b5b693 100644 --- a/build.gradle +++ b/build.gradle @@ -40,20 +40,6 @@ buildscript { allprojects { repositories { - maven { - // Per https://docs.mapbox.com/android/maps/guides/install/ we now need to signin to download mapbox lib - url 'https://api.mapbox.com/downloads/v2/releases/maven' - authentication { - basic(BasicAuthentication) - } - credentials { - // Do not change the username below. - // This should always be `mapbox` (not your username). - username = 'mapbox' - // Use the secret token you stored in gradle.properties as the password - password = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: "" - } - } google() mavenCentral() // jcenter()