Compare commits

..

12 Commits

Author SHA1 Message Date
Konstantin Pastbin
86b266a579 [styles] Regenerate
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
2025-06-16 14:59:48 +07:00
Yannik Bloscheck
a9c9caaeb5 Made beach color a bit more distinct 2025-06-16 14:59:03 +07:00
Yannik Bloscheck
85fa291e3e Made parking a slightly bit more visible 2025-06-16 14:57:34 +07:00
Yannik Bloscheck
082403f506 Incorporated feedback 2025-06-16 14:57:34 +07:00
Yannik Bloscheck
af8b4a99a9 Adjusted bicycle paths in the outdoor style to be more in sync with the default style 2025-06-16 14:57:34 +07:00
Yannik Bloscheck
d5e0919079 Improved distinguishability of the different bicycle paths 2025-06-16 14:57:34 +07:00
Yannik Bloscheck
d736fa2399 Improved road visibility further 2025-06-16 14:57:34 +07:00
Yannik Bloscheck
ed796c1ffe Fixed typo in style file 2025-06-16 14:57:34 +07:00
Yannik Bloscheck
71142c794b Improved road visibility 2025-06-16 14:57:33 +07:00
Yannik Bloscheck
1bfc448af4 Custom heath color 2025-06-16 14:57:33 +07:00
Yannik Bloscheck
d4bb911fe2 Incorporated feedback about improved light map style 2025-06-16 14:57:33 +07:00
Yannik Bloscheck
36b8da5aec Improved light map style and separated motorways and trunk roads 2025-06-16 14:57:33 +07:00
854 changed files with 5979 additions and 11243 deletions

View File

@@ -1,8 +0,0 @@
name: dco
on: [pull_request]
jobs:
check:
runs-on: codeberg-tiny
steps:
- uses: https://github.com/KineticCafe/actions-dco@v1

View File

@@ -41,7 +41,7 @@ jobs:
LANG: en_US.UTF-8 # Fastlane complains that the terminal is using ASCII.
LANGUAGE: en_US.UTF-8
LC_ALL: en_US.UTF-8
TEST_RESULTS_BUNDLE_NAME: CoMaps-Test-Results
TEST_RESULTS_BUNDLE_NAME: OMaps-Test-Results
strategy:
fail-fast: false
matrix:
@@ -74,8 +74,8 @@ jobs:
shell: bash
run: |
xcodebuild test \
-workspace xcode/CoMaps.xcworkspace \
-scheme CoMaps \
-workspace xcode/omim.xcworkspace \
-scheme OMaps \
-configuration Debug \
-sdk iphonesimulator \
-destination 'platform=iOS Simulator,name=iPhone 16 Pro Max,OS=latest' \
@@ -97,8 +97,8 @@ jobs:
shell: bash
run: |
xcodebuild build \
-workspace xcode/CoMaps.xcworkspace \
-scheme CoMaps \
-workspace xcode/omim.xcworkspace \
-scheme OMaps \
-configuration Release \
-destination 'generic/platform=iOS' \
-quiet \

View File

@@ -15,7 +15,6 @@ jobs:
LANGUAGE: en_US.UTF-8
LC_ALL: en_US.UTF-8
TEST_RESULTS_BUNDLE_NAME: CoMaps-Test-Results
SIMULATOR_DEVICE: 'iPhone 16 Pro Max'
strategy:
fail-fast: false
matrix:
@@ -51,15 +50,12 @@ jobs:
if: matrix.buildType == 'Debug'
shell: bash
run: |
# Start sim before the build to make sure it's booted when tests start.
xcrun simctl boot "${{ env.SIMULATOR_DEVICE }}" || true
xcrun simctl bootstatus "${{ env.SIMULATOR_DEVICE }}" -b
xcodebuild test \
-workspace xcode/CoMaps.xcworkspace \
-scheme CoMaps \
-workspace xcode/omim.xcworkspace \
-scheme OMaps \
-configuration Debug \
-sdk iphonesimulator \
-destination "platform=iOS Simulator,name=${{ env.SIMULATOR_DEVICE }},OS=latest" \
-destination 'platform=iOS Simulator,name=iPhone 16 Pro Max,OS=latest' \
-quiet \
-resultBundlePath ${{ env.TEST_RESULTS_BUNDLE_NAME }}.xcresult \
CODE_SIGNING_REQUIRED=NO \
@@ -78,8 +74,8 @@ jobs:
shell: bash
run: |
xcodebuild build \
-workspace xcode/CoMaps.xcworkspace \
-scheme CoMaps \
-workspace xcode/omim.xcworkspace \
-scheme OMaps \
-configuration Release \
-destination 'generic/platform=iOS' \
-quiet \

2
.gitignore vendored
View File

@@ -62,7 +62,7 @@ iphone/*/build/*
tools/emacsmode/build
**/DerivedData/*
**/xcshareddata/*
!iphone/Maps/Maps.xcodeproj/xcshareddata/xcschemes/CoMaps.xcscheme
!iphone/Maps/Maps.xcodeproj/xcshareddata/xcschemes/OMaps.xcscheme
**/xcuserdata
**/xcschemes
iphone/**/*.moved-aside

View File

@@ -7,10 +7,6 @@ CoMaps contributors:
(in alphabetic order)
--------------------------------------------------------------------------------
clover sage
Harry Bond <me@hbond.xyz>
vikiawv
--------------------------------------------------------------------------------
Organic Maps (formerly OMaps) contributors:
(in alphabetic order)

View File

@@ -1,8 +1,8 @@
To build, install and run e.g. a Web Debug version on your device/emulator: './gradlew runWebDebug'
Or to compile a redistributable Fdroid Test apk for testing: './gradlew assembleFdroidBeta'
Or to compile a redistributable Fdroid Beta apk for testing: './gradlew assembleFdroidBeta'
Or to build test apks for all flavors: './gradlew assembleBeta'
Or to build beta apks for all flavors: './gradlew assembleBeta'
To see all available build targets './gradlew tasks'

View File

@@ -7,6 +7,7 @@ buildscript {
// Detect flavors from the task name.
def taskName = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase()
def isFdroid = taskName.contains('fdroid')
def isBeta = taskName.contains('beta')
dependencies {
classpath libs.android.tools
@@ -296,6 +297,7 @@ android {
ndk.debugSymbolLevel = 'symbol_table'
}
// TODO(@pastk): rename to "test" everywhere in code
beta {
applicationIdSuffix '.test'
versionNameSuffix '-test'

View File

@@ -1 +1 @@
Jednoduchá navigace v mapě - Objevte více na své cestě Vyvíjeno komunitou
Jednoduchá navigace v mapě Objevte více na své cestě Vyvíjeno komunitou

View File

@@ -1,8 +1,8 @@
Kartenfarben aufgefrischt heller, wärmer, freundlicher!
OSM-Editor: „Stockwerk“ Feld hinzugefügt
Symbole für Tankstellen und Ladestationen aktualisiert
Farben einiger UI Elemente überarbeitet
Funktionierende Links zum Teilen von Orten
Falsch angezeigte Kartengröße nach Downloadfehlern korrigiert
Kleine Sprünge des Standortpfeils in bestimmten Fällen behoben
Bugfixes für Android 5 & 6
OpenStreetMap Daten vom 2. Juni
Neue Einstellungsoption zum Ändern oder Ausblenden der "Über CoMaps" Schaltfläche ganz links
Routen als GPS Track speichern
Qingdao Metro, Gärtnereien, Leitplanken, Leitern, Studios, Tanzsäle, Feuerstellen und Stundenhotels hinzugefügt
transparente Navigationsleiste im Light Mode
Mastodon und Bluesky Kontaktoptionen für POIs und im OSM-Editor hinzugefügt
Anzeige der Kompassgradzahl in der Richtungspfeilansicht
Übersetzungen aktualisiert

View File

@@ -1,8 +1,8 @@
refresh map colors - lighter, warmer, friendlier!
OSM editor: add a "level" field
update gas and charging stations icons
update colors of some UI elements
fix location sharing links
fix wrong displayed map size after download errors
fix small location arrow jumps in some cases
android 5&6 bugfixes
OpenStreetMap data as of June 2
add a setting to change the leftmost button or hide it
save built routes as tracks
add Qingdao metro, plant nurseries, highway guard rails, ladders, studios, dance venues, firepits, love hotels
transparent system navigation bar in the light mode
add Mastodon and Bluesky contact options to POIs and OSM editor
display Azimuth angle in direction arrow view
update translations

View File

@@ -1,8 +0,0 @@
• colores del mapa renovados - más claros, cálidos y amigables!
• editor OSM: campo "nivel" agregado
• actualización de íconos de carga de combustible y electricidad
• actualización de colores de algunos elementos de IU
• corrección de links para compartir ubicación
• corrección de tamaño incorrecto del mapa luego de errores de descarga
• corrección de pequeños saltos de flechas de posición en algunos casos
• corrección de bugs en Android 5 y 6

View File

@@ -1,32 +0,0 @@
Yhteisövetoinen, ilmainen ja avoimeen lähdekoodiin perustuva karttasovellus, jonka pohjalla käytetään OpenStreetMapin avointa karttadataa. Sovelluksen kehityksessä on sitouduttu läpinäkyvyyteen, yksityisyyteen ja voittoa tavoittelemattomuuteen. CoMapsin projekti on haarautunut Organic Mapsista, joka taas on haarautunut aiemmin Maps.ME:stä
Lue lisää projektin tavotteista ja suunnasta osoitteesta <b><i>codeberg.org/comaps</i></b>.
Liity yhteisöön ja auta kehittämään paras saatavilla oleva karttasovellus
• Käytä sovellusta ja kerro siitä myös muille
• Anna palautetta ja raportoi ongelmia
• Päivitä karttoja, joko sovelluksessa tai OpenStreetMapin verkkosivuilla
‣ <b>Offline-painotteinen</b>: Suunnittele ja navigoi ulkomailla ilman mobiiliverkkoja. Kaikki sovelluksen toiminnot on suunniteltu käytettäväksi ilman verkkoyhteyttä.
‣ <b>Kunnioittaa yksityisyyttä</b>: Sovellus on suunniteltu yksilön yksityisyys silmälläpitäen. Sovellus ei tunnista tai kerää tietoja sinusta. Mainosvapaa.
‣ <b>Yksinkertainen ja viimeistelty</b>: Olennaiset ominaisuudet, joita on helppo käyttää.
‣ <b>Säästä akkua ja tallennustilaa</b>: Ei kuluta akkua, kuten muut navigointisovellukset. Kompaktit kartat säästävät arvokasta tallennustilaa puhelimessasi.
‣ <b>Ilmainen ja yhteisön luoma</b>: Vapaaehtoiset, kuten sinä olette auttaneet sovelluksen kehityksessä lisäämällä paikkoja OpenStreetMap:iin, testaamalla sovellusta ja antamalla palautetta. Voit myös auttaa kehittämällä ominaisuuksia ja lahjoittamalla sovelluskehitykseen
‣ <b>Avoin ja läpinäkyvä päätöksenteko sekä rahoitus. Voittoa tavoittelematon ja täysin avoimeen lähdekoodiin perustuva.</b>
<b>Tärkeimmät ominaisuudet</b>:
• Ladattavat yksityiskohtaiset kartat paikoista, joita ei löydy edes Google Maps:sta
• Ulkoilutila, josta löytyy korostettuna reitit, leirintäpaikat, vesipisteet, huiput ja korkeuserot yms.
• Kävely- ja pyörätiet
• Kiinnostavat paikat, kuten ravintolat, huoltoasemat, hotellit, kaupat, nähtävyydet ja monta muuta
• Etsi nimellä, osoitteella tai kiinnostavan paikan kategorialla
• Navigointi ääni-ilmoituksilla kävellessä, pyöräillessä tai ajaessa
• Tallenna suosikkipaikkasi yhdellä napautuksella
• Offline Wikipedia-artikkelit
• Maanalaisen liikenteen tasot ja ohjeet
• Reittien tallennus
• Tuo ja vie kirjanmerkkejä ja reittejä KML-, KMZ- ja GPX-formaateissa
• Tumma tila iltaa ja yötä varten
• Paranna karttadataa kaikille sisäänrakennetulla editorilla
<b>Vapaus on täällä</b>
Löydä matkasi ja navigoi maailmalla yksityisyyden ja yhteisön tukemana!

View File

@@ -1 +1 @@
CoMaps - Navigoi ilman verkkoyhteyttä yksityisesti
CoMaps - Vaella, pyöräile, autoile ilman verkkoyhteyttä, yksityisesti

View File

@@ -1,8 +1,8 @@
Mise à jour des couleurs de la carte, plus claires, plus chaudes et plus conviviales
Editeur OSM: ajout du champ "level"
Mise à jour des icônes des stations-service et bornes de recharge
Mise à jour des couleurs de certains éléments d'interface
Correction de lien de partage
Correction de la taille d'une carte suite à une erreur de téléchargement
Correction de saut de la localisation dans certaines situations
Corrections de bug sur Android 5&6
Données OpenStreetMap du 02 juin
Ajout d'une option pour personnaliser le bouton tout à gauche sur l'écran principal
Ajout de la possibilité d'enregistrer un itinéraire en tant que traces GPS
Ajout du métro de Qingdao, et divers objets sur la carte
Support de la barre de navigation transparent en mode clair
Ajout des tags Mastodon et Bluesky sur les lieux et dans l'éditeur
Affichage de l'azimut
Mise à jour des traductions

View File

@@ -0,0 +1,8 @@
• Data di OpenStreetmap fino a giugno 2°
• Nuova impostazione per cambiare o modificare la positione del tasto sinistra
• Salvare i percorsi costruiti come tracce
• È stato aggiunto: metropolitana di Qingdao, giardinaggi, guardrail, scale, studio,
sala da ballo, focolari, love hotel
• Barra di navigatione transparente di sisteme in moda luce
• Aggiungi le opzioni di contatto Mastodon e Bluesky ai POI e all'editor di OSM
• Visualizza l'angolo di azimut nella freccia di direzione

View File

@@ -1 +0,0 @@
CoMaps - Wandel, fiets, rijdt offline met privacy

View File

@@ -1,8 +1,8 @@
Atualizadas as cores do mapa - mais claras, quentes e amigáveis!
Editor OSM: adicionado um campo de "andar"
Atualizados ícones de postos de gasolina e recarga
• Atualizadas cores de alguns elementos da interface do usuário
Correção de links de compartilhamento de localização
Correção de erros de tamanho de mapa exibidos incorretamente após download
Correção de pequenos saltos na seta de localização em alguns casos
Correções de bugs do Android 5 e 6
Dados do OSM de 2/06
Adicionada uma configuração para alterar ou ocultar o botão mais à esquerda
Salve rotas construídas como trilhas
• Adicionado metrô de Qingdao, viveiros de plantas, guarda-corpos de rodovias, escadas, estúdios, casas de dança, fogueiras e motéis
Barra de navegação do sistema transparente no modo claro
Adicionadas opções de contato Mastodon e Bluesky aos POIs e ao editor OSM
Exibição de ângulo de azimute na visualização de seta de direção
Novas traduções

View File

@@ -1,55 +0,0 @@
Um aplicativo de mapas gratuito e de código aberto, liderado pela comunidade, baseado em dados do OpenStreetMap e reforçado pelo compromisso com a transparência, privacidade e sem fins lucrativos. O CoMaps é um fork/spin-off do Organic Maps, que por sua vez é um fork do Maps.ME.
Leia mais sobre os motivos do projeto e sua direção em <b><i>codeberg.org/comaps</i></b>.
Junte-se à comunidade e ajude a criar o melhor aplicativo de mapas.
• Use o aplicativo e divulgue-o.
• Envie feedback e relate problemas.
• Atualize os dados do mapa no aplicativo ou no site do OpenStreetMap.
‣ <b>Foco offline</b>: Planeje e navegue em sua viagem ao exterior sem a necessidade de sinal de celular, pesquise pontos de referência durante uma caminhada distante, etc. Todas as funções do aplicativo foram projetadas para funcionar offline.
‣ <b>Respeitando a privacidade</b>: O aplicativo foi projetado com a privacidade em mente - não identifica pessoas, não rastreia e não coleta informações pessoais. Sem anúncios.
‣ <b>Simples e sofisticado</b>: recursos essenciais e fáceis de usar que simplesmente funcionam.
‣ <b>Economiza bateria e espaço</b>: Não consome muita bateria como outros aplicativos de navegação. Mapas compactos economizam espaço precioso no seu celular.
‣ <b>Gratuito e desenvolvido pela comunidade</b>: Pessoas como você ajudaram a desenvolver o aplicativo adicionando lugares ao OpenStreetMap, testando e dando feedback sobre os recursos e contribuindo com suas habilidades de desenvolvimento e dinheiro.
‣ <b>Tomada de decisões e finanças abertas e transparentes, sem fins lucrativos e totalmente de código aberto.</b>
<b>Principais recursos</b>:
• Mapas detalhados para download com locais não disponíveis no Google Maps
• Modo ao ar livre com trilhas em destaque, acampamentos, fontes de água, picos, curvas de nível, etc.
• Trilhas para caminhada e ciclovias
• Pontos de interesse como restaurantes, postos de gasolina, hotéis, lojas, pontos turísticos e muito mais
• Pesquise por nome, endereço ou por categoria de ponto de interesse
• Navegação com anúncios de voz para caminhadas, ciclismo ou direção
• Marque seus lugares favoritos com um único toque
• Artigos offline da Wikipédia
• Camada e direções de transporte público do metrô
• Gravação de trilhas
• Exporte e importe favoritos e trilhas nos formatos KML, KMZ e GPX
• Um modo escuro para usar à noite
• Aprimore os dados do mapa para todos usando um editor básico integrado
<b>A Liberdade Chegou</b>
Descubra sua jornada, navegue pelo mundo com privacidade e comunidade em primeiro lugar!

View File

@@ -1 +0,0 @@
Navegação fácil nos mapas - Descobre mais sobre o teu percurso - Feito por todos

View File

@@ -1 +1 @@
CoMaps - Mapas e Navegação - Offline e Privada
CoMaps - Andar, Pedalar, Dirigir Offline com Privacidade

View File

@@ -1,33 +1,26 @@
Бесплатное и свободное картографическое приложение, основанное на данных OpenStreetMap и подкреплённое обязательствами по прозрачности, конфиденциальности и некоммерческой направленности. CoMaps это ответвление от Organic Maps, которое, в свою очередь, является ответвлением от Maps.ME.
Бесплатное картографическое приложение с открытым исходным кодом, основанное на данных OpenStreetMap и подкрепленное обязательствами по прозрачности, конфиденциальности и некоммерческому характеру. CoMaps - это форк/ответвление Organic Maps, который, в свою очередь, является форком Maps.ME.
Подробнее о причинах проекта и его направлении читайте на <a href="https://codeberg.org/comaps">сайте</a>.
Присоединяйтесь к сообществу и помогите создать лучшее приложение с картами
• Используйте приложение и распространяйте информацию о нём
• Оставляйте отзывы и сообщайте о проблемах
• Обновляйте данные карт в приложении или на веб-сайте OpenStreetMap
‣ <b>Приоритет на работу без интернета</b>: Планируйте и ориентируйтесь в путешествии за границей, не нуждаясь в сотовой связи и т.д. Всё в приложении рассчитано на работу в автономном режиме.
‣ <b>Соблюдение конфиденциальности</b>: Приложение разработано с учётом требований конфиденциальности — оно не идентифицирует людей, не отслеживает и не собирает личную информацию. Без рекламы.
‣ <b>Простота и отточенность</b>: Основные и простые в использовании функции, которые просто работают.
‣ <b>Приоритет на работу без интернета</b>: Планируйте и ориентируйтесь в путешествии за границей, не нуждаясь в сотовой связи и т.д. Все функции приложения рассчитаны на работу в автономном режиме.
‣ <b>Соблюдение конфиденциальности</b>: Приложение разработано с учетом требований конфиденциальности - оно не идентифицирует людей, не отслеживает и не собирает личную информацию. Без рекламы.
‣ <b>Простота и Элегантность</b>: Необходимые и легкие в использовании функции, которые просто работают.
‣ <b>Экономия заряда батареи и места на устройстве</b>: Не разряжает аккумулятор, как другие приложения для навигации. Компактные карты экономят драгоценное место на вашем телефоне.
‣ <b>Бесплатное и созданное сообществом</b>: Такие люди, как и вы, помогали создавать приложение, добавляя места в OpenStreetMap, протестировав и оставляя отзывы о функциях, а также вложив свои навыки и деньги в разработку.
‣ <b>Открытое и прозрачное принятие решений, финансовая отчётность, некоммерческая организация и полностью открытый исходный код.</b>
‣ <b>Бесплатное и созданное сообществом</b>: Люди, подобные вам, помогали создавать приложение, добавляя места в OpenStreetMap, тестируя и оставляя отзывы о функциях, а также вкладывая свои навыки и деньги в разработку..
‣ <b>Открытое и прозрачное принятие решений, финансовая отчетность, некоммерческая организация и полностью открытый исходный код.</b>
<b>Главные возможности</b>:
Скачиваемые и подробные карты с местами, которые недоступны в Google Maps
Уличный режим с отмеченными туристическими тропами, кемпингами, источниками воды, вершинами, контурными линиями и т.д.
<b>Главные особенности</b>:
Загружаемые и подробные карты с местами, которые недоступны в Google Maps
Режим Outdoor с отмеченными туристическими тропами, кемпингами, источниками воды, вершинами, контурными линиями и т.д.
• Пешеходные переходы и велодорожки
Интересные места, такие как: рестораны, заправочные станции, гостиницы, магазины, достопримечательности и многое другое
• Поиск по названию или адресу или по категории достопримечательностей
Точки интереса, такие как: рестораны, заправочные станции, отели, магазины, достопримечательности и многое другое
• Поиск по имени, адресу или категории достопримечательностей
• Навигация с голосовыми уведомлениями для пешеходов, велосипедистов или водителей
• Возможность добавлять любимые места в закладки одним нажатием
Скачиваемые страницы Википедии
• Возможность добавлять любимые места в закладки одним касанием
Загружаемые страницы Википедии
• Слой общественного транспорта (метро)
• Запись маршрута
• Экспорт и импорт закладок и маршрутов в форматах KML, KMZ, GPX
Тёмный режим для использования в ночное время
• Улучшение данных карты для всех с помощью базового встроенного редактора
Темный режим для использования в ночное время
• Улучшение картографических данных для всех с помощью базового встроенного редактора
• Поддержка Android Auto и CarPlay
<b>Свобода здесь</b>
Откройте для себя путешествия, навигацию по миру, ставя во главе приватность и сообщество!
<i>Свобода здесь - Открой для себя поездки, навигацию по миру, ставя приватность и сообщество во главе</i>

View File

@@ -1,8 +1,7 @@
обновлены цвета карты — теперь они светлее, теплее и дружелюбнее
редактор OSM: добавлено поле «этаж»
обновлены иконки заправок и зарядных станций
обновлены цвета некоторых элементов интерфейса
исправлена ссылка на карту при попытке поделиться местоположением
исправлено неверное отображение размера карты после ошибок загрузки
исправлены мелкие скачки стрелки местоположения в некоторых случаях
• исправления ошибок для Android 5 и 6
карты OpenStreetMap от 2 июня
настройка для изменения функции левой кнопки или её скрытия
сохранение построенных маршрутов в виде треков
добавлены: метро в Qingdao, питомники растений, отбойники на шоссе, постоянные лестницы-стремянки, студии, места для танцев, кострища, отели любви
прозрачная полоска с системными кнопками (в светлом режиме)
в объекты на карте (а также в их редактор) добавлены Mastodon и Bluesky контакты
к стрелке направления на выбранный объект добавлен азимут

View File

@@ -1 +0,0 @@
Простая навигация по карте — Откройте больше за ваше путешествие. От сообщества

View File

@@ -1 +0,0 @@
CoMaps - Карты и путешествия с приватностью

View File

@@ -1,8 +0,0 @@
• освежене су боје мапе светлије, топлије, пријатније!
у OSM едитору је додато поље „спрат“
• ажуриране су иконице бензинских пумпи и станица за пуњење
• ажуриране су боје неких елемената корисничког интерфејса
• поправљени су линкови за дељење локације
• поправљена је погрешно приказана величина мапе након грешака при преузимању
• исправљена су мала поскакивања стрелице локације у неким случајевима
• исправљене су грешке за Android 5 и 6

View File

@@ -1 +1 @@
Једноставна навигација - Сазнајте више о свом путовању - Покреће је заједница
Једноставна навигација - Сазнајте више о свом путовању - Захваљујући заједници

View File

@@ -1,32 +1,2 @@
OpenStreetMap'in verilerine ve kar amacı gütmeyen olma taahhüdündeki topluluk liderliğine dayanan şeffaflık, gizlilik, ücretsiz ve açık kaynaklı haritalar uygulaması. Comaps, Organic Maps çatalı/düzenlemesidir, bu da bir Maps.ME çatalıdır.
Projenin sebepleri ve rotası hakkında <b><i>codeberg.org/comaps</i></b> adresinden bilgi edinebilirsiniz.
Oradaki topluluğa katılın ve en iyi harita uygulamasını yapmanıza yardımcı olun
• Uygulamayı kullanın ve bu bilgiyi yayın
• Geri bildirim verin ve sorunları bildirin
• Uygulamada veya OpenStreetMap internet sitesinde harita verilerini güncelleyin
‣ <b>Çevrimdışı odaklı</b>: Hücresel veriye ihtiyaç duymadan yurt dışında seyahatinizi planlayın ve gezin, uzak bir yürüyüş sırasında durak noktaları arama, vb. Tüm uygulama işlevleri çevrimdışı çalışacak şekilde tasarlanmıştır.
‣ <b>Gizliliğe saygı gösterir</b>: Uygulama gizlilik göz önünde bulundurularak tasarlanmıştır - insanları fişlemez, izlemez ve kişisel bilgileri toplamaz. Reklamsızdır.
‣ <b>Basit ve parlak</b>: Sadece işe yarayan kullanımı kolay özellikler.
‣ <b>Pilinizi ve hafızanızı kurtarın</b>: Pilinizi diğer gezinme uygulamaları gibi boşaltmaz. Sıkıştırılmış haritalar telefonunuzdaki değerli hafızadan tasarruf eder.
‣ <b>Özgür ve topluluk tarafından inşa edilmiştir</b>: Sizin gibi insanlar, OpenStreetMap'e yerler ekleyerek, özellikleri test edip hakkında geri bildirim vererek, geliştirme becerileri ve paralarıyla katkıda bulunarak uygulamanın oluşturulmasına yardımcı oldu.
‣ <b>Açık, şeffaf finans ve karar verme, kar amacı gütmeyen ve tamamen açık kaynaklı.</b>
<b>Ana Özellikler</b>:
• Google Haritalarda mevcut olmayan yerlerle, indirilebilir ve ayrıntılı haritalar
• Vurgulanmış yürüyüş parkurları, kamp alanları, su kaynakları, zirveler, yükseklik çizgileri, vb.
• Yürüyüş ve bisiklet yolları
• Lokantalar, benzin istasyonları, oteller, mağazalar, şahin tepeleri ve daha fazla ilgi çekici nokta
• Ada, adrese veya ilgi alanına göre arayın
• Yürüyüş, bisiklete binme veya sürüş için sesli bildirimlerle gezinme
• En sevdiğiniz yerlere tek bir dokunuşla yer işareti koyun
• Çevrimdışı Vikipedi makaleleri
• Metro katmanı ve tarifler
• Rota kaydı
• KML, KMZ, GPX biçimlerindeki yer imlerini ve izlerini dışa veya içe aktarın
• Gece boyunca kullanılacak karanlık kip
• Temel yerleşik bir arayüz kullanan herkes için harita verilerini geliştirin
<b>Özgürlük Burada</b>
Yolculuğunuzu keşfedin, dünyayı gizlilik ve topluluk desteğiyle gezin!
Gönüllüler tarafından yürütülen, OpenStreetMap harita verisini kullanan, şeffaf, mahremiyete saygılı, kamu yararına olma kararlılığıyla güçlendirilmiş bir özgür yazılım. CoMaps OrganicMaps isimli, esasen Maps.ME'nin çatalı olan bir özgür yazılımın çatalıdır.
Projenin ortaya çıkma sebebini ve gidişatını <b><i>codeberg.org/comaps</i></b>'den okuyabilirsiniz.

View File

@@ -1,8 +0,0 @@
• 刷新地图颜色-更浅、更暖、更友好!
• OSM 编辑器:添加“楼层”字段
• 更新加油站和充电站图标
• 更新部分用户界面组件的颜色
• 修复位置共享的链接
• 修复下载后错误显示地图大小的问题
• 修复定位箭头偶尔轻微跳动的问题
• Android 5&6 错误修复

View File

@@ -1,8 +0,0 @@
• 刷新地圖顏色-更淺、更暖、更友好!
• OSM 編輯器:新增「樓層」欄位
• 更新加油站和充電站圖示
• 更新某些使用者介面元件的顏色
• 修正位置分享的連結
• 修正下載後錯誤顯示地圖尺寸的問題
• 修正定位箭頭偶爾輕微跳動的問題
• Android 5&6 錯誤修正

View File

@@ -1 +1 @@
Jednoduchá navigace v mapě - Objevte více na své cestě Vyvíjeno komunitou
Jednoduchá navigace v mapě Objevte více na své cestě Vyvíjeno komunitou

View File

@@ -1 +1 @@
CoMaps - Navigace se soukromím
CoMaps Navigace se soukromím

View File

@@ -1 +1 @@
CoMaps - Navi mit Datenschutz
CoMaps: Navigation Datenschutz

View File

@@ -1,4 +1,4 @@
Una app sviluppata dalla comunità, gratuita e open-source, basata su OpenStreetMap e sull'impegno alla trasparenza, al rispetto della Privacy senza scopo di lucro.
Una app sviluppata dalla comunità, gratuita e open-source, basata su OpenStreetMap e sull'impegno alla trasparenza, al rispetto della Privacy senza scopo di lucro. CoMaps è uno spin-off di Organic Maps, che a sua volta deriva da Maps.ME.
Unisciti alla nostra comunità e aiutaci a creare la migliore app di mappe.
• usa l'app e consigliala

View File

@@ -1 +0,0 @@
Eenvoudige kaartnavigatie - Ontdek meer van je reis - Gemaakt door de community

View File

@@ -1 +0,0 @@
CoMaps - Navigeer met privacy

View File

@@ -1,38 +0,0 @@
Бесплатное и открытое приложение с картами, созданное сообществом на основе картографических данных OpenStreetMap и подкрепленное стремлением к прозрачности, уважению конфиденциальности и некоммерческой направленностью.
Подробнее о причинах проекта и его направлении читайте на <a href="https://codeberg.org/comaps">сайте</a>.
Присоединяйтесь к сообществу и помогите создать лучшее приложение с картами
• Используйте приложение и распространяйте информацию о нём
• Оставляйте отзывы и сообщайте о проблемах
• Обновляйте данные карт в приложении или на веб-сайте OpenStreetMap
<i>Ваши отзыв и звёздочки будут для нас лучшей поддержкой!</i>
‣ <b>Приоритет на работу без интернета</b>: Планируйте и ориентируйтесь в путешествии за границей, не нуждаясь в сотовой связи и т.д. Всё в приложении рассчитано на работу в автономном режиме.
‣ <b>Соблюдение конфиденциальности</b>: Приложение разработано с учётом требований конфиденциальности — оно не идентифицирует людей, не отслеживает и не собирает личную информацию. Без рекламы.
‣ <b>Простота и отточенность</b>: Основные и простые в использовании функции, которые просто работают.
‣ <b>Экономия заряда батареи и места на устройстве</b>: Не разряжает аккумулятор, как другие приложения для навигации. Компактные карты экономят драгоценное место на вашем телефоне.
‣ <b>Бесплатное и созданное сообществом</b>: Такие люди, как и вы, помогали создавать приложение, добавляя места в OpenStreetMap, протестировав и оставляя отзывы о функциях, а также вложив свои навыки и деньги в разработку.
‣ <b>Открытое и прозрачное принятие решений, финансовая отчётность, некоммерческая организация и полностью открытый исходный код.</b>
<b>Главные возможности</b>:
• Скачиваемые и подробные карты с местами, которые недоступны в Google Maps
• Уличный режим с отмеченными туристическими тропами, кемпингами, источниками воды, вершинами, контурными линиями и т.д.
• Пешеходные переходы и велодорожки
• Интересные места, такие как: рестораны, заправочные станции, гостиницы, магазины, достопримечательности и многое другое
• Поиск по названию или адресу или по категории достопримечательностей
• Навигация с голосовыми уведомлениями для пешеходов, велосипедистов или водителей
• Возможность добавлять любимые места в закладки одним нажатием
• Скачиваемые страницы Википедии
• Слой общественного транспорта (метро)
• Запись маршрута
• Экспорт и импорт закладок и маршрутов в форматах KML, KMZ, GPX
• Тёмный режим для использования в ночное время
• Улучшение данных карты для всех с помощью базового встроенного редактора
• Поддержка Андроид Авто
Пожалуйста сообщайте о ошибках, предлагайте идеи и присоединяйтесь к сообществу на сайте <a href="https://comaps.app">comaps.app</a>.
<b>Свобода!</b>
Откройте для себя путешествия, навигацию по миру, ставя во главе приватность и сообщество!

View File

@@ -1 +0,0 @@
Простая навигация по карте — Откройте больше за ваше путешествие. От сообщества

View File

@@ -1 +0,0 @@
CoMaps - Оффлайн навигация

View File

@@ -1,6 +1,6 @@
Бесплатна апликација за мапе отвореног кода коју води заједница заснована на OpenStreetMap подацима и ојачана посвећеношћу транспарентности, приватности и непрофитности.
Придружите се заједници и помозите да направимо најбољу навигацију
Придружите се заједници и помозите да направите најбољу навигацију
• Користите апликацију и ширите информације о њој
• Оставите повратне информације и пријавите проблеме
• Ажурирајте мапе из апликације или на сајту OpenStreetMap
@@ -32,5 +32,5 @@
Молимо Вас да пријавите проблеме са апликацијом, предложите идеје и придружите се нашој заједници на <b><i>comaps.app</i></b> страни.
<b>Сад је слободна</b>
<b>Сад је слободно</b>
Откријте своје путовање, путујте светом с приватношћу и заједницом на челу!

View File

@@ -1 +1 @@
Једноставна навигација - Сазнајте више о свом путовању - Покреће је заједница
Једноставна навигација - Сазнајте више о свом путовању - Захваљујући заједници

View File

@@ -1 +1 @@
CoMaps - Navigacija
CoMaps - навигација

View File

@@ -1,36 +0,0 @@
OpenStreetMap verilerine dayanan ve şeffaflık, gizlilik ve kar amacı gütmeyen olma taahhüdüyle güçlendirilen, topluluk tarafından yönetilen ücretsiz ve açık kaynaklı bir harita uygulaması.
Topluluğa katılın ve en iyi harita uygulamasını oluşturmaya yardımcı olun
• Uygulamayı kullanın ve bunu herkese duyurun
• Geri bildirimde bulunun ve sorunları bildirin
• Harita verilerini uygulamada veya OpenStreetMap web sitesinde güncelleyin
<i>Geri bildirimleriniz ve 5 yıldızlı yorumlarınız bizim için en iyi destektir!</i>
‣ <b>Basit ve Cilalı</b>: sadece işe yarayan, kullanımı kolay temel özellikler.
‣ <b>Çevrim dışı odaklı</b>: Cep telefonu hizmetine ihtiyaç duymadan yurtdışı seyahatinizi planlayın ve gezinin, uzun bir yürüyüş sırasında rota noktalarını arayın, vb. Tüm uygulama işlevleri çevrimdışı çalışmak üzere tasarlanmıştır.
‣ <b>Gizliliğe Saygı</b>: Uygulama gizlilik düşünülerek tasarlanmıştır; kişileri tanımlamaz, takip etmez ve kişisel bilgi toplamaz. Reklamsız.
‣ <b>Pilinizden ve Alanınızdan Tasarruf Edin</b>: Diğer navigasyon uygulamaları gibi pilinizi tüketmez. Kompakt haritalar telefonunuzda değerli alan tasarrufu sağlar.
‣ <b>Ücretsiz ve Topluluk Tarafından Oluşturuldu</b>: Sizin gibi insanlar, OpenStreetMap'e yerler ekleyerek, özellikleri test ederek ve geri bildirimde bulunarak ve geliştirme becerilerinizi ve paranızı katkıda bulunarak uygulamanın oluşturulmasına yardımcı oldunuz..
‣ <b>Açık ve Şeffaf Karar Alma ve Finansman, Kar Amacı Gütmeyen ve Tamamen Açık Kaynak.</b>
<b>Ana Özellikleri</b>:
• Google Haritalar'da bulunmayan yerleri içeren indirilebilir detaylı haritalar
• Vurgulanan yürüyüş parkurları, kamp alanları, su kaynakları, zirveler, kontur çizgileriyle açık hava modu gibi
• Yürüyüş yolları ve bisiklet yolları
• Restoranlar, benzin istasyonları, oteller, mağazalar, turistik yerler gibi ilgi çekici noktalar ve daha fazlası
• İsme veya adrese göre veya ilgi noktası kategorisine göre arama yapın
• Yürüyerek, bisikletle veya araçla seyahat edenler için sesli duyurularla navigasyon
• Favori yerlerinizi tek bir dokunuşla yer imlerine ekleyin
• Çevrim dışı Wikipedia makaleleri
• Metro geçiş katmanı ve yönleri
• Rota kaydı
• Yer imlerini ve parkurları KML, KMZ, GPX formatlarında dışa ve içe aktarın
• Geceleri kullanmak için karanlık mod
• Temel bir yerleşik düzenleyici kullanarak herkes için harita verilerini iyileştirin
• Android Auto desteği
Lütfen uygulama sorunlarını bildirin, fikir önerin ve <b><i>comaps.app</i></b> web sitesinde topluluğumuza katılın.
<b>Özgürlük Burada</b>
Yolculuğunuzu keşfedin, gizlilik ve topluluk ön planda tutularak dünyayı keşfedin!

View File

@@ -1 +1 @@
CoMaps - Gizlilikle Gezin
CoMaps - Mahremiyetli Seyahat

View File

@@ -44,7 +44,6 @@ import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.ViewModelProvider;
import app.organicmaps.api.Const;
import app.organicmaps.backup.PeriodicBackupRunner;
import app.organicmaps.base.BaseMwmFragmentActivity;
import app.organicmaps.base.OnBackPressListener;
import app.organicmaps.bookmarks.BookmarkCategoriesActivity;
@@ -140,7 +139,6 @@ import static app.organicmaps.leftbutton.LeftButtonsHolder.BUTTON_HELP_CODE;
import static app.organicmaps.leftbutton.LeftButtonsHolder.BUTTON_RECORD_TRACK_CODE;
import static app.organicmaps.leftbutton.LeftButtonsHolder.BUTTON_SETTINGS_CODE;
import static app.organicmaps.util.PowerManagment.POWER_MANAGEMENT_TAG;
import static app.organicmaps.util.concurrency.UiThread.runLater;
public class MwmActivity extends BaseMwmFragmentActivity
implements PlacePageActivationListener,
@@ -255,8 +253,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
@NonNull
private DisplayManager mDisplayManager;
private PeriodicBackupRunner backupRunner;
ManageRouteBottomSheet mManageRouteBottomSheet;
private boolean mRemoveDisplayListener = true;
@@ -611,8 +607,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
*/
if (Map.isEngineCreated())
onRenderingInitializationFinished();
backupRunner = new PeriodicBackupRunner(this);
}
private void onSettingsResult(ActivityResult activityResult)
@@ -844,7 +838,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
@Override
public String getPrefsName()
{
return getString(R.string.about_help);
return getString(R.string.help);
}
@Override
@@ -1358,11 +1352,6 @@ public class MwmActivity extends BaseMwmFragmentActivity
final String backUrl = Framework.nativeGetParsedBackUrl();
if (!TextUtils.isEmpty(backUrl))
Utils.openUri(this, Uri.parse(backUrl), null);
if (backupRunner != null && !backupRunner.isAlreadyChecked() && backupRunner.isTimeToBackup())
{
backupRunner.doBackup();
}
}
@CallSuper
@@ -2595,28 +2584,20 @@ public class MwmActivity extends BaseMwmFragmentActivity
{
if (id.equals(MAIN_MENU_ID))
{
final String activeLeftButton = buttonsHolder.getActiveButtonCode();
ArrayList<MenuBottomSheetItem> items = new ArrayList<>();
if (!BUTTON_ADD_PLACE_CODE.equals(activeLeftButton))
items.add(new MenuBottomSheetItem(R.string.placepage_add_place_button, R.drawable.ic_plus, this::onAddPlaceOptionSelected));
items.add(new MenuBottomSheetItem(R.string.download_maps, R.drawable.ic_download, getDownloadMapsCounter(), this::onDownloadMapsOptionSelected));
if (!Config.getDonateUrl(getApplicationContext()).isEmpty())
items.add(new MenuBottomSheetItem(R.string.placepage_add_place_button, R.drawable.ic_plus, this::onAddPlaceOptionSelected));
items.add(new MenuBottomSheetItem(
R.string.download_maps,
R.drawable.ic_download,
getDownloadMapsCounter(),
this::onDownloadMapsOptionSelected
));
mDonatesUrl = Config.getDonateUrl(getApplicationContext());
if (!TextUtils.isEmpty(mDonatesUrl))
items.add(new MenuBottomSheetItem(R.string.donate, R.drawable.ic_donate, this::onDonateOptionSelected));
if (!BUTTON_SETTINGS_CODE.equals(activeLeftButton))
items.add(new MenuBottomSheetItem(R.string.settings, R.drawable.ic_settings, this::onSettingsOptionSelected));
if (!BUTTON_RECORD_TRACK_CODE.equals(activeLeftButton))
items.add(new MenuBottomSheetItem(R.string.start_track_recording, R.drawable.ic_track_recording_off, -1, this::onTrackRecordingOptionSelected));
items.add(new MenuBottomSheetItem(R.string.settings, R.drawable.ic_settings, this::onSettingsOptionSelected));
items.add(new MenuBottomSheetItem(R.string.start_track_recording, R.drawable.ic_track_recording_off, -1, this::onTrackRecordingOptionSelected));
items.add(new MenuBottomSheetItem(R.string.share_my_location, R.drawable.ic_share, this::onShareLocationOptionSelected));
if (!BUTTON_HELP_CODE.equals(activeLeftButton))
items.add(new MenuBottomSheetItem(R.string.about_help, R.drawable.ic_question_mark, this::showHelp));
return items;
}
return null;

View File

@@ -1,114 +0,0 @@
package app.organicmaps.backup;
import static app.organicmaps.settings.BackupSettingsFragment.MAX_BACKUPS_DEFAULT_COUNT;
import static app.organicmaps.settings.BackupSettingsFragment.MAX_BACKUPS_KEY;
import static app.organicmaps.util.StorageUtils.isFolderWritable;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.AbsoluteSizeSpan;
import androidx.annotation.NonNull;
import androidx.documentfile.provider.DocumentFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import app.organicmaps.R;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.log.Logger;
public class BackupUtils
{
private static final String BACKUP_PREFIX = "backup_";
private static final String BACKUP_EXTENSION = ".kmz";
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss").withLocale(Locale.US);
private static final String TAG = BackupUtils.class.getSimpleName();
public static CharSequence formatReadableFolderPath(Context context, @NonNull Uri uri)
{
String docId = DocumentsContract.getTreeDocumentId(uri);
String volumeId;
String subPath = "";
int colonIndex = docId.indexOf(':');
if (colonIndex >= 0)
{
volumeId = docId.substring(0, colonIndex);
subPath = docId.substring(colonIndex + 1);
}
else
{
volumeId = docId;
}
String volumeName;
if ("primary".equalsIgnoreCase(volumeId))
volumeName = context.getString(R.string.maps_storage_shared);
else
volumeName = context.getString(R.string.maps_storage_removable);
SpannableStringBuilder sb = new SpannableStringBuilder();
sb.append(volumeName + ": \n", new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_body_3)), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sb.append("/" + subPath, new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_body_4)), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
}
public static int getMaxBackups(SharedPreferences prefs)
{
String rawValue = prefs.getString(MAX_BACKUPS_KEY, String.valueOf(MAX_BACKUPS_DEFAULT_COUNT));
try
{
return Integer.parseInt(rawValue);
} catch (NumberFormatException e)
{
Logger.e(TAG, "Failed to parse max backups count, raw value: " + rawValue + " set to default: " + MAX_BACKUPS_DEFAULT_COUNT, e);
prefs.edit()
.putString(MAX_BACKUPS_KEY, String.valueOf(MAX_BACKUPS_DEFAULT_COUNT))
.apply();
return MAX_BACKUPS_DEFAULT_COUNT;
}
}
public static DocumentFile createUniqueBackupFolder(@NonNull DocumentFile parentDir, LocalDateTime backupTime)
{
String folderName = BACKUP_PREFIX + backupTime.format(DATE_FORMATTER);
return parentDir.createDirectory(folderName);
}
public static String getBackupName(LocalDateTime backupTime)
{
String formattedBackupTime = backupTime.format(DATE_FORMATTER);
return BACKUP_PREFIX + formattedBackupTime + BACKUP_EXTENSION;
}
public static DocumentFile[] getBackupFolders(DocumentFile parentDir)
{
List<DocumentFile> backupFolders = new ArrayList<>();
for (DocumentFile file : parentDir.listFiles())
{
if (file.isDirectory() && file.getName() != null && file.getName().startsWith(BACKUP_PREFIX))
backupFolders.add(file);
}
return backupFolders.toArray(new DocumentFile[0]);
}
public static boolean isBackupFolderAvailable(Context context, String storedFolderPath)
{
return !TextUtils.isEmpty(storedFolderPath) && isFolderWritable(context, storedFolderPath);
}
}

View File

@@ -1,189 +0,0 @@
package app.organicmaps.backup;
import static app.organicmaps.backup.BackupUtils.getBackupName;
import static app.organicmaps.backup.BackupUtils.getBackupFolders;
import static app.organicmaps.util.StorageUtils.copyFileToDocumentFile;
import static app.organicmaps.util.StorageUtils.deleteDirectoryRecursive;
import android.app.Activity;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.documentfile.provider.DocumentFile;
import java.io.File;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import app.organicmaps.bookmarks.data.BookmarkCategory;
import app.organicmaps.bookmarks.data.BookmarkManager;
import app.organicmaps.bookmarks.data.BookmarkSharingResult;
import app.organicmaps.bookmarks.data.KmlFileType;
import app.organicmaps.util.concurrency.ThreadPool;
import app.organicmaps.util.concurrency.UiThread;
import app.organicmaps.util.log.Logger;
public class LocalBackupManager implements BookmarkManager.BookmarksSharingListener
{
public static final String TAG = LocalBackupManager.class.getSimpleName();
private final Activity activity;
private final String backupFolderPath;
private final int maxBackups;
private Listener listener;
public LocalBackupManager(@NonNull Activity activity, @NonNull String backupFolderPath, int maxBackups)
{
this.activity = activity;
this.backupFolderPath = backupFolderPath;
this.maxBackups = maxBackups;
}
public void doBackup()
{
BookmarkManager.INSTANCE.addSharingListener(this);
prepareBookmarkCategoriesForSharing();
if (listener != null)
listener.onBackupStarted();
}
public void setListener(@NonNull Listener listener)
{
this.listener = listener;
}
@Override
public void onPreparedFileForSharing(@NonNull BookmarkSharingResult result)
{
BookmarkManager.INSTANCE.removeSharingListener(this);
ThreadPool.getWorker().execute(() -> {
ErrorCode errorCode = null;
switch (result.getCode())
{
case BookmarkSharingResult.SUCCESS ->
{
if (!saveBackup(result))
{
Logger.e(TAG, "Failed to save backup. See system log above");
errorCode = ErrorCode.FILE_ERROR;
}
else
{
Logger.i(TAG, "Backup was created and saved successfully");
}
}
case BookmarkSharingResult.EMPTY_CATEGORY ->
{
errorCode = ErrorCode.EMPTY_CATEGORY;
Logger.e(TAG, "Failed to create backup. Category is empty");
}
case BookmarkSharingResult.ARCHIVE_ERROR ->
{
errorCode = ErrorCode.ARCHIVE_ERROR;
Logger.e(TAG, "Failed to create archive of bookmarks");
}
case BookmarkSharingResult.FILE_ERROR ->
{
errorCode = ErrorCode.FILE_ERROR;
Logger.e(TAG, "Failed create file for archive");
}
default ->
{
errorCode = ErrorCode.UNSUPPORTED;
Logger.e(TAG, "Failed to create backup. Unknown error");
}
}
ErrorCode finalErrorCode = errorCode;
UiThread.run(() -> {
if (listener != null)
{
if (finalErrorCode == null)
listener.onBackupFinished();
else
listener.onBackupFailed(finalErrorCode);
}
});
});
}
private boolean saveBackup(@NonNull BookmarkSharingResult result)
{
boolean isSuccess = false;
Uri folderUri = Uri.parse(backupFolderPath);
try
{
DocumentFile parentFolder = DocumentFile.fromTreeUri(activity, folderUri);
if (parentFolder != null && parentFolder.canWrite())
{
LocalDateTime now = LocalDateTime.now();
DocumentFile backupFolder = BackupUtils.createUniqueBackupFolder(parentFolder, now);
if (backupFolder != null)
{
String backupName = getBackupName(now);
DocumentFile backupFile = backupFolder.createFile(result.getMimeType(), backupName);
if (backupFile != null && copyFileToDocumentFile(activity, new File(result.getSharingPath()), backupFile))
{
Logger.i(TAG, "Backup saved to " + backupFile.getUri());
isSuccess = true;
}
}
else
{
Logger.e(TAG, "Failed to create backup folder");
}
}
cleanOldBackups(parentFolder);
} catch (Exception e)
{
Logger.e(TAG, "Failed to save backup", e);
}
return isSuccess;
}
public void cleanOldBackups(DocumentFile parentDir)
{
DocumentFile[] backupFolders = getBackupFolders(parentDir);
if (backupFolders.length > maxBackups)
{
Arrays.sort(backupFolders, Comparator.comparing(DocumentFile::getName));
for (int i = 0; i < backupFolders.length - maxBackups; i++)
{
Logger.i(TAG, "Delete old backup " + backupFolders[i].getUri());
deleteDirectoryRecursive(backupFolders[i]);
}
}
}
private void prepareBookmarkCategoriesForSharing()
{
List<BookmarkCategory> categories = BookmarkManager.INSTANCE.getCategories();
long[] categoryIds = new long[categories.size()];
for (int i = 0; i < categories.size(); i++)
categoryIds[i] = categories.get(i).getId();
BookmarkManager.INSTANCE.prepareCategoriesForSharing(categoryIds, KmlFileType.Text);
}
public interface Listener
{
void onBackupStarted();
void onBackupFinished();
void onBackupFailed(ErrorCode errorCode);
}
public enum ErrorCode
{
EMPTY_CATEGORY,
ARCHIVE_ERROR,
FILE_ERROR,
UNSUPPORTED,
}
}

View File

@@ -1,104 +0,0 @@
package app.organicmaps.backup;
import static app.organicmaps.backup.BackupUtils.getMaxBackups;
import static app.organicmaps.backup.BackupUtils.isBackupFolderAvailable;
import static app.organicmaps.settings.BackupSettingsFragment.BACKUP_FOLDER_PATH_KEY;
import static app.organicmaps.settings.BackupSettingsFragment.BACKUP_INTERVAL_KEY;
import static app.organicmaps.settings.BackupSettingsFragment.LAST_BACKUP_TIME_KEY;
import static app.organicmaps.util.StorageUtils.isFolderWritable;
import android.app.Activity;
import android.content.SharedPreferences;
import androidx.preference.PreferenceManager;
import app.organicmaps.util.log.Logger;
public class PeriodicBackupRunner
{
private final Activity activity;
private static final String TAG = PeriodicBackupRunner.class.getSimpleName();
private final SharedPreferences prefs;
private boolean alreadyChecked = false;
public PeriodicBackupRunner(Activity activity)
{
this.activity = activity;
this.prefs = PreferenceManager.getDefaultSharedPreferences(activity);
}
public boolean isAlreadyChecked()
{
return alreadyChecked;
}
public boolean isTimeToBackup()
{
long intervalMs = getBackupIntervalMs();
if (intervalMs <= 0)
return false;
long lastBackupTime = prefs.getLong(LAST_BACKUP_TIME_KEY, 0);
long now = System.currentTimeMillis();
alreadyChecked = true;
return (now - lastBackupTime) >= intervalMs;
}
public void doBackup()
{
String storedFolderPath = prefs.getString(BACKUP_FOLDER_PATH_KEY, null);
if (isBackupFolderAvailable(activity, storedFolderPath))
{
Logger.i(TAG, "Performing periodic backup");
performBackup(storedFolderPath, getMaxBackups(prefs));
}
else
{
Logger.w(TAG, "Backup folder is not writable, passed path: " + storedFolderPath);
}
}
private long getBackupIntervalMs()
{
String defaultValue = "0";
try
{
return Long.parseLong(prefs.getString(BACKUP_INTERVAL_KEY, defaultValue));
} catch (NumberFormatException e)
{
return 0;
}
}
private void performBackup(String backupFolderPath, int maxBackups)
{
LocalBackupManager backupManager = new LocalBackupManager(activity, backupFolderPath, maxBackups);
backupManager.setListener(new LocalBackupManager.Listener()
{
@Override
public void onBackupStarted()
{
Logger.i(TAG, "Periodic backup started");
}
@Override
public void onBackupFinished()
{
prefs.edit().putLong(LAST_BACKUP_TIME_KEY, System.currentTimeMillis()).apply();
Logger.i(TAG, "Periodic backup finished");
}
@Override
public void onBackupFailed(LocalBackupManager.ErrorCode errorCode)
{
Logger.e(TAG, "Periodic backup was failed with code: " + errorCode);
}
});
backupManager.doBackup();
}
}

View File

@@ -1,6 +1,7 @@
package app.organicmaps.bookmarks;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Context;
@@ -20,9 +21,6 @@ import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.adapter.OnItemClickListener;
@@ -281,7 +279,7 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment<Bookmark
}
private void showNoFileManagerError() {
new MaterialAlertDialogBuilder(requireActivity())
new AlertDialog.Builder(requireActivity())
.setMessage(R.string.error_no_file_manager_app)
.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss())
.show();

View File

@@ -69,8 +69,7 @@ public class Metadata implements Parcelable
FMD_OUTDOOR_SEATING(48),
FMD_NETWORK(49),
FMD_CONTACT_FEDIVERSE(50),
FMD_CONTACT_BLUESKY(51),
FMD_PANORAMAX(52);
FMD_CONTACT_BLUESKY(51);
private final int mMetaType;
MetadataType(int metadataType)

View File

@@ -41,7 +41,7 @@ public class HelpScreen extends BaseMapScreen
{
final Header.Builder builder = new Header.Builder();
builder.setStartHeaderAction(Action.BACK);
builder.setTitle(getCarContext().getString(R.string.about_help));
builder.setTitle(getCarContext().getString(R.string.help));
return builder.build();
}

View File

@@ -109,7 +109,7 @@ public class SettingsScreen extends BaseMapScreen
private Item createHelpItem()
{
final Row.Builder builder = new Row.Builder();
builder.setTitle(getCarContext().getString(R.string.about_help));
builder.setTitle(getCarContext().getString(R.string.help));
builder.setOnClickListener(() -> getScreenManager().push(new HelpScreen(getCarContext(), getSurfaceRenderer())));
builder.setBrowsable(true);
return builder.build();

View File

@@ -11,6 +11,7 @@ import android.text.style.StyleSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
@@ -27,7 +28,6 @@ import app.organicmaps.util.UiUtils;
import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment;
import app.organicmaps.util.bottomsheet.MenuBottomSheetItem;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textview.MaterialTextView;
import java.util.ArrayList;
import java.util.Collection;
@@ -362,10 +362,10 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
private class ItemViewHolder extends BaseInnerViewHolder<CountryItem>
{
private final DownloaderStatusIcon mStatusIcon;
private final MaterialTextView mName;
private final MaterialTextView mSubtitle;
private final MaterialTextView mFoundName;
private final MaterialTextView mSize;
private final TextView mName;
private final TextView mSubtitle;
private final TextView mFoundName;
private final TextView mSize;
private void processClick(boolean clickOnStatus)
{
@@ -510,7 +510,7 @@ class DownloaderAdapter extends RecyclerView.Adapter<DownloaderAdapter.ViewHolde
static class HeaderViewHolder extends BaseInnerViewHolder<String>
{
@NonNull
private final MaterialTextView mTitle;
private final TextView mTitle;
HeaderViewHolder(@NonNull View frame)
{

View File

@@ -3,14 +3,13 @@ package app.organicmaps.downloader;
import static android.Manifest.permission.POST_NOTIFICATIONS;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import android.app.ForegroundServiceStartNotAllowedException;
import android.app.Service;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.os.Build;
import android.os.IBinder;
import androidx.annotation.Nullable;
import androidx.core.app.ServiceCompat;
import androidx.core.content.ContextCompat;
import java.util.List;
@@ -41,11 +40,19 @@ public class DownloaderService extends Service implements MapManager.StorageCall
Logger.i(TAG, "Downloading: " + MapManager.nativeIsDownloading());
var notification = mNotifier.buildProgressNotification();
Logger.i(TAG, "Starting Downloader Foreground Service");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
ServiceCompat.startForeground(this, DownloaderNotifier.NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC);
else
ServiceCompat.startForeground(this, DownloaderNotifier.NOTIFICATION_ID, notification, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
{
try
{
startForeground(DownloaderNotifier.NOTIFICATION_ID, notification);
} catch (ForegroundServiceStartNotAllowedException e)
{
Logger.e(TAG, "Oops! ForegroundService is not allowed", e);
}
} else
{
startForeground(DownloaderNotifier.NOTIFICATION_ID, notification);
}
return START_NOT_STICKY;
}

View File

@@ -2,12 +2,11 @@ package app.organicmaps.downloader;
import android.util.SparseIntArray;
import android.view.View;
import android.widget.ImageView;
import androidx.annotation.AttrRes;
import androidx.annotation.DrawableRes;
import com.google.android.material.imageview.ShapeableImageView;
import app.organicmaps.R;
import app.organicmaps.widget.WheelProgressView;
import app.organicmaps.util.ThemeUtils;
@@ -16,7 +15,7 @@ import app.organicmaps.util.UiUtils;
public class DownloaderStatusIcon
{
private final View mFrame;
protected final ShapeableImageView mIcon;
protected final ImageView mIcon;
private final WheelProgressView mProgress;
private static final SparseIntArray sIconsCache = new SparseIntArray();

View File

@@ -43,7 +43,7 @@ public class CopyrightFragment extends BaseMwmFragment
{
if (!mDelegate.onBackPressed())
{
((HelpActivity) requireActivity()).stackFragment(HelpFragment.class, getString(R.string.about_help), null);
((HelpActivity) requireActivity()).stackFragment(HelpFragment.class, getString(R.string.help), null);
}
return true;

View File

@@ -43,21 +43,15 @@ public class LeftButtonsHolder
}
@Nullable
public String getActiveButtonCode()
public LeftButton getActiveButton()
{
String activeButtonCode = prefs.getString(leftButtonPreferenceKey, DEFAULT_BUTTON_CODE);
if (!TextUtils.isEmpty(activeButtonCode))
return activeButtonCode;
return availableButtons.get(activeButtonCode);
else
return null;
}
@Nullable
public LeftButton getActiveButton()
{
return availableButtons.get(getActiveButtonCode());
}
public Collection<LeftButton> getAllButtons()
{
return availableButtons.values();

View File

@@ -1,11 +1,11 @@
package app.organicmaps.location;
import android.app.ForegroundServiceStartNotAllowedException;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.location.Location;
import android.os.Build;
import android.os.IBinder;
@@ -17,7 +17,6 @@ import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationChannelCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.app.ServiceCompat;
import androidx.core.content.ContextCompat;
import app.organicmaps.MwmActivity;
import app.organicmaps.MwmApplication;
@@ -159,11 +158,21 @@ public class TrackRecordingService extends Service implements LocationListener
return START_NOT_STICKY;
}
Logger.i(TAG, "Starting Track Recording Foreground service");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
ServiceCompat.startForeground(this, TrackRecordingService.TRACK_REC_NOTIFICATION_ID, getNotificationBuilder(this).build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION);
Logger.i(TAG, "Starting foreground service");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
{
try
{
startForeground(TrackRecordingService.TRACK_REC_NOTIFICATION_ID, getNotificationBuilder(this).build());
} catch (ForegroundServiceStartNotAllowedException e)
{
Logger.e(TAG, "Oops! ForegroundService is not allowed", e);
}
}
else
ServiceCompat.startForeground(this, TrackRecordingService.TRACK_REC_NOTIFICATION_ID, getNotificationBuilder(this).build(), 0);
{
startForeground(TrackRecordingService.TRACK_REC_NOTIFICATION_ID, getNotificationBuilder(this).build());
}
final LocationHelper locationHelper = LocationHelper.from(this);

View File

@@ -52,7 +52,7 @@ public class LayerBottomSheetItem
case SUBWAY:
disabledResource = R.attr.subwayMenuDisabled;
enabledResource = R.attr.subwayMenuEnabled;
buttonTextResource = R.string.subway;
buttonTextResource = R.string.button_layer_subway;
break;
case ISOLINES:
disabledResource = R.attr.isoLinesMenuDisabled;

View File

@@ -43,7 +43,6 @@ public class LayersAdapter extends RecyclerView.Adapter<LayerHolder>
boolean isEnabled = item.getMode().isEnabled(context);
holder.mButton.setSelected(isEnabled);
holder.mButton.setContentDescription(context.getString(item.getTitle()));
holder.mTitle.setSelected(isEnabled);
holder.mTitle.setText(item.getTitle());
boolean isNewLayer = SharedPropertiesUtils.shouldShowNewMarkerForLayerMode(context,

View File

@@ -213,13 +213,11 @@ public class MapButtonsController extends Fragment
)
{
leftButtonView.setImageResource(R.drawable.ic_christmas_tree);
leftButtonView.setContentDescription(getString(R.string.about_help));
leftButtonView.setOnClickListener((v) -> mMapButtonClickListener.onMapButtonClick(MapButtons.help));
}
else
{
mLeftButton.drawIcon(leftButtonView);
leftButtonView.setContentDescription(mLeftButton.getPrefsName());
leftButtonView.setOnClickListener((v) -> mLeftButton.onClick(leftButtonView));
}
// else
@@ -484,10 +482,7 @@ public class MapButtonsController extends Fragment
.build();
ViewCompat.setOnApplyWindowInsetsListener(mFrame, insetsListener);
// Fixes insets on older Androids and with a search opened via API on all Androids.
if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.Q)
mFrame.postDelayed(() -> ViewCompat.requestApplyInsets(mFrame), 1250);
else
mFrame.post(() -> ViewCompat.requestApplyInsets(mFrame));
mFrame.post(() -> ViewCompat.requestApplyInsets(mFrame));
}
@Override

View File

@@ -266,8 +266,7 @@ public class NavigationController implements TrafficManager.TrafficCallback,
mSpeedLimit.setSpeedLimit(0, false);
return;
}
final int fSpeedLimit = StringUtils.nativeFormatSpeed(info.speedLimitMps);
final boolean speedLimitExceeded = fSpeedLimit < StringUtils.nativeFormatSpeed(location.getSpeed());
mSpeedLimit.setSpeedLimit(fSpeedLimit, speedLimitExceeded);
final boolean speedLimitExceeded = info.speedLimitMps < location.getSpeed();
mSpeedLimit.setSpeedLimit(StringUtils.nativeFormatSpeed(info.speedLimitMps), speedLimitExceeded);
}
}

View File

@@ -7,12 +7,12 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static app.organicmaps.util.Constants.Vendor.XIAOMI;
import android.annotation.SuppressLint;
import android.app.ForegroundServiceStartNotAllowedException;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.location.Location;
@@ -27,7 +27,6 @@ import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationChannelCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.app.ServiceCompat;
import androidx.core.content.ContextCompat;
import app.organicmaps.Framework;
@@ -225,11 +224,21 @@ public class NavigationService extends Service implements LocationListener
return START_NOT_STICKY; // The service will be stopped by stopSelf().
}
Logger.i(TAG, "Starting Navigation Foreground service");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
ServiceCompat.startForeground(this, NavigationService.NOTIFICATION_ID, getNotificationBuilder(this).build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION);
Logger.i(TAG, "Starting foreground");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
{
try
{
startForeground(NavigationService.NOTIFICATION_ID, getNotificationBuilder(this).build());
} catch (ForegroundServiceStartNotAllowedException e)
{
Logger.e(TAG, "Oops! ForegroundService is not allowed", e);
}
}
else
ServiceCompat.startForeground(this, NavigationService.NOTIFICATION_ID, getNotificationBuilder(this).build(), 0);
{
startForeground(NavigationService.NOTIFICATION_ID, getNotificationBuilder(this).build());
}
final LocationHelper locationHelper = LocationHelper.from(this);

View File

@@ -28,9 +28,6 @@ import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.Framework;
import app.organicmaps.R;
import app.organicmaps.bookmarks.data.DistanceAndAzimut;
@@ -70,21 +67,21 @@ final class RoutingBottomMenuController implements View.OnClickListener
@NonNull
private final ImageView mAltitudeChart;
@NonNull
private final MaterialTextView mTime;
private final TextView mTime;
@NonNull
private final MaterialTextView mAltitudeDifference;
private final TextView mAltitudeDifference;
@NonNull
private final TextView mTimeVehicle;
@Nullable
private final MaterialTextView mArrival;
private final TextView mArrival;
@NonNull
private final View mActionFrame;
@NonNull
private final MaterialTextView mActionMessage;
private final TextView mActionMessage;
@NonNull
private final View mActionButton;
@NonNull
private final ShapeableImageView mActionIcon;
private final ImageView mActionIcon;
@NonNull
private final DotDividerItemDecoration mTransitViewDecorator;
@@ -101,10 +98,10 @@ final class RoutingBottomMenuController implements View.OnClickListener
TextView error = (TextView) getViewById(activity, frame, R.id.error);
Button start = (Button) getViewById(activity, frame, R.id.start);
ImageView altitudeChart = (ImageView) getViewById(activity, frame, R.id.altitude_chart);
MaterialTextView time = (MaterialTextView) getViewById(activity, frame, R.id.time);
TextView time = (TextView) getViewById(activity, frame, R.id.time);
TextView timeVehicle = (TextView) getViewById(activity, frame, R.id.time_vehicle);
MaterialTextView altitudeDifference = (MaterialTextView) getViewById(activity, frame, R.id.altitude_difference);
MaterialTextView arrival = (MaterialTextView) getViewById(activity, frame, R.id.arrival);
TextView altitudeDifference = (TextView) getViewById(activity, frame, R.id.altitude_difference);
TextView arrival = (TextView) getViewById(activity, frame, R.id.arrival);
View actionFrame = getViewById(activity, frame, R.id.routing_action_frame);
return new RoutingBottomMenuController(activity, altitudeChartFrame, timeElevationLine, transitFrame,
@@ -127,10 +124,10 @@ final class RoutingBottomMenuController implements View.OnClickListener
@NonNull TextView error,
@NonNull Button start,
@NonNull ImageView altitudeChart,
@NonNull MaterialTextView time,
@NonNull MaterialTextView altitudeDifference,
@NonNull TextView time,
@NonNull TextView altitudeDifference,
@NonNull TextView timeVehicle,
@Nullable MaterialTextView arrival,
@Nullable TextView arrival,
@NonNull View actionFrame,
@Nullable RoutingBottomMenuListener listener)
{
@@ -201,12 +198,12 @@ final class RoutingBottomMenuController implements View.OnClickListener
scrollToBottom(rv);
MaterialTextView totalTimeView = mTransitFrame.findViewById(R.id.total_time);
TextView totalTimeView = mTransitFrame.findViewById(R.id.total_time);
totalTimeView.setText(RoutingController.formatRoutingTime(mContext, info.getTotalTime(),
R.dimen.text_size_routing_number));
View dotView = mTransitFrame.findViewById(R.id.dot);
View pedestrianIcon = mTransitFrame.findViewById(R.id.pedestrian_icon);
MaterialTextView distanceView = mTransitFrame.findViewById(R.id.total_distance);
TextView distanceView = mTransitFrame.findViewById(R.id.total_distance);
UiUtils.showIf(info.getTotalPedestrianTimeInSec() > 0, dotView, pedestrianIcon, distanceView);
distanceView.setText(info.getTotalPedestrianDistance() + " " + info.getTotalPedestrianDistanceUnits());
}

View File

@@ -38,17 +38,15 @@ public class RoutingErrorDialogFragment extends BaseRoutingErrorDialogFragment
ResultCodesHelper.getDialogTitleSubtitle(requireContext(), mResultCode, mMissingMaps.size());
Pair<String, String> titleMessage = resHolder.getTitleMessage();
if (!TextUtils.isEmpty(titleMessage.first))
{
TextView titleView = new TextView(requireContext());
titleView.setText(titleMessage.first);
titleView.setPadding(65, 32, 32, 16);
titleView.setTextSize(18);
titleView.setMaxLines(4);
titleView.setEllipsize(TextUtils.TruncateAt.END);
titleView.setTypeface(null, Typeface.BOLD);
builder.setCustomTitle(titleView);
}
TextView titleView = new TextView(requireContext());
titleView.setText(titleMessage.first);
titleView.setPadding(65, 32, 32, 16);
titleView.setTextSize(18);
titleView.setMaxLines(4);
titleView.setEllipsize(TextUtils.TruncateAt.END);
titleView.setTypeface(null, Typeface.BOLD);
builder.setCustomTitle(titleView);
mMessage = titleMessage.second;
builder.setNegativeButton(resHolder.getCancelBtnResId(), null);
if (ResultCodesHelper.isDownloadable(mResultCode, mMissingMaps.size()))

View File

@@ -1,384 +0,0 @@
package app.organicmaps.settings;
import static app.organicmaps.backup.BackupUtils.formatReadableFolderPath;
import static app.organicmaps.backup.BackupUtils.getMaxBackups;
import static app.organicmaps.backup.BackupUtils.isBackupFolderAvailable;
import static app.organicmaps.util.StorageUtils.isFolderWritable;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.text.DateFormat;
import app.organicmaps.R;
import app.organicmaps.backup.LocalBackupManager;
import app.organicmaps.util.log.Logger;
public class BackupSettingsFragment
extends BaseXmlSettingsFragment
{
private ActivityResultLauncher<Intent> folderPickerLauncher;
private static final String TAG = LocalBackupManager.class.getSimpleName();
public static final String BACKUP_FOLDER_PATH_KEY = "backup_location";
public static final String LAST_BACKUP_TIME_KEY = "last_backup_time";
private static final String BACKUP_NOW_KEY = "backup_now";
public static final String BACKUP_INTERVAL_KEY = "backup_history_interval";
public static final String MAX_BACKUPS_KEY = "backup_history_count";
public static final int MAX_BACKUPS_DEFAULT_COUNT = 10;
public static final String DEFAULT_BACKUP_INTERVAL = "86400000"; // 24 hours in ms
private LocalBackupManager mBackupManager;
private SharedPreferences prefs;
@Override
protected int getXmlResources()
{
return R.xml.prefs_backup;
}
@NonNull
@SuppressWarnings("NotNullFieldNotInitialized")
Preference backupLocationOption;
@NonNull
@SuppressWarnings("NotNullFieldNotInitialized")
ListPreference backupIntervalOption;
@NonNull
@SuppressWarnings("NotNullFieldNotInitialized")
Preference maxBackupsOption;
@NonNull
@SuppressWarnings("NotNullFieldNotInitialized")
Preference backupNowOption;
@NonNull
@SuppressWarnings("NotNullFieldNotInitialized")
Preference advancedCategory;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
folderPickerLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
boolean isSuccess = false;
String lastFolderPath = prefs.getString(BACKUP_FOLDER_PATH_KEY, null);
if (result.getResultCode() == Activity.RESULT_OK)
{
Intent data = result.getData();
Logger.i(TAG, "Folder selection result: " + data);
if (data == null)
return;
Uri uri = data.getData();
if (uri != null)
{
takePersistableUriPermission(uri);
Logger.i(TAG, "Backup location changed to " + uri);
prefs.edit().putString(BACKUP_FOLDER_PATH_KEY, uri.toString()).apply();
setFormattedBackupPath(uri);
runBackup();
isSuccess = true;
}
else
{
Logger.w(TAG, "Folder selection result is null");
}
}
else if (result.getResultCode() == Activity.RESULT_CANCELED)
{
Logger.w(TAG, "User canceled folder selection");
if (TextUtils.isEmpty(lastFolderPath))
{
prefs.edit().putString(BACKUP_FOLDER_PATH_KEY, null).apply();
Logger.i(TAG, "Backup settings reset");
initBackupLocationOption();
}
else if (isFolderWritable(requireActivity(), lastFolderPath))
{
Logger.i(TAG, "Backup location not changed, using previous value " + lastFolderPath);
isSuccess = true;
}
else
{
Logger.e(TAG, "Backup location not changed, but last folder is not writable: " + lastFolderPath);
}
}
resetLastBackupTime();
updateStatusSummaryOption();
Logger.i(TAG, "Folder selection result: " + isSuccess);
applyAdvancedSettings(isSuccess);
}
);
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey)
{
super.onCreatePreferences(savedInstanceState, rootKey);
prefs = PreferenceManager.getDefaultSharedPreferences(requireContext());
backupLocationOption = findPreference(BACKUP_FOLDER_PATH_KEY);
backupIntervalOption = findPreference(BACKUP_INTERVAL_KEY);
maxBackupsOption = findPreference(MAX_BACKUPS_KEY);
backupNowOption = findPreference(BACKUP_NOW_KEY);
initBackupLocationOption();
initBackupIntervalOption();
initMaxBackupsOption();
initBackupNowOption();
}
private void initBackupLocationOption()
{
String storedFolderPath = prefs.getString(BACKUP_FOLDER_PATH_KEY, null);
boolean isEnabled = false;
if (!TextUtils.isEmpty(storedFolderPath))
{
if (isFolderWritable(requireContext(), storedFolderPath))
{
setFormattedBackupPath(Uri.parse(storedFolderPath));
isEnabled = true;
}
else
{
Logger.e(TAG, "Backup location is not available, path: " + storedFolderPath);
showBackupErrorAlertDialog(requireContext().getString(R.string.dialog_report_error_missing_folder));
backupLocationOption.setSummary(requireContext().getString(R.string.pref_backup_now_summary_folder_unavailable));
}
}
else
{
backupLocationOption.setSummary(requireContext().getString(R.string.pref_backup_location_summary_initial));
}
applyAdvancedSettings(isEnabled);
backupLocationOption.setOnPreferenceClickListener(preference -> {
launchFolderPicker();
return true;
});
}
private void setFormattedBackupPath(@NonNull Uri uri)
{
backupLocationOption.setSummary(formatReadableFolderPath(requireContext(), uri));
}
private void initBackupIntervalOption()
{
String backupInterval = prefs.getString(BACKUP_INTERVAL_KEY, DEFAULT_BACKUP_INTERVAL);
CharSequence entry = getEntryForValue(backupIntervalOption, backupInterval);
if (entry != null)
backupIntervalOption.setSummary(entry);
backupIntervalOption.setOnPreferenceChangeListener((preference, newValue) -> {
CharSequence newEntry = getEntryForValue(backupIntervalOption, newValue.toString());
Logger.i(TAG, "auto backup interval changed to " + newEntry);
if (newEntry != null)
backupIntervalOption.setSummary(newEntry);
return true;
});
}
private void initMaxBackupsOption()
{
maxBackupsOption.setSummary(String.valueOf(getMaxBackups(prefs)));
maxBackupsOption.setOnPreferenceChangeListener((preference, newValue) -> {
maxBackupsOption.setSummary(newValue.toString());
return true;
});
}
private void initBackupNowOption()
{
updateStatusSummaryOption();
backupNowOption.setOnPreferenceClickListener(preference -> {
runBackup();
return true;
});
}
private void updateStatusSummaryOption()
{
long lastBackupTime = prefs.getLong(LAST_BACKUP_TIME_KEY, 0L);
String summary;
if (lastBackupTime > 0)
{
String time = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(lastBackupTime);
summary = requireContext().getString(R.string.pref_backup_status_summary_success) + ": " + time;
}
else
{
summary = requireContext().getString(R.string.pref_backup_now_summary);
}
backupNowOption.setSummary(summary);
}
private void resetLastBackupTime()
{
prefs.edit().remove(LAST_BACKUP_TIME_KEY).apply();
}
private void applyAdvancedSettings(boolean isBackupEnabled)
{
backupIntervalOption.setVisible(isBackupEnabled);
maxBackupsOption.setVisible(isBackupEnabled);
backupNowOption.setVisible(isBackupEnabled);
}
private void runBackup()
{
String currentFolderPath = prefs.getString(BACKUP_FOLDER_PATH_KEY, null);
if (!TextUtils.isEmpty(currentFolderPath))
{
if (isFolderWritable(requireContext(), currentFolderPath))
{
mBackupManager = new LocalBackupManager(requireActivity(), currentFolderPath, getMaxBackups(prefs));
mBackupManager.setListener(new LocalBackupManager.Listener()
{
@Override
public void onBackupStarted()
{
Logger.i(TAG, "Manual backup started");
backupNowOption.setEnabled(false);
backupNowOption.setSummary(R.string.pref_backup_now_summary_progress);
}
@Override
public void onBackupFinished()
{
Logger.i(TAG, "Manual backup successful");
backupNowOption.setEnabled(true);
backupNowOption.setSummary(R.string.pref_backup_now_summary_ok);
prefs.edit().putLong(LAST_BACKUP_TIME_KEY, System.currentTimeMillis()).apply();
}
@Override
public void onBackupFailed(LocalBackupManager.ErrorCode errorCode)
{
String errorMessage = switch (errorCode)
{
case EMPTY_CATEGORY -> requireContext().getString(R.string.pref_backup_now_summary_empty_lists);
default -> requireContext().getString(R.string.pref_backup_now_summary_failed);
};
Logger.e(TAG, "Manual backup was failed with code: " + errorCode);
backupNowOption.setEnabled(true);
backupNowOption.setSummary(errorMessage);
showBackupErrorAlertDialog(requireContext().getString(R.string.dialog_report_error_with_logs));
}
});
mBackupManager.doBackup();
}
else
{
backupNowOption.setSummary(R.string.pref_backup_now_summary_folder_unavailable);
showBackupErrorAlertDialog(requireContext().getString(R.string.dialog_report_error_missing_folder));
Logger.e(TAG, "Manual backup error: folder " + currentFolderPath + " unavailable");
}
}
else
{
backupNowOption.setSummary(R.string.pref_backup_now_summary_folder_unavailable);
Logger.e(TAG, "Manual backup error: no folder selected");
}
}
private void launchFolderPicker()
{
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
PackageManager packageManager = requireActivity().getPackageManager();
if (intent.resolveActivity(packageManager) != null)
folderPickerLauncher.launch(intent);
else
showNoFileManagerError();
}
private void showNoFileManagerError()
{
new MaterialAlertDialogBuilder(requireActivity())
.setMessage(R.string.error_no_file_manager_app)
.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss())
.show();
}
private void showBackupErrorAlertDialog(String message)
{
requireActivity().runOnUiThread(() -> {
new MaterialAlertDialogBuilder(requireActivity())
.setTitle(R.string.pref_backup_now_summary_failed)
.setMessage(message)
.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss())
.show();
});
}
private void takePersistableUriPermission(Uri uri)
{
requireContext().getContentResolver().takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
);
}
@Nullable
public static CharSequence getEntryForValue(@NonNull ListPreference listPref, @NonNull CharSequence value)
{
CharSequence[] entryValues = listPref.getEntryValues();
CharSequence[] entries = listPref.getEntries();
if (entryValues == null || entries == null)
return null;
for (int i = 0; i < entryValues.length; i++)
{
if (entryValues[i].equals(value))
return entries[i];
}
return null;
}
}

View File

@@ -184,15 +184,15 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
{
getSettingsActivity().stackFragment(VoiceInstructionsSettingsFragment.class, getString(R.string.pref_tts_enable_title), null);
}
else if (key.equals(getString(R.string.pref_help)))
{
startActivity(new Intent(requireActivity(), HelpActivity.class));
}
else if (key.equals(getString(R.string.pref_map_locale)))
{
LanguagesFragment langFragment = (LanguagesFragment)getSettingsActivity().stackFragment(LanguagesFragment.class, getString(R.string.change_map_locale), null);
langFragment.setListener(this);
}
else if (key.equals(getString(R.string.pref_backup)))
{
getSettingsActivity().stackFragment(BackupSettingsFragment.class, getString(R.string.pref_backup_title), null);
}
}
return super.onPreferenceTreeClick(preference);
}

View File

@@ -1,6 +1,5 @@
package app.organicmaps.util;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -11,13 +10,10 @@ import android.provider.DocumentsContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import androidx.documentfile.provider.DocumentFile;
import app.organicmaps.BuildConfig;
import app.organicmaps.util.log.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
@@ -327,76 +323,4 @@ public class StorageUtils
}
}
}
public static boolean copyFileToDocumentFile(
@NonNull Activity activity,
@NonNull File sourceFile,
@NonNull DocumentFile targetFile
)
{
try (
InputStream in = new FileInputStream(sourceFile);
OutputStream out = activity.getContentResolver().openOutputStream(targetFile.getUri())
)
{
if (out == null)
{
Logger.e(TAG, "Failed to open output stream for " + targetFile.getUri());
return false;
}
byte[] buffer = new byte[8192];
int length;
while ((length = in.read(buffer)) > 0)
out.write(buffer, 0, length);
out.flush();
return true;
} catch (IOException e)
{
Logger.e(TAG, "Failed to copy file from " + sourceFile.getAbsolutePath() + " to " + targetFile.getUri(), e);
return false;
}
}
public static void deleteDirectoryRecursive(@NonNull DocumentFile dir)
{
try
{
for (DocumentFile file : dir.listFiles())
{
if (file.isDirectory())
deleteDirectoryRecursive(file);
else
file.delete();
}
dir.delete();
} catch (Exception e)
{
Logger.e(TAG, "Failed to delete directory: " + dir.getUri(), e);
}
}
public static boolean isFolderWritable(Context context, String folderPath)
{
try
{
Uri folderUri = Uri.parse(folderPath);
DocumentFile folder = DocumentFile.fromTreeUri(context, folderUri);
if (folder != null && folder.canWrite())
{
DocumentFile tempFile = folder.createFile("application/octet-stream", "temp_file");
if (tempFile != null)
{
tempFile.delete();
return true;
}
}
} catch (Exception e)
{
Logger.e(TAG, "Failed to check if folder is writable: " + folderPath, e);
}
return false;
}
}

View File

@@ -113,7 +113,6 @@ public final class PlacePageButtons extends Fragment implements Observer<List<Pl
TextView title = parent.findViewById(R.id.title);
title.setText(current.getTitle());
parent.setContentDescription(getString(current.getTitle()));
@AttrRes final int tint = current.getType() == ButtonType.BOOKMARK_DELETE
? R.attr.iconTintActive
: R.attr.iconTint;

View File

@@ -56,9 +56,6 @@ public class PlacePageLinksFragment extends Fragment implements Observer<MapObje
private View mWikimedia;
private TextView mTvWikimedia;
private View mPanoramax;
private TextView mTvPanoramax;
private PlacePageViewModel mViewModel;
private MapObject mMapObject;
@@ -166,11 +163,6 @@ public class PlacePageLinksFragment extends Fragment implements Observer<MapObje
mTvLinePage = mFrame.findViewById(R.id.tv__place_line_page);
mLinePage.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_CONTACT_LINE));
mLinePage.setOnLongClickListener((v) -> copyUrl(mLinePage, Metadata.MetadataType.FMD_CONTACT_LINE));
mPanoramax = mFrame.findViewById(R.id.ll__place_panoramax);
mTvPanoramax = mFrame.findViewById(R.id.tv__place_panoramax);
mPanoramax.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_PANORAMAX));
mTvPanoramax.setOnLongClickListener((v) -> copyUrl(mPanoramax, Metadata.MetadataType.FMD_PANORAMAX));
}
private void openUrl(Metadata.MetadataType type)
@@ -234,9 +226,6 @@ public class PlacePageLinksFragment extends Fragment implements Observer<MapObje
final String line = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_LINE);
refreshMetadataOrHide(line, mLinePage, mTvLinePage);
final String panoramax = mMapObject.getMetadata(Metadata.MetadataType.FMD_PANORAMAX);
refreshMetadataOrHide(panoramax, mPanoramax, mTvPanoramax);
}
@Override

File diff suppressed because one or more lines are too long

View File

@@ -23,7 +23,7 @@
android:orientation="vertical"
android:layout_marginEnd="@dimen/margin_base"
android:layout_gravity="center_vertical" >
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -33,7 +33,7 @@
tools:text="5 h 55 min • 1555km"
tools:visibility="visible" />
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/altitude_difference"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -6,14 +6,14 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/time"
android:singleLine="true"
android:ellipsize="end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="5 h 55 min • 1555km"/>
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/altitude_difference"
android:layout_width="wrap_content"
android:layout_height="@dimen/altitude_chart_time_distance_height"

View File

@@ -23,7 +23,7 @@
android:orientation="vertical"
android:layout_marginEnd="@dimen/margin_base"
android:layout_gravity="center_vertical" >
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -33,7 +33,7 @@
tools:text="5 h 55 min • 1555km"
tools:visibility="visible" />
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/altitude_difference"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -64,7 +64,7 @@
tools:text="5 h 55 min • 1555km"
tools:visibility="visible" />
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/arrival"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@@ -5,7 +5,7 @@
android:id="@+id/numbers"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -13,7 +13,7 @@
android:ellipsize="end"
android:layout_marginBottom="4dp"
tools:text="5 h 55 min • 1555km"/>
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/arrival"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -23,7 +23,7 @@
tools:text="Arrival 13:03"
style="@style/MwmWidget.TextView.PlanDetail.Number.Secondary"
android:textSize="@dimen/text_size_routing_plan_detail_arrival"/>
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/altitude_difference"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -8,7 +8,7 @@
<include
layout="@layout/toolbar_extended"/>
<com.google.android.material.card.MaterialCardView
<androidx.cardview.widget.CardView
android:layout_width="@dimen/settings_width"
android:layout_height="match_parent"
android:layout_marginTop="?actionBarSize"
@@ -18,6 +18,6 @@
style="@style/MwmWidget.FrameLayout.Elevation"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.google.android.material.card.MaterialCardView>
</androidx.cardview.widget.CardView>
</FrameLayout>

View File

@@ -21,7 +21,7 @@
android:orientation="horizontal"
android:layout_marginTop="@dimen/margin_half"
android:layout_marginBottom="@dimen/margin_half">
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/time"
android:layout_width="0dp"
android:layout_height="wrap_content"
@@ -31,7 +31,7 @@
tools:text="5 h 55 min • 1555km"
tools:visibility="visible" />
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/altitude_difference"
android:layout_width="wrap_content"
android:layout_height="@dimen/altitude_chart_time_distance_height"

View File

@@ -15,7 +15,6 @@
android:paddingEnd="@dimen/margin_base_plus"
android:textAppearance="@style/MwmTextAppearance.Body2"
android:visibility="gone"
tools:text="Select maps to download"
tools:visibility="visible"/>
<View

View File

@@ -18,7 +18,7 @@
android:layout_marginEnd="@dimen/margin_base"
android:layout_centerVertical="true"/>
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -37,7 +37,7 @@
android:layout_centerVertical="true"
android:layout_toEndOf="@id/downloader_status_frame"
android:layout_toStartOf="@id/size">
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/found_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -46,7 +46,7 @@
tools:text="Крымск"
tools:background="#60FF00FF"/>
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -54,7 +54,7 @@
tools:text="Донецкая область"
tools:background="#40FF0000"/>
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:background="#400000FF">
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@@ -15,7 +15,7 @@
wheel:wheelSecondaryColor="?dividerHorizontal"
wheel:wheelThickness="@dimen/margin_eighth"/>
<com.google.android.material.imageview.ShapeableImageView
<ImageView
android:id="@+id/downloader_status"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@@ -22,8 +22,6 @@
android:layout_height="wrap_content"
android:textColorHint="?android:textColorSecondary"
app:endIconMode="custom"
app:endIconCheckable="false"
app:endIconContentDescription="@string/clear"
app:endIconDrawable="@drawable/ic_clear_rounded"
app:endIconTint="?android:textColorSecondary">
<com.google.android.material.textfield.TextInputEditText
@@ -81,7 +79,6 @@
android:layout_alignParentEnd="true"
android:layout_alignEnd="@id/divideerrr"
android:background="?clickableBackground"
android:contentDescription="@string/bookmark_color"
android:padding="@dimen/margin_half"
tools:src="@drawable/ic_bookmark_none" />
</RelativeLayout>

View File

@@ -218,7 +218,7 @@
android:layout_height="wrap_content"
android:textAppearance="?android:textAppearance"
android:text="@string/elevation_profile_time" />
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -4,6 +4,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/help_button"
style="@style/MwmWidget.MapButton.Square"
android:contentDescription="@string/help"
android:tint="@null"
app:shapeAppearanceOverlay="@style/MwmWidget.MapButton.Square"
app:srcCompat="@drawable/ic_question_mark" />

View File

@@ -21,5 +21,4 @@
<include layout="@layout/place_page_line" />
<include layout="@layout/place_page_bluesky" />
<include layout="@layout/place_page_wikimedia" />
<include layout="@layout/place_page_panoramax" />
</LinearLayout>

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ll__place_panoramax"
style="@style/PlacePageItemFrame"
android:tag="website"
tools:background="#20FF0000"
tools:visibility="visible">
<ImageView
android:id="@+id/iv__place_panoramax"
style="@style/PlacePageMetadataIcon"
app:srcCompat="@drawable/ic_panoramax"
app:tint="?colorAccent"/>
<TextView
android:id="@+id/tv__place_panoramax"
android:textAlignment="viewStart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/MwmTextAppearance.PlacePage.Accent"
tools:text="@string/panoramax"/>
</LinearLayout>

View File

@@ -15,14 +15,14 @@
android:layout_height="match_parent"
android:gravity="center_vertical"
android:background="?clickableBackground">
<com.google.android.material.imageview.ShapeableImageView
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_search"
app:tint="?colorAccent"
android:layout_marginStart="@dimen/margin_base"
android:layout_marginEnd="@dimen/margin_base"/>
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/tv__message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -49,7 +49,7 @@
android:layout_marginBottom="@dimen/margin_half"
android:layout_marginTop="@dimen/margin_half"
android:background="?dividerHorizontal"/>
<com.google.android.material.imageview.ShapeableImageView
<ImageView
android:id="@+id/iv__icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -10,7 +10,7 @@
android:paddingEnd="@dimen/margin_base"
android:paddingBottom="@dimen/margin_half"
android:paddingTop="@dimen/margin_half_plus">
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/total_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -18,7 +18,7 @@
app:layout_constraintTop_toTopOf="parent"
style="@style/MwmWidget.TextView.PlanDetail.Number.Time"
tools:text="40 min"/>
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/dot"
style="@style/MwmWidget.TextView.PlanDetail.Number.Secondary"
android:layout_marginStart="@dimen/margin_quarter_plus"
@@ -28,7 +28,7 @@
app:layout_constraintStart_toEndOf="@id/total_time"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText"/>
<com.google.android.material.imageview.ShapeableImageView
<ImageView
android:id="@+id/pedestrian_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -37,7 +37,7 @@
app:layout_constraintBottom_toBottomOf="@id/total_time"
app:layout_constraintStart_toEndOf="@id/dot"
app:tint="?iconTint"/>
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/total_distance"
style="@style/MwmWidget.TextView.PlanDetail.Number.Secondary"
android:layout_width="wrap_content"

View File

@@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/altitude_chart_time_distance_margin_bottom">
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/altitude_difference"
android:layout_width="wrap_content"
android:layout_height="@dimen/altitude_chart_time_distance_height"
@@ -19,7 +19,7 @@
android:visibility="gone"
tools:text="43 m"
tools:visibility="visible"/>
<com.google.android.material.textview.MaterialTextView
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:maxLines="2"

View File

@@ -38,7 +38,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:contentDescription="@string/route_type"
android:orientation="horizontal">
<app.organicmaps.widget.RoutingToolbarButton
@@ -46,7 +45,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/routing_selector_wheel_margin"
android:contentDescription="@string/vehicle"
tools:button="@drawable/ic_car"
tools:buttonTint="?colorAccent" />
@@ -56,7 +54,6 @@
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:contentDescription="@string/pedestrian"
tools:button="@drawable/ic_pedestrian"
tools:buttonTint="?iconTintLight" />
@@ -65,7 +62,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/margin_half_plus"
android:contentDescription="@string/subway"
tools:button="@drawable/ic_transit"
tools:buttonTint="?iconTintLight" />
@@ -74,7 +70,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:contentDescription="@string/bicycle"
tools:button="@drawable/ic_bike"
tools:buttonTint="?iconTintLight" />
@@ -83,7 +78,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:contentDescription="@string/ruler"
tools:button="@drawable/ic_ruler_route"
tools:buttonTint="?iconTintLight" />
</RadioGroup>

View File

@@ -493,7 +493,7 @@
<!-- Title for OSM note section in the editor -->
<string name="editor_other_info">Nota aan OpenStreetMap-vrywilligers (opsioneel)</string>
<!-- Hint of the input field in the OSM note section of the editor -->
<string name="editor_note_hint">Beskryf foute in die kaart of wat nie met CoMaps geredigeer kan word nie</string>
<string name="editor_note_hint">Beskryf foute in die kaart of wat nie met Organiese Kaarte geredigeer kan word nie</string>
<!-- Information about OSM at the top of the editing page -->
<string name="editor_about_osm">Jou wysigings word opgelaai na die publieke <a href="https://wiki.openstreetmap.org/wiki/About_OpenStreetMap">OpenStreetMap</a>-databasis. Moet asseblief nie persoonlike of kopiereginligting byvoeg nie.</string>
<string name="editor_more_about_osm">Meer oor OpenStreetMap</string>
@@ -503,7 +503,7 @@
<!-- To indicate the operator of ATMs, bicycle rentals, electric vehicle charging stations... -->
<string name="operator">Operateur: %s</string>
<string name="editor_category_unsuitable_title">Kan u nie \'n geskikte kategorie vind nie?</string>
<string name="editor_category_unsuitable_text">CoMaps laat toe om slegs eenvoudige puntkategorieë by te voeg, dit beteken geen dorpe, paaie, mere, gebouomlynings, ens. Voeg asseblief sulke kategorieë direk by <a href="https://www.openstreetmap.org">OpenStreetMap.org</a>. Gaan ons <a href="https://www.comaps.app/support/advanced-map-editing/">gids</a> na vir gedetailleerde stap-vir-stap-instruksies.</string>
<string name="editor_category_unsuitable_text">Organiese kaarte laat toe om slegs eenvoudige puntkategorieë by te voeg, dit beteken geen dorpe, paaie, mere, gebouomlynings, ens. Voeg asseblief sulke kategorieë direk by <a href="https://www.openstreetmap.org">OpenStreetMap.org</a>. Gaan ons <a href="https://www.comaps.app/support/advanced-map-editing/">gids</a> na vir gedetailleerde stap-vir-stap-instruksies.</string>
<string name="downloader_no_downloaded_maps_title">U het geen kaarte afgelaai nie</string>
<string name="downloader_no_downloaded_maps_message">Laai kaarte af om die ligging te soek en vanlyn te navigeer.</string>
<string name="current_location_unknown_error_title">Huidige ligging is onbekend.</string>
@@ -546,7 +546,7 @@
<string name="editor_share_to_all_dialog_title">Wil u dit na alle gebruikers stuur?</string>
<!-- Dialog before publishing the modifications to the public map. -->
<string name="editor_share_to_all_dialog_message_1">Maak seker u het geen privaat of persoonlike data ingevoer nie.</string>
<string name="editor_share_to_all_dialog_message_2">OpenStreetMap-redigeerders sal die verandeirnge nagaan en u kontak indien hulle vrae het.</string>
<string name="editor_share_to_all_dialog_message_2">OpenStraatMap-redigeerders sal die verandeirnge nagaan en u kontak indien hulle vrae het.</string>
<!-- Shown as toast when starting the recent track recording -->
<string name="track_recording">Opname van die spoor</string>
<!-- For the first routing -->
@@ -616,7 +616,7 @@
<string name="privacy_policy">Privaatheidsbeleid</string>
<string name="terms_of_use">Gebruiksvoorwaardes</string>
<string name="button_layer_traffic">Verkeer</string>
<string name="subway">Moltrein</string>
<string name="button_layer_subway">Moltrein</string>
<string name="layers_title">Kaartstyle en -lae</string>
<string name="subway_data_unavailable">Moltreinkaart is onbeskikbaar</string>
<string name="bookmarks_empty_list_title">Hierdie lys is leeg</string>
@@ -797,10 +797,4 @@
<string name="uri_open_location_failed">Geen toepassing geïnstalleer wat die ligging kan oopmaak nie</string>
<!-- preference string for using auto theme only in navigation mode -->
<string name="nav_auto">Outo in navigasie</string>
<string name="telegram_url">https://t.me/CoMapsApp/</string>
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/About_OpenStreetMap</string>
<string name="comma_separated_pair">%1$s, %2$s</string>
<string name="tts_info_link">https://www.comaps.app/support/tts-configuration-guide-for-android/</string>
<string name="translated_om_site_url">https://comaps.app/</string>
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
</resources>

View File

@@ -567,6 +567,7 @@
<string name="type.landuse.education">Opvoedkundige fasiliteit</string>
<string name="type.landuse.farmland">Landbougrond</string>
<string name="type.landuse.farmyard">Plaaswerf</string>
<string name="type.landuse.field">Veld</string>
<string name="type.landuse.forest">Woud</string>
<string name="type.landuse.forest.coniferous">Naaldwoud</string>
<string name="type.landuse.forest.deciduous">Loofwoud</string>

View File

@@ -503,7 +503,7 @@
<!-- Text in About and OSM Login screens. First %@ is replaced by a local, human readable date. -->
<string name="osm_presentation">بيانات OpenStreetMap التي أنشأها المجتمع اعتبارًا من %s. تعرف على المزيد حول كيفية تعديل الخريطة وتحديثها على OpenStreetMap.org</string>
<!-- OSM explanation on Android login screen -->
<string name="login_osm_presentation">OpenStreetMap.org (OSM) هو مشروع مجتمعي لبناء خريطة مجانية ومفتوحة. إنه المصدر الرئيسي لبيانات الخرائط في CoMaps ويعمل على غرار ويكيبيديا. يمكنك إضافة الأماكن أو تعديلها وتصبح متاحة لملايين المستخدمين في جميع أنحاء العالم.\nنضم إلى المجتمع وساعد في إنشاء خريطة أفضل للجميع!</string>
<string name="login_osm_presentation">OpenStreetMap.org (OSM) هو مشروع مجتمعي لبناء خريطة مجانية ومفتوحة. إنه المصدر الرئيسي لبيانات الخرائط في الخرائط العضوية ويعمل على غرار ويكيبيديا. يمكنك إضافة الأماكن أو تعديلها وتصبح متاحة لملايين المستخدمين في جميع أنحاء العالم. نضم إلى المجتمع وساعد في إنشاء خريطة أفضل للجميع!</string>
<string name="login_to_make_edits_visible">أنشئ حساباً على OpenStreetMap أو سجّل الدخول لنشر تعديلاتك على الخريطة للعالم.</string>
<!-- Downloaded 10 **of** 20 <- it is that "of" -->
<string name="downloader_of">%1$d من%2$d</string>
@@ -519,7 +519,7 @@
<!-- Title for OSM note section in the editor -->
<string name="editor_other_info">ملاحظة لمتطوعي OpenStreetMap (اختياري)</string>
<!-- Hint of the input field in the OSM note section of the editor -->
<string name="editor_note_hint">وصف الأخطاء على الخريطة أو الأشياء التي لا يمكن تحريرها باستخدام CoMaps</string>
<string name="editor_note_hint">وصف الأخطاء على الخريطة أو الأشياء التي لا يمكن تحريرها باستخدام الخرائط العضوية</string>
<!-- Information about OSM at the top of the editing page -->
<string name="editor_about_osm">يتم تحميل تعديلاتك على قاعدة البيانات العامة <a href="https://wiki.openstreetmap.org/wiki/Ar:About_OpenStreetMap">OpenStreetMap</a>. يرجى عدم إضافة معلومات شخصية أو محمية بحقوق الطبع والنشر.</string>
<string name="editor_more_about_osm">المزيد عن خريطة الشارع المفتوحة</string>
@@ -598,7 +598,7 @@
<!-- Settings: "Send general feedback" button -->
<string name="feedback_general">تعقيب عام</string>
<string name="prefs_languages_information">نحن نستخدم نظام تحويل النص إلى كلام (TTS) للتعليمات الصوتية. تستخدم العديد من أجهزة أندرويد نظام Google TTS، يمكنك تنزيله من أو تحديثه من متجر Play (https://play.google.com/store/apps/details?id=com.google.android.tts)</string>
<string name="prefs_languages_information_off">بالنسبة لبعض اللغات، ستحتاج إلى تنزيل تطبيق تحويل النص إلى كلام أو حزمة لغات إضافية من متجر التطبيقات (متجر Play، متجر Galaxy، معرض التطبيقات، FDroid).\nافتح إعدادات جهازك، ثم اللغة والإدخال، ثم تحويل النص إلى كلام.\nهنا يمكنك إدارة إعدادات نظامي تحويل النص إلى كلام (على سبيل المثال، تنزيل حزمة لغات للاستخدام دون اتصال بالإنترنت).</string>
<string name="prefs_languages_information_off">بالنسبة لبعض اللغات، ستحتاج إلى تنزيل تطبيق تحويل النص إلى كلام أو حزمة لغات إضافية من متجر التطبيقات(متجر Play، Galaxy Store، App Gallery، FDroid(. \nافتح إعدادات جهازك ثم اللغة والإدخال ثم تحويل النص إلى كلام. \nهنا يمكنك إدارة الإعدادات لأنظمة تحويل النص إلى كلا(على سبيل المثال، تنزيل حزمة اللغة للاستجدام دون اتصال انترنيت)</string>
<string name="prefs_languages_information_off_link">لمزيد من المعلومات الرجاء مراجعة هذا الدليل.</string>
<string name="transliteration_title">كتابة جميع الاسماء بالحروف اللاتينية بشكل حرفي</string>
<string name="learn_more">معرفة المزيد</string>
@@ -667,7 +667,7 @@
<string name="privacy_policy">سياسة الخصوصية</string>
<string name="terms_of_use">شروط الاستخدام</string>
<string name="button_layer_traffic">حركة مرور</string>
<string name="subway">مترو الانفاق</string>
<string name="button_layer_subway">مترو الانفاق</string>
<string name="layers_title">أنماط الخريطة وطبقاتها</string>
<string name="subway_data_unavailable">خريطة مترو الانفاق غير متوفرة</string>
<string name="bookmarks_empty_list_title">هذه اللائحة فارغة</string>
@@ -821,9 +821,9 @@
<!-- App tip #09 -->
<string name="app_tip_09">هدفنا الرئيسي هو إنشاء خرائط سريعة وسهلة الاستخدام تركز على الخصوصية والتي ستعجبك.</string>
<!-- Text on the Android Auto or CarPlay placeholder screen that maps are displayed on the phone screen -->
<string name="car_used_on_the_phone_screen">أنت الآن تستخدم CoMaps على شاشة الهاتف</string>
<string name="car_used_on_the_phone_screen">أنت الآن تستخدم الخرائط العضوية على شاشة الهاتف</string>
<!-- Text on the phone placeholder screen that maps are displayed on the car screen -->
<string name="car_used_on_the_car_screen">أنت الآن تستخدم CoMaps على شاشة السيارة</string>
<string name="car_used_on_the_car_screen">أنت الآن تستخدم الخرائط العضوية على شاشة السيارة</string>
<!-- Displayed on the phone screen. Android Auto connected -->
<string name="aa_connected_title">أنت متصل بـ Android Auto</string>
<!-- Displayed on the phone screen. Button to display maps on the phone screen instead of a car -->
@@ -831,11 +831,11 @@
<!-- Displayed on the Android Auto or CarPlay screen. Button to display maps on the car screen instead of a phone. Must be no more than 18 symbols! -->
<string name="car_continue_in_the_car">إلى شاشة السيارة</string>
<!-- Ask user to grant location permissions -->
<string name="aa_location_permissions_request">تحتاج CoMaps ة إلى الوصول إلى الموقع. عندما يكون الوضع آمنًا، تحقق من الإشعارات الموجودة على هاتفك.</string>
<string name="aa_location_permissions_request">تحتاج الخرائط العضوية إلى الوصول إلى الموقع. عندما يكون الوضع آمنًا، تحقق من الإشعارات الموجودة على هاتفك.</string>
<!-- Notification title for permission request from AA. -->
<string name="aa_request_permission_notification">هذا التطبيق يحتاج إلى إذنك</string>
<!-- The text in the activity for location permission request. -->
<string name="aa_request_permission_activity_text">تحتاج CoMaps في Android Auto إلى إذن تحديد الموقع للعمل بفعالية</string>
<string name="aa_request_permission_activity_text">تحتاج الخرائط العضوية في Android Auto إلى إذن تحديد الموقع للعمل بفعالية</string>
<!-- Grant Permissions button. -->
<string name="aa_grant_permissions">أذونات المنح</string>
<!-- Outdoors/hiking map style (activity) name in the Styles and Layers dialog -->
@@ -886,9 +886,4 @@
<string name="uri_open_location_failed">لم يتم تثبيت أي تطبيق يمكنه فتح الموقع</string>
<!-- preference string for using auto theme only in navigation mode -->
<string name="nav_auto">تلقائي في التنقل</string>
<string name="translated_om_site_url">https://comaps.app/ar</string>
<string name="telegram_url">https://t.me/CoMapsApp</string>
<string name="tts_info_link">https://www.comaps.app/support/tts-configuration-guide-for-android</string>
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
<string name="wikimedia_commons">ويكيميديا كومنز</string>
</resources>

View File

@@ -594,6 +594,7 @@
<string name="type.landuse.construction">منطقة بناء</string>
<string name="type.landuse.education">مؤسسة تعليمية</string>
<string name="type.landuse.farmland">حقل</string>
<string name="type.landuse.field">حقل</string>
<string name="type.landuse.flowerbed">مشتل أزهار</string>
<string name="type.landuse.forest">غابة</string>
<string name="type.landuse.forest.coniferous">غابة صنوبرية</string>

View File

@@ -86,7 +86,7 @@
<string name="privacy">Privacidá</string>
<string name="layers_title">Estilos y capes del mapa</string>
<string name="subway_data_unavailable">El mapa del metro nun ta disponible</string>
<string name="subway">Metro</string>
<string name="button_layer_subway">Metro</string>
<string name="delete_list">Desaniciar llista</string>
<string name="public_access">Accesu públicu</string>
<string name="bookmarks_empty_list_title">Esta llista ta balera</string>
@@ -176,10 +176,4 @@
<string name="choose_street">Escueyi una cai</string>
<string name="select_option">Esbilla una opción</string>
<string name="choose_color">Escueyi un color</string>
<string name="telegram_url">https://t.me/CoMapsApp/</string>
<string name="translated_om_site_url">https://comaps.app/</string>
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/About_OpenStreetMap</string>
<string name="tts_info_link">https://www.comaps.app/support/tts-configuration-guide-for-android/</string>
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
<string name="wikimedia_commons">Wikimedia Commons</string>
</resources>

View File

@@ -492,7 +492,7 @@
<!-- Text in About and OSM Login screens. First %@ is replaced by a local, human readable date. -->
<string name="osm_presentation">%s tarixinə icma tərəfindən yaradılmış OpenStreetMap datası. OpenStreetMap.org saytında xəritəni necə redaktə etmək və yeniləmək haqqında ətraflı məlumat əldə edin</string>
<!-- OSM explanation on Android login screen -->
<string name="login_osm_presentation">OpenStreetMap.org (OSM) pulsuz və açıq xəritə yaratmaq üçün icma layihəsidir. O, CoMaps xəritə məlumatlarının əsas mənbəyidir və Vikipediyaya oxşar işləyir. Siz yerlər əlavə edə və ya redaktə edə bilərsiniz və onlar bütün dünyada milyonlarla istifadəçi üçün əlçatan olur. \nİcmaya qoşulun və hər kəs üçün daha yaxşı xəritə yaratmağa kömək edin!</string>
<string name="login_osm_presentation">OpenStreetMap.org (OSM) pulsuz və açıq xəritə yaratmaq üçün icma layihəsidir. O, Üzvi Xəritələrdə xəritə məlumatlarının əsas mənbəyidir və Vikipediyaya oxşar işləyir. Siz yerlər əlavə edə və ya redaktə edə bilərsiniz və onlar bütün dünyada milyonlarla istifadəçi üçün əlçatan olur. \nİcmaya qoşulun və hər kəs üçün daha yaxşı xəritə yaratmağa kömək edin!</string>
<string name="login_to_make_edits_visible">OpenStreetMap hesabı yaradın və ya xəritə redaktələrinizi dünyada dərc etmək üçün daxil olun.</string>
<!-- Downloaded 10 **of** 20 <- it is that "of" -->
<string name="downloader_of">%1$d/%2$d</string>
@@ -508,7 +508,7 @@
<!-- Title for OSM note section in the editor -->
<string name="editor_other_info">OpenStreetMap könüllüləri üçün qeyd (isteğe bağlı)</string>
<!-- Hint of the input field in the OSM note section of the editor -->
<string name="editor_note_hint">Xəritədəki səhvləri və ya CoMaps istifadə edərək redaktə edilə bilməyənləri təsvir edin</string>
<string name="editor_note_hint">Xəritədəki səhvləri və ya Üzvi Xəritələrdən istifadə edərək redaktə edilə bilməyənləri təsvir edin</string>
<!-- Information about OSM at the top of the editing page -->
<string name="editor_about_osm">Redaktələriniz ictimai <a href="https://wiki.openstreetmap.org/wiki/Tr:About">OpenStreetMap</a> verilənlər bazasına yüklənir. Zəhmət olmasa şəxsi və ya müəllif hüquqları ilə qorunan məlumatları əlavə etməyin.</string>
<string name="editor_more_about_osm">OpenStreetMap haqqında əlavə məlumat</string>
@@ -518,7 +518,7 @@
<!-- To indicate the operator of ATMs, bicycle rentals, electric vehicle charging stations... -->
<string name="operator">Operator: %s</string>
<string name="editor_category_unsuitable_title">Uyğun kateqoriya tapa bilmirsiniz?</string>
<string name="editor_category_unsuitable_text">CoMaps yalnız sadə nöqtə kateqoriyaları əlavə etməyə imkan verir, bu o deməkdir ki, şəhərlər, yollar, göllər, bina konturları və s. yoxdur. Lütfən, belə kateqoriyaları birbaşa <a href="https://www.openstreetmap.org">OpenStreetMap.org</a> saytına əlavə edin. Ətraflı addım-addım təlimatlar üçün <a href="https://www.comaps.app/support/advanced-map-editing/">bələdçimizi</a> yoxlayın.</string>
<string name="editor_category_unsuitable_text">Üzvi Xəritələr yalnız sadə nöqtə kateqoriyaları əlavə etməyə imkan verir, bu o deməkdir ki, şəhərlər, yollar, göllər, bina konturları və s. yoxdur. Lütfən, belə kateqoriyaları birbaşa <a href="https://www.openstreetmap.org">OpenStreetMap.org</a> saytına əlavə edin. Ətraflı addım-addım təlimatlar üçün <a href="https://www.comaps.app/support/advanced-map-editing/">bələdçimizi</a> yoxlayın.</string>
<string name="downloader_no_downloaded_maps_title">Siz heç bir xəritə endirməmisiniz</string>
<string name="downloader_no_downloaded_maps_message">Ünvanları tapmaq və oflayn naviqasiya etmək üçün xəritələri endirin.</string>
<string name="current_location_unknown_error_title">Cari yer məlum deyil.</string>
@@ -644,7 +644,7 @@
<string name="privacy_policy">Gizlilik Siyasəti</string>
<string name="terms_of_use">İstifadə qaydaları</string>
<string name="button_layer_traffic">Nəqliyyat</string>
<string name="subway">Metro</string>
<string name="button_layer_subway">Metro</string>
<string name="layers_title">Xəritə Üslubları və Qatları</string>
<string name="subway_data_unavailable">Metro xəritəsi mövcud deyil</string>
<string name="bookmarks_empty_list_title">Bu siyahı boşdur</string>
@@ -671,7 +671,7 @@
<string name="power_managment_setting_never">Heç vaxt</string>
<string name="power_managment_setting_auto">Avtomatik</string>
<string name="power_managment_setting_manual_max">Maksimum enerji qənaəti</string>
<string name="enable_logging_warning_message">Yardım dialoq qutusunda “Problemi bildir” istifadə etməklə probleminizlə bağlı ətraflı diaqnostik jurnalları qeyd etmək və bizə göndərmək üçün bu seçimi müvəqqəti aktivləşdirin. Qeydlərə məkan məlumatı daxil ola bilər.</string>
<string name="enable_logging_warning_message">Yardım dialoq qutusunda “Problemi bildir” istifadə etməklə probleminizlə bağlı ətraflı diaqnostik jurnalları qeyd etmək və bizə göndərmək üçün bu seçimi müvəqqəti aktivləşdirin. Qeydlərə məkan məlumatı daxil ola bilər</string>
<string name="access_rules_author_only">Onlayn redaktə</string>
<string name="driving_options_title">Marşrutlaşdırma seçimləri</string>
<!-- Recommended length for CarPlay and Android Auto is around 25-27 characters -->
@@ -682,7 +682,7 @@
<string name="avoid_ferry">Bərə keçidlərindən çəkinin</string>
<string name="avoid_motorways">Magistral yoldan çəkinin</string>
<string name="unable_to_calc_alert_title">Marşrutu hesablamaq mümkün deyil</string>
<string name="unable_to_calc_alert_subtitle">Təəssüf ki, seçdiyiniz seçimlərə görə marşrut tapa bilmədik. Seçimləri dəyişdirin və yenidən cəhd edin.</string>
<string name="unable_to_calc_alert_subtitle">Təəssüf ki, seçdiyiniz seçimlərə görə marşrut tapa bilmədik. Seçimləri dəyişdirin və yenidən cəhd edin</string>
<string name="define_to_avoid_btn">Qarşısını almaq üçün yolları müəyyənləşdirin</string>
<string name="change_driving_options_btn">Sürmə seçimləri aktiv edildi</string>
<string name="toll_road">Ücrətli yol</string>
@@ -777,7 +777,7 @@
<!-- Translated CoMaps site, add new translations here: https://github.com/organicmaps/organicmaps.github.io/tree/master/content -->
<string name="translated_om_site_url">https://comaps.app/tr/</string>
<!-- Link to OSM wiki for Editor, Profile and About pages -->
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/Az:Layihə_haqqında</string>
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/Tr:About</string>
<!-- App Tip #00 -->
<string name="app_tip_00">İcma tərəfindən yaradılmış xəritələrimizdən istifadə etdiyiniz üçün təşəkkür edirik!</string>
<!-- App tip #04 -->
@@ -840,8 +840,4 @@
<string name="uri_open_location_failed">Məkanı aça biləcək proqram quraşdırılmayıb</string>
<!-- preference string for using auto theme only in navigation mode -->
<string name="nav_auto">Naviqasiyada avtomatik</string>
<string name="telegram_url">https://t.me/CoMapsApp/</string>
<string name="tts_info_link">https://www.comaps.app/support/tts-configuration-guide-for-android/</string>
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
<string name="wikimedia_commons">Vikianbar</string>
</resources>

View File

@@ -585,6 +585,7 @@
<string name="type.landuse.construction">Struktur</string>
<string name="type.landuse.farmland">Kənd Təsərrüfatı Torpaqları</string>
<string name="type.landuse.farmyard">Ferma rayonu</string>
<string name="type.landuse.field">Ərazi</string>
<string name="type.landuse.flowerbed">Çiçəklik</string>
<string name="type.landuse.forest">Meşə</string>
<string name="type.landuse.forest.coniferous">Şam meşəsi</string>

View File

@@ -636,7 +636,7 @@
<string name="privacy_policy">Палітыка прыватнасці</string>
<string name="terms_of_use">Умовы выкарыстання</string>
<string name="button_layer_traffic">Рух</string>
<string name="subway">Метро</string>
<string name="button_layer_subway">Метро</string>
<string name="layers_title">Стылі і слаі карты</string>
<string name="subway_data_unavailable">Карта метро недаступная</string>
<string name="bookmarks_empty_list_title">Гэты спіс пусты</string>
@@ -880,8 +880,7 @@
<item quantity="other">Знойдзена %d файлаў. Вы можаце ўбачыць іх пасля пераўтварэння.</item>
</plurals>
<string name="error_enter_correct_vk_page">Увядзіце сапраўднае імя карыстальніка або спасылку VK</string>
<string name="wikimedia_commons">Вікісховішча</string>
<string name="wikimedia_commons">Wikimedia Commons</string>
<string name="comma_separated_pair">%1$s, %2$s</string>
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/RU:О_проекте</string>
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/About_OpenStreetMap</string>
</resources>

View File

@@ -542,7 +542,7 @@
<!-- Settings: "Send general feedback" button -->
<string name="feedback_general">Обща обратна връзка</string>
<string name="prefs_languages_information">Навигирането се озвучава от системен синтезатор на реч (TTS). Много устройства използват Google TTS, който може да бъде изтеглен или актуализиран от Google Play (https://play.google.com/store/apps/details?id=com.google.android.tts).</string>
<string name="prefs_languages_information_off">За някои езици може да се наложи да инсталирате допълнителен синтезатор на реч (TTS) от магазина за приложения (Google Play, Samsung Galaxy Store, Huawei AppGallery, F-Droid). \nЗа да настроите синтезатора на реч, отидете в Настройки → Езици и въвеждане → Синтезиран говор. \nТук можете да инсталирате допълнителни езикови пакети или да изберете синтезатор на реч.</string>
<string name="prefs_languages_information_off">За някои езици може да се наложи да инсталирате допълнителен синтезатор на реч (TTS) от магазина за приложения (Google Play Магазин, Galaxy Store). \nЗа да настроите синтезатора на реч, отидете в Настройки → Езици и въвеждане → Синтезиран говор. \nТук можете да инсталирате допълнителни езикови пакети или да изберете синтезатор на реч.</string>
<string name="prefs_languages_information_off_link">За повече информация вижте това ръководство.</string>
<string name="transliteration_title">Изпиши на латиница</string>
<string name="learn_more">Научете повече</string>
@@ -594,7 +594,7 @@
<string name="privacy_policy">Политика за поверителност</string>
<string name="terms_of_use">Условия за ползване</string>
<string name="button_layer_traffic">Трафик</string>
<string name="subway">Метро</string>
<string name="button_layer_subway">Метро</string>
<string name="layers_title">Стилове и слоеве на картата</string>
<string name="subway_data_unavailable">Картата на метрото не е налична</string>
<string name="bookmarks_empty_list_title">Този списък е празен</string>
@@ -690,7 +690,7 @@
<!-- OpenStreetMap text on splash screen -->
<string name="splash_subtitle">Картографски данни от OpenStreetMap</string>
<!-- Link to OSM wiki for Editor, Profile and About pages -->
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/Bg:About_OpenStreetMap</string>
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/Bg:About</string>
<!-- App Tip #00 -->
<string name="app_tip_00">Благодарим ви, че използвате нашите карти, създадени от общността!</string>
<!-- App tip #01 -->
@@ -824,7 +824,7 @@
<string name="miles_per_hour">мили/ч</string>
<string name="animals">Животни</string>
<string name="buildings">Сгради</string>
<string name="translated_om_site_url">https://comaps.app/</string>
<string name="translated_om_site_url">https://www.comaps.app/</string>
<string name="hotels">Хотели</string>
<string name="others_sorttype">Други</string>
<string name="month_ago_sorttype">Преди месец</string>
@@ -838,5 +838,4 @@
<string name="trip_finished">Пристигнахте!</string>
<string name="instagram">Instagram</string>
<string name="downloader_loading_ios">Изтегляне</string>
<string name="wikimedia_commons">Общомедия</string>
</resources>

View File

@@ -10,30 +10,8 @@
<string name="search">অনুসন্ধান</string>
<string name="download_has_failed">ডাউনলোড ব্যর্থ। আবার চেষ্টা করতে টিপ দাও।</string>
<string name="mb">এমবি</string>
<string name="search_map">্যাপ অনুসন্ধান</string>
<string name="search_map">ানচিত্র অনুসন্ধান</string>
<string name="gb">জিবি</string>
<string name="kilometres">কিলোমিটার</string>
<string name="downloading">ডাউনলোডরত…</string>
<string name="telegram_url">https://t.me/CoMapsApp/</string>
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/About_OpenStreetMap</string>
<string name="translated_om_site_url">https://comaps.app/</string>
<string name="tts_info_link">https://www.comaps.app/support/tts-configuration-guide-for-android/</string>
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
<string name="app_site_url">https://comaps.app/</string>
<string name="location_is_disabled_long_text">আপনার ডিভাইস বা অ্যাপ এর সব লোকেশন পরিষেবা বন্ধ করা আছে। দয়া করে সেটিংস থেকে চালু করুন।</string>
<string name="close">বন্ধ</string>
<string name="download">ডাউনলোড</string>
<string name="limited_accuracy">সীমিত সঠিকতা</string>
<string name="precise_location_is_disabled_long_text">সঠিক ন্যাভিগেশনের জন্য সেটিংস থেকে নিখুঁত লোকেশন অন করুন।</string>
<string name="zoom_to_country">ম্যাপে দেখান</string>
<string name="country_status_download_failed">ডাউনলোড ব্যর্থ হল</string>
<string name="try_again">আবার চেষ্টা করুন</string>
<string name="about_menu_title">CoMaps এর ব্যাপারে</string>
<string name="about_headline">উন্মুক্ত প্রকল্প, তার সমাজ দ্বারা চলিত</string>
<string name="location_settings">লোকেশন সেটিংস</string>
<string name="about_proposition_1">• ব্যবহার করা সহজ এবং দেখতে সুন্দর</string>
<string name="about_proposition_2">• গোপনীয়তা বান্ধব এবং বিজ্ঞাপন মুক্ত</string>
<string name="about_proposition_3">• অফলাইন, দ্রুত এবং ছোট সাইজ</string>
<string name="about_developed_by_enthusiasts">পুরোপুরি ওপেন সোর্স, অলাভজনক, প্রকাশ্য সিদ্ধান্ত করণ এবং অর্থায়ন।</string>
<string name="wikimedia_commons">উইকিমিডিয়া কমন্স</string>
</resources>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

Some files were not shown because too many files have changed in this diff Show More