Compare commits
1 Commits
release/20
...
2025.06.25
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fdd37edb46 |
@@ -8,8 +8,6 @@ CoMaps contributors:
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
clover sage
|
||||
Harry Bond <me@hbond.xyz>
|
||||
vikiawv
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Organic Maps (formerly OMaps) contributors:
|
||||
|
||||
32
README.md
@@ -13,16 +13,16 @@
|
||||
# [CoMaps](https://comaps.app) – Hike, Bike, Drive Offline – Easy Map Navigation with Privacy
|
||||
|
||||
[
|
||||

|
||||

|
||||
](https://github.com/comaps/comaps/actions/workflows/android-check.yaml)
|
||||
[
|
||||

|
||||

|
||||
](https://github.com/comaps/comaps/actions/workflows/ios-check.yaml)
|
||||
[
|
||||

|
||||

|
||||
](https://opencollective.com/comaps)
|
||||
[
|
||||

|
||||

|
||||
](https://liberapay.com/CoMaps)
|
||||
|
||||
|
||||
@@ -32,16 +32,20 @@ A community-led free & open source maps app based on [OpenStreetMap](https://www
|
||||
There are apps for Android and iOS (and ARM MacOS).
|
||||
An alpha Linux / MacOS Qt desktop version, which is also suitable for Linux phones.
|
||||
|
||||
[<img src="docs/badges/apple-appstore.png" alt="App Store" width="160">](https://apps.apple.com/app/comaps/id6747180809)
|
||||
The June app release is available on Google Play, F-Droid and as an APK to download now! We are working on publishing in the iOS App Store as well, please stay tuned!
|
||||
|
||||
<!--
|
||||
[<img src="docs/badges/apple-appstore.png" alt="App Store" width="160">](https://apps.apple.com/app/comaps/id1567437057)
|
||||
-->
|
||||
[<img src="docs/badges/google-play.png" alt="Google Play" width="160">](https://play.google.com/store/apps/details?id=app.comaps.google)
|
||||
[<img src="docs/badges/fdroid.png" alt="F-Droid" width="160">](https://f-droid.org/en/packages/app.comaps.fdroid/)
|
||||
[<img src="docs/badges/codeberg.png" alt="Codeberg" width="160">](https://codeberg.org/comaps/comaps/releases)
|
||||
|
||||
<p float="left">
|
||||
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/1.png" width="180" />
|
||||
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/2.png" width="180" />
|
||||
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/3.png" width="180" />
|
||||
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/4.png" width="180" />
|
||||
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/1.jpg" width="180" />
|
||||
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/2.jpg" width="180" />
|
||||
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/3.jpg" width="180" />
|
||||
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/4.jpg" width="180" />
|
||||
</p>
|
||||
|
||||
**Offline-focused**: Plan and navigate your trip abroad without the need for cellular service, search waypoints while on a distant hike, etc. All app functions are designed to work offline.
|
||||
@@ -101,9 +105,9 @@ There is a dedicated Zulip chat for active contributors: [comaps.zulipchat.com](
|
||||
|
||||
### Feedback
|
||||
|
||||
|
||||
- **Rate us on the [App Store](https://apps.apple.com/app/comaps/id6747180809)
|
||||
and [Google Play](https://play.google.com/store/apps/details?id=app.comaps.google)**.
|
||||
<!-- uncomment when linked resources are ready
|
||||
- **Rate us on the [App Store](https://apps.apple.com/app/comaps/id1567437057)
|
||||
and [Google Play](https://play.google.com/store/apps/details?id=app.comaps)**. -->
|
||||
- Star our repos on Codeberg
|
||||
- Report bugs and discuss features at [the issue tracker](https://codeberg.org/comaps/comaps/issues)
|
||||
|
||||
@@ -113,10 +117,6 @@ The app is free for everyone, so we rely on donations. Please [donate](https://o
|
||||
|
||||
The project's financial information is completely open and transparent at [our Open Collective](https://opencollective.com/comaps).
|
||||
|
||||
## Privacy
|
||||
|
||||
The Android application was analysed by the [Exodus platform](https://reports.exodus-privacy.eu.org/fr/reports/app.comaps.google/latest/)
|
||||
|
||||
## License and Copyright
|
||||
|
||||
Licensed under the Apache License, Version 2.0. See
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
• OpenStreetMap-Daten vom 22. Juni
|
||||
• Optionale automatische Backups von Lesezeichen & Tracks
|
||||
• Neue 100m-Höhenlinien für Regionen die vorher gröbere/keine Isolinien hatten
|
||||
• Vegetation & Spielplätze werden früher angezeigt, neue Farben für Campingplätze & andere Einrichtungen
|
||||
• Pfade & Tracks werden standardmäßig bei höherem Zoom angezeigt, Outdoor-Stil für Detailübersicht
|
||||
• Aktion des linken Button nichtm mehr im Hamburger-Menü, stattdessen werden "Über & Hilfe" dort angezeigt
|
||||
• 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
|
||||
|
||||
|
After Width: | Height: | Size: 747 KiB |
|
Before Width: | Height: | Size: 628 KiB |
|
After Width: | Height: | Size: 749 KiB |
|
Before Width: | Height: | Size: 532 KiB |
|
After Width: | Height: | Size: 730 KiB |
|
Before Width: | Height: | Size: 391 KiB |
|
After Width: | Height: | Size: 590 KiB |
|
Before Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 268 KiB |
|
Before Width: | Height: | Size: 263 KiB |
@@ -1,7 +1,8 @@
|
||||
• OpenStreetMap data as of June 22
|
||||
• a setting for automatic bookmarks and tracks backup
|
||||
• added 100m-step altitude isolines to all regions that had worse or no isolines
|
||||
• display vegetation and playground color fills earlier, add fills to camp sites and some amenities
|
||||
• paths & tracks appear on the map later by default - still appear earlier in the outdoor style
|
||||
• hide active custom button action from the hamburger menu, move there About & Help from the settings
|
||||
• update map transport icons
|
||||
• 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
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
• datos de OpenStreetMap a 22 de junio
|
||||
• añadido ajuste para la copia de seguridad automática de marcadores y trazas
|
||||
• añadidas isolíneas de 100 m a las regiones que tenían isolíneas peores o no tenían isolíneas
|
||||
• se muestra antes la vegetación y zonas de juego, añadidas áreas a campings y otros servicios
|
||||
• los senderos y pistas aparecen más tarde - siguen igual en estilo de outdoors
|
||||
• se oculta botón personalizado del menú y se mueve allí Acerca de y Ayuda desde los ajustes
|
||||
• 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
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
Komunitateko doako eta iturburu irekiko aplikazioa OpenStreetMap datuetan oinarrituta eta gardentasuna, pribatutasuna eta irabazi asmorik gabeko konpromisoarekin indartua. Comaps Organic Maps-en fork edo aldaera bat da, eta hori, aldi berean, maps.me-ren forka da.
|
||||
|
||||
Irakurri proiektuaren zergatia eta haren norabidea <b> <i> codeberg.org/comaps </ i> </ b>.
|
||||
Sartu komunitatean eta lagundu maparik onena aplikatzen
|
||||
• Erabili aplikazioa eta horren berri eman
|
||||
• Eman feedbacka eta txostenetako gaiak
|
||||
• Eguneratu maparen datuak aplikazioan edo OpenStreetMap webgunean
|
||||
|
||||
‣ <b> Konexiorik gabe fokatuta </ b> Planifikatu eta nabigatu atzerrira bidaiatzea, telefono zerbitzu beharrik gabe, bilaketa-biderapenak urruneko ibilaldian eta abar. Aplikazio funtzio guztiak lineaz kanpo lan egiteko diseinatuta daude.
|
||||
‣ <b> Pribatutasuna errespetatzea </ b> errespetatzea: aplikazioa pribatutasunarekin diseinatuta dago, ez du pertsonak identifikatzen, ez du jarraipena egiten, eta ez du informazio pertsonala biltzen. Iragarkirik ez.
|
||||
‣ <b> Sinplea eta leundua </ b>: Ezinbestekoa da funtzionatzen duten ezaugarriak erabiltzeko.
|
||||
‣ <b> Zure bateria eta espazioa gordetzen ditu </ b>: ez du bateria xahutzen beste nabigazio aplikazioak bezala. Mapa trinkoak. Gorde espazio preziatua zure telefonoan.
|
||||
‣ <b> Librea eta komunitateak eraikitakoa: Jendeak aplikazioa eraikitzen lagundu zuen aplikazioa eraikitzen lagunduz OpenStreetMap, probatu eta funtzioei buruzko iritzia emanez eta garapen trebetasunak eta dirua lagunduz.
|
||||
‣ <b> Erabakiak eta finantza irekiak eta gardena, irabazi asmorik gabeko eta guztiz irekitako iturria. </ B>
|
||||
|
||||
<b> Ezaugarri nagusiak </ b>:
|
||||
• Deskargatu mapa zehatzak Google Maps-ekin eskuragarri ez dauden lekuekin
|
||||
• Mendiko modua nabarmendutako mendi ibilbideak, kanpinak, ur iturriak, gailurrak, sestra-lerroak, etab
|
||||
• Bideak eta bidegorriak
|
||||
• Jatetxe, gas geltokiak, hotelak, dendak, bisitak eta bestelako interesguneak
|
||||
• Bilatu izenaren edo helbide baten arabera edo interes-kategoriaren arabera
|
||||
• Oinez, txirrinduaz edo gidatzeko ahots-oharrekin nabigazioa
|
||||
• Markatu zure gogoko lekuak sakatze bakarrarekin
|
||||
• Lineaz kanpoko Wikipedia artikuluak
|
||||
• Metroaren garraio geruza eta jarraibideak
|
||||
• Arrastoen grabazioa
|
||||
• Laster-markak eta ibilbideak esportatu eta inportatu KML, KMZ, GPX formatuetan
|
||||
• Gauean erabiltzeko modu iluna
|
||||
• Hobetu mapako datuak guztiontzat oinarrizko editore integratua erabiliz
|
||||
|
||||
<b> Askatasuna hemen </ b> da
|
||||
Ezagutu zure bidaia, nabigatu munduan pribatutasunarekin eta komunitatez abangoardian!
|
||||
@@ -1 +1 @@
|
||||
CoMaps- Mendia, bizikleta, autoa, dena offline
|
||||
CoMaps- Mendia, bizikleta, autoa. Dena offline eta pribatutasunearekin
|
||||
|
||||
|
After Width: | Height: | Size: 737 KiB |
|
Before Width: | Height: | Size: 655 KiB |
|
After Width: | Height: | Size: 765 KiB |
|
Before Width: | Height: | Size: 532 KiB |
|
After Width: | Height: | Size: 735 KiB |
|
Before Width: | Height: | Size: 391 KiB |
|
After Width: | Height: | Size: 594 KiB |
|
Before Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 254 KiB |
|
Before Width: | Height: | Size: 263 KiB |
@@ -1,6 +1,8 @@
|
||||
• Données OpenStreetMap du 22 juin
|
||||
• Sauvegarde automatique des signets et traces GPS en local
|
||||
• Ajout des courbes d'altitude avec un précision de 100 mètres dans toutes les régions qui avaient peu de courbes ou aucune
|
||||
• Ajustements des styles notamment sur la végétation, les aires de jeu et les chemins
|
||||
• Masque l’action active du bouton personnalisé dans le menu hamburger
|
||||
• Correction de certains plantages et bugs
|
||||
• 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
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Navegación doada - Descubre máis sobre o teu camiño - Creada pola comunidade
|
||||
@@ -1 +0,0 @@
|
||||
CoMaps - Aplicación de mapas privada, sen conexión
|
||||
@@ -0,0 +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
|
||||
@@ -1 +1 @@
|
||||
Navegação fácil nos mapas - Descubra mais sobre o seu percurso - Feito por todos
|
||||
Navegação fácil nos mapas - Descobre mais sobre o teu percurso - Feito por todos
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
• карты OpenStreetMap от 22 июня
|
||||
• автоматическое резервное копирование меток и треков
|
||||
• линии высот с шагом 100м для всех регионов, где линии с этим шагом отсутствовали
|
||||
• цветная заливка растительности и игровых площадок отображается раньше, добавлена заливка для кемпингов и других объектов
|
||||
• тропы и грунтовки отображаются позже в стиле по умолчанию - используйте стиль «Активный отдых» для обзора троп
|
||||
• выбранная функция настраиваемой кнопки больше не дублируется в пунктах меню
|
||||
• обновлены цвета карты — теперь они светлее, теплее и дружелюбнее
|
||||
• редактор OSM: добавлено поле «этаж»
|
||||
• обновлены иконки заправок и зарядных станций
|
||||
• обновлены цвета некоторых элементов интерфейса
|
||||
• исправлена ссылка на карту при попытке поделиться местоположением
|
||||
• исправлено неверное отображение размера карты после ошибок загрузки
|
||||
• исправлены мелкие скачки стрелки местоположения в некоторых случаях
|
||||
• исправления ошибок для Android 5 и 6
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
• освежене су боје мапе – светлије, топлије, пријатније!
|
||||
• у OSM едитору је додато поље „спрат“
|
||||
• ажуриране су иконице бензинских пумпи и станица за пуњење
|
||||
• ажуриране су боје неких елемената корисничког интерфејса
|
||||
• поправљени су линкови за дељење локације
|
||||
• поправљена је погрешно приказана величина мапе након грешака при преузимању
|
||||
• исправљена су мала поскакивања стрелице локације у неким случајевима
|
||||
• исправљене су грешке за Android 5 и 6
|
||||
@@ -0,0 +1,8 @@
|
||||
• 刷新地图颜色-更浅、更暖、更友好!
|
||||
• OSM 编辑器:添加“楼层”字段
|
||||
• 更新加油站和充电站图标
|
||||
• 更新部分用户界面组件的颜色
|
||||
• 修复位置共享的链接
|
||||
• 修复下载后错误显示地图大小的问题
|
||||
• 修复定位箭头偶尔轻微跳动的问题
|
||||
• Android 5&6 错误修复
|
||||
@@ -0,0 +1,8 @@
|
||||
• 刷新地圖顏色-更淺、更暖、更友好!
|
||||
• OSM 編輯器:新增「樓層」欄位
|
||||
• 更新加油站和充電站圖示
|
||||
• 更新某些使用者介面元件的顏色
|
||||
• 修正位置分享的連結
|
||||
• 修正下載後錯誤顯示地圖尺寸的問題
|
||||
• 修正定位箭頭偶爾輕微跳動的問題
|
||||
• Android 5&6 錯誤修正
|
||||
@@ -1 +1 @@
|
||||
version: 2025.06.30-22-FDroid+25063022
|
||||
version: 2025.03.02-7-FDroid+25030207
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Navegación doada - Descubre máis sobre o teu camiño - Creada pola comunidade
|
||||
@@ -1 +0,0 @@
|
||||
Navegação fácil nos mapas - Descubra mais sobre o seu percurso - Feito por todos
|
||||
@@ -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!
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -213,7 +213,7 @@ public class MapButtonsController extends Fragment
|
||||
)
|
||||
{
|
||||
leftButtonView.setImageResource(R.drawable.ic_christmas_tree);
|
||||
leftButtonView.setContentDescription(getString(R.string.about_help));
|
||||
leftButtonView.setContentDescription(getString(R.string.help));
|
||||
leftButtonView.setOnClickListener((v) -> mMapButtonClickListener.onMapButtonClick(MapButtons.help));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,391 +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;
|
||||
if (errorCode == LocalBackupManager.ErrorCode.EMPTY_CATEGORY)
|
||||
{
|
||||
errorMessage = requireContext().getString(R.string.pref_backup_now_summary_empty_lists);
|
||||
Logger.i(TAG, "Nothing to backup");
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = requireContext().getString(R.string.pref_backup_now_summary_failed);
|
||||
Logger.e(TAG, "Manual backup has failed: " + errorCode);
|
||||
}
|
||||
|
||||
backupNowOption.setEnabled(true);
|
||||
backupNowOption.setSummary(errorMessage);
|
||||
|
||||
if (errorCode != LocalBackupManager.ErrorCode.EMPTY_CATEGORY)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="144dp"
|
||||
android:height="144dp"
|
||||
android:viewportWidth="144"
|
||||
android:viewportHeight="144">
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:pathData="M40.34 29.42a41.6 41.6 0 0 0-19.66 5.03q-8.77 4.85-13.8 14.42-5.05 9.57-5.05 23.18 0 13.4 5.04 22.88a36 36 0 0 0 13.71 14.51q8.67 5.04 19.76 5.04 7.95 0 14.2-2.42A33.6 33.6 0 0 0 72.8 96.24a33 33 0 0 0 3.43-11.09l-17.64-0.1q-0.6 3.33-2.22 5.95a12 12 0 0 1-3.83 4.33 19 19 0 0 1-5.44 2.73q-2.93 0.9-6.45 0.9-6.15 0-10.99-3.02-4.82-3.03-7.46-9.07-2.61-6.05-2.62-14.82 0-8.56 2.62-14.61 2.63-6.06 7.46-9.28 4.64-3.22 11.09-3.22 3.53 0 6.55 1 3.13 1.01 5.44 3.03a14.5 14.5 0 0 1 3.83 4.63q1.51 2.63 2.02 6.05h17.64a37 37 0 0 0-3.83-12.8 30 30 0 0 0-7.76-9.47 34 34 0 0 0-10.99-5.95 43 43 0 0 0-13.3-2.01m71.29 21.16q-9.37 0-16.23 4.03a26.6 26.6 0 0 0-10.59 11.2q-3.62 7.14-3.62 16.82 0 9.48 3.62 16.73a28 28 0 0 0 10.69 11.2q6.84 4.01 16.28 4.02 9.24 0 16.07-4.03a27.4 27.4 0 0 0 10.59-11.19q3.72-7.25 3.73-16.73 0-9.87-3.73-16.93a27.6 27.6 0 0 0-10.59-11.09q-6.86-4.03-16.22-4.03m0.2 13.1a9.8 9.8 0 0 1 7.05 2.42 16 16 0 0 1 4.34 6.76q1.5 4.23 1.5 9.57a33 33 0 0 1-1.5 9.68 14 14 0 0 1-4.44 6.65q-2.72 2.52-7.05 2.52-4.24 0-7.26-2.52a15 15 0 0 1-4.44-6.65 31 31 0 0 1-1.4-9.68q0-5.34 1.4-9.57 1.52-4.24 4.44-6.76 2.92-2.41 7.36-2.42"
|
||||
android:pathData="M28.2,58.5q-1.6,0 -2.87,-0.74 -1.26,-0.73 -1.98,-2.09t-0.72,-3.21q0,-1.87 0.72,-3.23t1.98,-2.1q1.27,-0.72 2.87,-0.72 1.03,0 1.91,0.3 0.88,0.31 1.56,0.88 0.68,0.56 1.11,1.36 0.44,0.79 0.58,1.77L30.9,50.72q-0.1,-0.52 -0.34,-0.92 -0.23,-0.4 -0.58,-0.68t-0.8,-0.43q-0.43,-0.15 -0.96,-0.15 -1,0 -1.7,0.48t-1.08,1.36 -0.38,2.08 0.37,2.07 1.09,1.35 1.7,0.48q0.53,0 0.97,-0.14t0.78,-0.43 0.59,-0.68 0.35,-0.91h2.44q-0.14,0.97 -0.58,1.76 -0.43,0.8 -1.11,1.36t-1.57,0.88q-0.87,0.3 -1.9,0.3m10.56,0q-1.25,0 -2.2,-0.55 -0.95,-0.54 -1.48,-1.51 -0.53,-0.98 -0.53,-2.28t0.53,-2.27 1.48,-1.52 2.2,-0.55q1.27,0 2.21,0.55 0.95,0.54 1.48,1.52 0.54,0.97 0.54,2.27t-0.54,2.28 -1.48,1.51 -2.2,0.55m0,-1.88q0.57,0 1,-0.3 0.42,-0.3 0.65,-0.84 0.24,-0.55 0.24,-1.32t-0.24,-1.32q-0.23,-0.55 -0.66,-0.84 -0.42,-0.3 -0.99,-0.3 -0.55,0 -0.98,0.3 -0.42,0.29 -0.66,0.84 -0.23,0.55 -0.23,1.32 0,0.78 0.23,1.33 0.24,0.54 0.66,0.84t0.98,0.29m5.82,1.69L44.58,46.6h3.53l1.93,5.45 0.29,0.91 0.33,1.13q0.18,0.58 0.32,1.11l0.24,0.9h-0.6l0.23,-0.9 0.32,-1.11 0.34,-1.13 0.27,-0.9 1.91,-5.46h3.53v11.7h-2.37v-5.56l0.01,-0.93 0.03,-1.16 0.03,-1.25 0.03,-1.2h0.29l-0.38,1.27 -0.37,1.27 -0.34,1.13 -0.28,0.87 -1.98,5.57h-1.96l-2,-5.57 -0.3,-0.87 -0.35,-1.13 -0.38,-1.27 -0.39,-1.27h0.35l0.02,1.2 0.03,1.25 0.03,1.16 0.01,0.93v5.57zM61.72,58.45q-0.82,0 -1.47,-0.28 -0.64,-0.27 -1.01,-0.82 -0.37,-0.56 -0.37,-1.39 0,-0.7 0.26,-1.16 0.26,-0.47 0.7,-0.75 0.46,-0.3 1.04,-0.44 0.6,-0.15 1.24,-0.2 0.76,-0.09 1.2,-0.16 0.46,-0.07 0.65,-0.2 0.2,-0.14 0.2,-0.4v-0.06q0,-0.3 -0.17,-0.53 -0.16,-0.24 -0.47,-0.37 -0.3,-0.14 -0.72,-0.14t-0.75,0.14 -0.52,0.38q-0.18,0.24 -0.22,0.56h-2.17q0.05,-0.85 0.5,-1.48 0.46,-0.63 1.27,-0.97 0.82,-0.35 1.96,-0.35 0.85,0 1.52,0.2 0.67,0.19 1.12,0.56 0.47,0.37 0.7,0.9 0.24,0.52 0.24,1.19v5.63h-2.27v-1.17h-0.03q-0.22,0.4 -0.54,0.7t-0.79,0.45 -1.1,0.16m0.65,-1.61q0.56,0 0.96,-0.2t0.63,-0.57 0.22,-0.8v-0.83l-0.27,0.11 -0.39,0.1 -0.48,0.08 -0.53,0.09q-0.4,0.06 -0.72,0.2 -0.33,0.12 -0.52,0.34 -0.18,0.21 -0.18,0.54 0,0.3 0.15,0.5 0.16,0.22 0.45,0.33t0.68,0.1m5.98,4.75L68.35,50.01h2.29v1.12h0.02q0.26,-0.43 0.62,-0.72 0.37,-0.29 0.83,-0.43 0.48,-0.15 1.01,-0.15 1.06,0 1.86,0.55 0.81,0.55 1.26,1.52 0.46,0.97 0.46,2.25 0,1.3 -0.45,2.27 -0.45,0.98 -1.25,1.52t-1.9,0.54q-0.54,0 -1,-0.16 -0.46,-0.15 -0.82,-0.47t-0.59,-0.79h-0.02v4.53zM72.51,56.58q0.56,0 0.97,-0.28 0.42,-0.29 0.65,-0.83 0.23,-0.55 0.23,-1.33t-0.23,-1.32 -0.65,-0.83q-0.4,-0.3 -0.97,-0.3 -0.59,0 -1.03,0.31 -0.44,0.3 -0.69,0.85 -0.23,0.54 -0.23,1.29 0,0.74 0.23,1.29 0.25,0.55 0.69,0.85 0.45,0.3 1.03,0.3m9.18,1.92q-1.08,0 -1.92,-0.33 -0.84,-0.34 -1.35,-0.97 -0.5,-0.62 -0.58,-1.51h2.28q0.07,0.54 0.46,0.85 0.4,0.3 1.07,0.3 0.64,0 1,-0.24 0.37,-0.24 0.37,-0.63 0,-0.33 -0.28,-0.53 -0.27,-0.2 -0.79,-0.3l-1.45,-0.29q-1.21,-0.23 -1.84,-0.84 -0.63,-0.62 -0.63,-1.58 0,-0.78 0.43,-1.37t1.21,-0.91q0.8,-0.33 1.88,-0.33t1.88,0.35 1.25,0.97q0.46,0.63 0.48,1.49h-2.14q-0.01,-0.5 -0.4,-0.83 -0.38,-0.33 -1,-0.33 -0.6,0 -0.94,0.26 -0.34,0.25 -0.34,0.62 0,0.32 0.27,0.52t0.74,0.31l1.57,0.3q1.26,0.25 1.85,0.8 0.6,0.56 0.6,1.48 0,0.82 -0.48,1.44 -0.46,0.62 -1.3,0.96 -0.82,0.34 -1.9,0.34"
|
||||
android:fillColor="#fff"/>
|
||||
</vector>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -802,5 +802,5 @@
|
||||
<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/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -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>
|
||||
@@ -889,6 +889,5 @@
|
||||
<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/comaps.app</string>
|
||||
<string name="wikimedia_commons">ويكيميديا كومنز</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -180,6 +180,5 @@
|
||||
<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/comaps.app/</string>
|
||||
<string name="wikimedia_commons">Wikimedia Commons</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -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>
|
||||
@@ -842,6 +842,5 @@
|
||||
<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/comaps.app/</string>
|
||||
<string name="wikimedia_commons">Vikianbar</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -880,8 +880,8 @@
|
||||
<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/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -800,7 +800,7 @@
|
||||
<string name="parkings">Паркинги</string>
|
||||
<string name="fuel_places">Бензиностанции</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity/</string>
|
||||
<string name="moreyear_ago_sorttype">Преди повече от година</string>
|
||||
<string name="maps_storage_external">Външно споделено хранилище</string>
|
||||
<string name="deep_orange">Тъмно Оранжево</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>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<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>
|
||||
@@ -18,22 +18,5 @@
|
||||
<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/comaps.app/</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>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources></resources>
|
||||
@@ -882,7 +882,7 @@
|
||||
<string name="twitter">X (Twitter)</string>
|
||||
<string name="wikimedia_commons">Wikimedia Commons</string>
|
||||
<string name="matrix">[Matrix]</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity/</string>
|
||||
<string name="tts_info_link">https://www.comaps.app/support/tts-configuration-guide-for-android/</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="comma_separated_pair">%1$s, %2$s</string>
|
||||
|
||||
@@ -960,6 +960,4 @@
|
||||
<string name="type.place.suburb">Suburbi</string>
|
||||
<string name="type.place.state.USA">Estat</string>
|
||||
<string name="type.power.line">Línia elèctrica</string>
|
||||
<string name="type.amenity.studio">Estudi</string>
|
||||
<string name="type.barrier.guard_rail">Barrera de seguretat</string>
|
||||
</resources>
|
||||
|
||||
@@ -871,7 +871,7 @@
|
||||
<string name="instagram">Instagram</string>
|
||||
<string name="editor_line_social_network">LINE</string>
|
||||
<string name="openstreetmap">OpenStreetMap</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity/</string>
|
||||
<string name="app_site_url">https://comaps.app/cs/</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="codeberg">Codeberg</string>
|
||||
@@ -886,11 +886,9 @@
|
||||
<string name="editor_level">Podlaží (0 je přízemí)</string>
|
||||
<string name="route_type">Typ trasy</string>
|
||||
<string name="vehicle">Vozidlo</string>
|
||||
<string name="pedestrian">Pěší zóna</string>
|
||||
<string name="bicycle">Jízdní kolo</string>
|
||||
<string name="ruler">Pravítko</string>
|
||||
<string name="pedestrian">Pěší</string>
|
||||
<string name="bicycle">Kolo</string>
|
||||
<string name="ruler">Měření</string>
|
||||
<string name="bookmark_color">Barva záložky</string>
|
||||
<string name="clear">Vymazat</string>
|
||||
<string name="panoramax">Obrázek Panoramax</string>
|
||||
<string name="about_help">O aplikaci a nápověda</string>
|
||||
</resources>
|
||||
|
||||
@@ -863,5 +863,5 @@
|
||||
<string name="change_map_locale">Sprog på kort</string>
|
||||
<string name="prefs_group_information">Information</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -883,7 +883,7 @@
|
||||
<string name="codeberg">Codeberg</string>
|
||||
<string name="app_site_url">https://comaps.app/de/</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity/</string>
|
||||
<string name="error_enter_correct_bluesky_page">Geben Sie einen gültigen Bluesky-Nutzernamen oder Webadresse ein</string>
|
||||
<string name="bluesky">Bluesky</string>
|
||||
<string name="error_enter_correct_fediverse_page">Geben Sie einen gültigen Mastodon-Nutzernamen oder Webadresse an</string>
|
||||
@@ -893,13 +893,4 @@
|
||||
<string name="editor_building_levels">Etagen (inkl. Erdgeschoss, ohne Dach)</string>
|
||||
<string name="error_enter_correct_level">Geben Sie eine gültige Etagen Nummer ein</string>
|
||||
<string name="editor_level">Etage (0 ist Erdgeschoss)</string>
|
||||
<string name="clear">Löschen</string>
|
||||
<string name="vehicle">Fahrzeug</string>
|
||||
<string name="bicycle">Fahrrad</string>
|
||||
<string name="ruler">Lineal</string>
|
||||
<string name="route_type">Routentyp</string>
|
||||
<string name="pedestrian">Fußgänger</string>
|
||||
<string name="bookmark_color">Lesezeichenfarbe</string>
|
||||
<string name="about_help">Über & Hilfe</string>
|
||||
<string name="panoramax">Panoramax Bild</string>
|
||||
</resources>
|
||||
|
||||
@@ -880,5 +880,5 @@
|
||||
<string name="vk">VK</string>
|
||||
<string name="telegram">Telegram</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -53,5 +53,5 @@
|
||||
<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/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -216,6 +216,6 @@
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/ES:Acerca_de_OpenStreetMap</string>
|
||||
<string name="translated_om_site_url">https://comaps.app/es/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
<string name="tts_info_link">https://www.comaps.app/support/tts-configuration-guide-for-android/</string>
|
||||
</resources>
|
||||
|
||||
@@ -888,8 +888,8 @@
|
||||
<string name="saved">Guardado</string>
|
||||
<string name="codeberg">Codeberg</string>
|
||||
<string name="error_enter_correct_fediverse_page">Introduce un nombre de usuario o una dirección web de Mastodon válidos</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="app_site_url">https://comaps.app/es/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
<string name="app_site_url">https://comaps.app/</string>
|
||||
<string name="bluesky">Bluesky</string>
|
||||
<string name="error_enter_correct_bluesky_page">Introduce un nombre de usuario o una dirección web de Bluesky válidos</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
@@ -898,8 +898,4 @@
|
||||
<string name="editor_level">Planta (0 es la planta baja)</string>
|
||||
<string name="editor_building_levels">Plantas (incl. planta baja, excl. tejado)</string>
|
||||
<string name="error_enter_correct_level">Introduce un número de planta válido</string>
|
||||
<string name="route_type">Tipo de ruta</string>
|
||||
<string name="vehicle">Vehículo</string>
|
||||
<string name="pedestrian">Peatonal</string>
|
||||
<string name="bicycle">Bicicleta</string>
|
||||
</resources>
|
||||
|
||||
@@ -876,7 +876,7 @@
|
||||
<string name="comma_separated_pair">%1$s, %2$s</string>
|
||||
<string name="about_developed_by_enthusiasts">Täielikult avatud lähtekoodiga, kasumit mittetaotlev, läbipaistva otsustusprotsessiga ning rahastamisega.</string>
|
||||
<string name="app_site_url">https://comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="codeberg">Codeberg</string>
|
||||
<string name="error_enter_correct_fediverse_page">Sisesta korrektne Mastodoni kasutajanimi või veebiaadress</string>
|
||||
@@ -895,14 +895,4 @@
|
||||
<string name="pedestrian">Jalakäija</string>
|
||||
<string name="ruler">Joonlaud</string>
|
||||
<string name="bookmark_color">Järjehoidja värv</string>
|
||||
<string name="panoramax">Panoramaxi pilt</string>
|
||||
<string name="about_help">Rakenduse teave ja abiteave</string>
|
||||
<string name="pref_backup_title">Järjehoidjate ja radade varundus</string>
|
||||
<string name="pref_backup_now_summary_ok">Varukoopia loomine õnnestus</string>
|
||||
<string name="pref_backup_summary">Varunda automaatselt sinu nutiseadmes asuvasse kausta</string>
|
||||
<string name="pref_backup_now_title">Varunda kohe</string>
|
||||
<string name="pref_backup_now_summary">Tee varukoopia kohe</string>
|
||||
<string name="pref_backup_now_summary_progress">Varundamine on töös…</string>
|
||||
<string name="pref_backup_now_summary_empty_lists">Pole järjehoidjaid ega radu, mida varundada</string>
|
||||
<string name="pref_backup_now_summary_failed">Varundamine ei õnnestunud</string>
|
||||
</resources>
|
||||
|
||||
@@ -866,7 +866,7 @@
|
||||
<string name="wikimedia_commons">Wikimedia Commons</string>
|
||||
<string name="vk">VK</string>
|
||||
<string name="editor_line_social_network">MARRA</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity/</string>
|
||||
<string name="matrix">Jabber (XMPP)</string>
|
||||
<string name="mastodon">Mastodon</string>
|
||||
<string name="openstreetmap">OpenStreetMap</string>
|
||||
@@ -881,21 +881,4 @@
|
||||
<string name="instagram">Instagram</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="saved">Gordeta</string>
|
||||
<string name="app_site_url">https://comaps.app/</string>
|
||||
<string name="pref_left_button_disable">Desgaitu</string>
|
||||
<string name="pref_left_button_title">Ezkerreko botoiaren ezarpena</string>
|
||||
<string name="about_help">Honi buruz eta Laguntza</string>
|
||||
<string name="bookmark_color">Laster-markaren kolorea</string>
|
||||
<string name="bluesky">Bluesky</string>
|
||||
<string name="error_enter_correct_bluesky_page">Sartu baliozko Blueskyko erabiltzaile-izena edo web helbidea</string>
|
||||
<string name="error_enter_correct_fediverse_page">Sartu baliozko Mastodoneko erabiltzaile-izena edo web helbidea</string>
|
||||
<string name="route_type">Ibilbide mota</string>
|
||||
<string name="vehicle">Ibilgailua</string>
|
||||
<string name="pedestrian">Oinezkoa</string>
|
||||
<string name="bicycle">Bizikleta</string>
|
||||
<string name="ruler">Erregela</string>
|
||||
<string name="clear">Garbitu</string>
|
||||
<string name="panoramax">Panoramax Picture</string>
|
||||
<string name="codeberg">Codeberg</string>
|
||||
</resources>
|
||||
|
||||
@@ -1279,66 +1279,4 @@
|
||||
<string name="type.leisure.slipway">Arrapala</string>
|
||||
<string name="type.leisure.track">Pista</string>
|
||||
<string name="type.leisure.track.area">Pista</string>
|
||||
<string name="type.landuse.plant_nursery">Landare haztegia</string>
|
||||
<string name="type.leisure.firepit">Su-ontzi</string>
|
||||
<string name="type.man_made.breakwater">Dike</string>
|
||||
<string name="type.man_made.cairn">Mugarri</string>
|
||||
<string name="type.amenity.studio">Apartamentua</string>
|
||||
<string name="type.man_made.mast">Masta</string>
|
||||
<string name="type.man_made.pier">Ontziraleku</string>
|
||||
<string name="type.man_made.pipeline">Hodi</string>
|
||||
<string name="type.man_made.flagpole">Bandera-masta</string>
|
||||
<string name="type.barrier.guard_rail">Baranda</string>
|
||||
<string name="type.highway.ladder">Eskailera</string>
|
||||
<string name="type.leisure.beach_resort">Hondartzako oporleku</string>
|
||||
<string name="type.waterway.weir">Presa</string>
|
||||
<string name="type.man_made.crane">Garabia</string>
|
||||
<string name="type.man_made.wastewater_plant">Hondakin urak araztegia</string>
|
||||
<string name="type.man_made.works">Lantegiak</string>
|
||||
<string name="type.military">Eremu militarra</string>
|
||||
<string name="type.mountain_pass">Mendatea</string>
|
||||
<string name="type.power.generator">Energia sorgailua</string>
|
||||
<string name="type.power.line">Linea elektrikoa</string>
|
||||
<string name="type.power.line.underground">Lur-azpiko linea elektrikoa</string>
|
||||
<string name="type.power.minor_line">Linea elektriko txikia</string>
|
||||
<string name="type.power.station">Elektrizitate zentrala</string>
|
||||
<string name="type.public_transport.platform">Plataforma</string>
|
||||
<string name="type.railway">Trenbidea</string>
|
||||
<string name="type.railway.abandoned">Utzitako trenbidea</string>
|
||||
<string name="type.railway.abandoned.bridge">Utzitako trenbide zubia</string>
|
||||
<string name="type.railway.abandoned.tunnel">Utzitako trenbide tunela</string>
|
||||
<string name="type.railway.crossing">Trenbide gurutzea</string>
|
||||
<string name="type.railway.disused">Erabilerarik gabeko trenbidea</string>
|
||||
<string name="type.railway.funicular.tunnel">Funikularreko tunela</string>
|
||||
<string name="type.railway.light_rail">Tranbia erraila</string>
|
||||
<string name="type.railway.light_rail.bridge">Tranbia zubia</string>
|
||||
<string name="type.railway.light_rail.tunnel">Tranbia tunela</string>
|
||||
<string name="type.railway.monorail.bridge">Monorrail zubia</string>
|
||||
<string name="type.railway.monorail.tunnel">Monorrail tunela</string>
|
||||
<string name="type.railway.narrow_gauge">Zabalera estuko trenbidea</string>
|
||||
<string name="type.railway.platform">Trenbide plataforma</string>
|
||||
<string name="type.railway.tram.bridge">Tranbia bideko zubia</string>
|
||||
<string name="type.railway.tram.tunnel">Tranbia bideko tunela</string>
|
||||
<string name="type.route">Ibilbidea</string>
|
||||
<string name="type.route.ferry">Ferry</string>
|
||||
<string name="type.leisure.resort">Oporleku</string>
|
||||
<string name="type.waterway.canal">Kanala</string>
|
||||
<string name="type.waterway.canal.tunnel">Kanal tunela</string>
|
||||
<string name="type.waterway.dam">Presa</string>
|
||||
<string name="type.barrier.ditch">Erretena</string>
|
||||
<string name="type.waterway.dock">Ibaibideko kaia</string>
|
||||
<string name="type.waterway">Ibaibide</string>
|
||||
<string name="type.waterway.drain">Estolda</string>
|
||||
<string name="type.man_made.pipeline.overground">Lur gaineko hodia</string>
|
||||
<string name="type.man_made.storage_tank">Biltegi-depositua</string>
|
||||
<string name="type.railway.construction">Trenbidea eraikuntzan</string>
|
||||
<string name="type.railway.funicular.bridge">Funikularreko zubia</string>
|
||||
<string name="type.railway.narrow_gauge.tunnel">Zabalera estuko trenbide tunela</string>
|
||||
<string name="type.railway.subway">Metro linea</string>
|
||||
<string name="type.power.pole">Elektrizitate zutoina</string>
|
||||
<string name="type.power">Elektrizitatea</string>
|
||||
<string name="type.tourism.hotel">Hotela</string>
|
||||
<string name="type.tourism.zoo">Zoo</string>
|
||||
<string name="type.railway.tram">Tranbia bidea</string>
|
||||
<string name="type.man_made.survey_point">Markatze-puntua</string>
|
||||
</resources>
|
||||
|
||||
@@ -395,7 +395,7 @@
|
||||
<string name="editor_example_values">مقادیر پیش فرض</string>
|
||||
<string name="editor_correct_mistake">تصحیح خطا</string>
|
||||
<string name="editor_add_select_location">مکان را انتخاب کنید</string>
|
||||
<string name="editor_report_problem_desription_1">لطفا مشکلتان را با جزئیات توضیح دهید بطوری که انجمن OpenStreetMap بتوانند آن را برطرف کنند.</string>
|
||||
<string name="editor_report_problem_desription_1">لطفا مشکلتان را با جزئیات توضیح دهید بطوری که انجمن OSM بتوانند آن را برطرف کنند.</string>
|
||||
<string name="editor_report_problem_desription_2">یا خودتان آن را انجام دهید در وبسایت https://www.openstreetmap.org/</string>
|
||||
<string name="editor_report_problem_send_button">ارسال</string>
|
||||
<string name="editor_report_problem_title">مشکل</string>
|
||||
@@ -463,7 +463,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) یک پروژه اجتماعی برای ساخت یک نقشه رایگان و باز است. این منبع اصلی داده های نقشه در نقشه های ارگانیک است و مشابه ویکی پدیا کار می کند. میu200cتوانید مکانu200cها را اضافه یا ویرایش کنید تا در دسترس میلیونu200cها کاربر در سراسر جهان قرار گیرند. \nبه انجمن بپیوندید و به ایجاد نقشه بهتر برای همه کمک کنید!</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>
|
||||
@@ -479,7 +479,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/Fa:About_OpenStreetMap">OpenStreetMap</a> آپلود می شود. لطفا اطلاعات شخصی یا دارای حق چاپ را اضافه نکنید.</string>
|
||||
<string name="editor_more_about_osm">در مورد OpenStreetMap بیشتر بدانید</string>
|
||||
@@ -489,7 +489,7 @@
|
||||
<!-- To indicate the operator of ATMs, bicycle rentals, electric vehicle charging stations... -->
|
||||
<string name="operator">اپراتور: %s</string>
|
||||
<string name="editor_category_unsuitable_title">آیا نمی توانید یک دسته بندی مناسب پیدا کنید؟</string>
|
||||
<string name="editor_category_unsuitable_text">CoMaps اجازه می دهد فقط دسته های نقطه ای ساده را اضافه کند، یعنی هیچ شهر، جاده، دریاچه، طرح کلی ساختمان و غیره وجود ندارد. لطفاً این دسته ها را مستقیماً به <a href="https://www.openstreetmap.org">OpenStreetMap.org</a> اضافه کنید. برای دستورالعمل های گام به گام، <a href="https://www.comaps.app/support/advanced-map-editing/">راهنمای</a> ما را بررسی کنید.</string>
|
||||
<string name="editor_category_unsuitable_text">CoMaps اجازه میu200cدهد فقط دستهu200cهای نقطهu200cای ساده را اضافه کند، یعنی هیچ شهر، جاده، دریاچه، طرح کلی ساختمان و غیره وجود ندارد. لطفاً این دستهu200cها را مستقیماً به <a href="https://www.openstreetmap.org">OpenStreetMap.org</a> اضافه کنید. برای دستورالعملu200cهای گام به گام، <a href="https://www.comaps.app/support/advanced-map-editing/">راهنمای</a> ما را بررسی کنید.</string>
|
||||
<string name="downloader_no_downloaded_maps_title">شما هیچ نقشه دانلود شده ای ندارید</string>
|
||||
<string name="downloader_no_downloaded_maps_message">برای جست وجو یک مکان و استفاده از قابلیت ناوبری، نقشهها را دانلود کنید.</string>
|
||||
<string name="current_location_unknown_error_title">مکان فعلیتان ناشناس است.</string>
|
||||
@@ -551,7 +551,7 @@
|
||||
<!-- Settings: "Send general feedback" button -->
|
||||
<string name="feedback_general">\"تنظیمات: دکمه \"ارسال بازخورد کلی</string>
|
||||
<string name="prefs_languages_information">ما از TTS سیستم برای دستورالعملهای صوتی استفاده می کنیم. بسیاری از دستگاههای Android از Google TTS استفاده می کنند، شما می توانید آن را از Google Play دانلود کنید (https://play.google.com/store/apps/details؟id=com.google.android.tts)</string>
|
||||
<string name="prefs_languages_information_off">برای بعضی از زبانها، شما باید speech synthesizer یا یک بسته زبان دیگر را از فروشگاه برنامه (Google Play, Galaxy Store, App Gallery, FDroid) نصب کنید. \n تنظیمات دستگاه خود را باز کنید. → زبان و ورودی → گفتار → خروجی متن به گفتار. می توانید تنظیمات برای ترکیب گفتار (به عنوان مثال، بستههای زبان را برای استفاده آفلاین دانلود کنید) را مدیریت کنید و یک موتور دیگر متن به گفتار را انتخاب کنید.</string>
|
||||
<string name="prefs_languages_information_off">برای برخی از زبانها، باید یک سینت سایزر گفتار یا بسته زبان دیگری را از فروشگاه برنامه (Google Play، Galaxy Store، AppGallery، F-Droid) نصب کنید.\nتنظیمات → زبان و ورودی → گفتار → خروجی متن به گفتار دستگاه خود را باز کنید.\nمیتوانید تنظیمات مربوط به سینت سایزر گفتار را مدیریت کنید (به عنوان مثال، بستههای زبانی را برای استفاده آفلاین دانلود کنید) و یک موتور متن به گفتار متفاوت انتخاب کنید.</string>
|
||||
<string name="prefs_languages_information_off_link">برای اطلاعات بیشتر لطفا این راهنما را بررسی کنید.</string>
|
||||
<string name="transliteration_title">ترجمه به لاتین</string>
|
||||
<string name="learn_more">بیشتر بدانید</string>
|
||||
@@ -582,7 +582,7 @@
|
||||
</plurals>
|
||||
<string name="bookmarks_create_new_group">ایجاد لیست جدید</string>
|
||||
<!-- Bookmark categories screen, button that opens folder selection dialog to import KML/KMZ/GPX/KMB files -->
|
||||
<string name="bookmarks_import">وارد کردن نشانک ها و آهنگ ها</string>
|
||||
<string name="bookmarks_import">وارد کردن نشانکu200cها و آهنگu200cها</string>
|
||||
<string name="bookmarks_error_message_share_general">با توجه به خطای برنامه، امکان اشتراک گذاری وجود ندارد</string>
|
||||
<string name="bookmarks_error_title_share_empty">خطای اشتراک</string>
|
||||
<string name="bookmarks_error_message_share_empty">یک لیست خالی را نمی توان به اشتراک گذاشت</string>
|
||||
@@ -793,7 +793,7 @@
|
||||
<!-- To indicate if restaurant or other place has outdoor seating -->
|
||||
<string name="outdoor_seating">نشستن در فضای باز</string>
|
||||
<!-- Disclaimer summary shown when Power Saving Mode is enabled -->
|
||||
<string name="power_save_dialog_summary">برای دقیق ترین ناوبری، توصیه می کنیم حالت صرفه جویی در مصرف انرژی را در تنظیمات باتری گوشی غیرفعال کنید.</string>
|
||||
<string name="power_save_dialog_summary">برای دقیقu200cترین ناوبری، توصیه میu200cکنیم حالت صرفهu200cجویی در مصرف انرژی را در تنظیمات باتری گوشی غیرفعال کنید.</string>
|
||||
<!-- Prompt to start recording a track. -->
|
||||
<string name="start_track_recording">ضبط مسیر</string>
|
||||
<!-- Prompt for stopping a track recording. -->
|
||||
@@ -816,6 +816,5 @@
|
||||
<string name="telegram_url">https://t.me/CoMapsApp</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/comaps.app</string>
|
||||
<string name="wikimedia_commons">ویکیانبار</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -885,7 +885,7 @@
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="codeberg">Codeberg</string>
|
||||
<string name="error_enter_correct_bluesky_page">Kirjoita kelvollinen Bluesky-käyttäjänimi tai verkko-osoite</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
<string name="app_site_url">https://comaps.app/</string>
|
||||
<string name="pref_left_button_title">Vasemman painikkeen asettelu</string>
|
||||
<string name="pref_left_button_disable">Poista käytöstä</string>
|
||||
@@ -893,13 +893,4 @@
|
||||
<string name="error_enter_correct_level">Syötä kerrosnumero</string>
|
||||
<string name="editor_building_levels">Kerrokset (sis. pohjakerroksen, jätä pois katto)</string>
|
||||
<string name="editor_level">Kerros (0 on pohjakerros)</string>
|
||||
<string name="clear">Tyhjennä</string>
|
||||
<string name="route_type">Reitin tyyppi</string>
|
||||
<string name="vehicle">Ajoneuvo</string>
|
||||
<string name="pedestrian">Jalankulkija</string>
|
||||
<string name="bicycle">Polkupyörä</string>
|
||||
<string name="ruler">Viivoitin</string>
|
||||
<string name="bookmark_color">Kirjanmerkin väri</string>
|
||||
<string name="about_help">Tietoja ja ohje</string>
|
||||
<string name="panoramax">Panoramax-kuva</string>
|
||||
</resources>
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
<string name="translated_om_site_url">https://comaps.app/fr/</string>
|
||||
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/FR: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/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -889,7 +889,7 @@
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="app_site_url">https://comaps.app/</string>
|
||||
<string name="codeberg">Codeberg</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
<string name="bluesky">Bluesky</string>
|
||||
<string name="error_enter_correct_bluesky_page">Entrez un nom d\'utilisateur ou une adresse web Bluesky correct</string>
|
||||
<string name="error_enter_correct_fediverse_page">Entrez un nom d\'utilisateur ou une adresse web Mastodon correct</string>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<string name="details">Detalles</string>
|
||||
<string name="editor_reset_edits_button">Restablecer</string>
|
||||
<string name="category_parking">Aparcamento</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity/</string>
|
||||
<string name="tts_info_link">https://www.comaps.app/support/tts-configuration-guide-for-android/</string>
|
||||
<string name="select_cuisine">Seleccionar cociña</string>
|
||||
<string name="comma_separated_pair">%1$s, %2$s</string>
|
||||
|
||||
@@ -1299,6 +1299,4 @@
|
||||
<string name="type.emergency.emergency_ward_entrance">Entrada a urxencias</string>
|
||||
<string name="type.amenity.dojo">Dojo</string>
|
||||
<string name="type.leisure.sports_hall">Pavillón deportivo</string>
|
||||
<string name="type.highway.ladder">Escada</string>
|
||||
<string name="type.man_made.crane">Grúa</string>
|
||||
</resources>
|
||||
|
||||
@@ -596,8 +596,7 @@
|
||||
<!-- preference string for using auto theme only in navigation mode -->
|
||||
<string name="nav_auto">नेविगेशन में ऑटो</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
<string name="tts_info_link">https://www.comaps.app/support/tts-configuration-guide-for-android/</string>
|
||||
<string name="osm_wiki_about_url">https://wiki.openstreetmap.org/wiki/About_OpenStreetMap</string>
|
||||
<string name="wikimedia_commons">विकिमीडिया कॉमन्स</string>
|
||||
</resources>
|
||||
|
||||
@@ -147,6 +147,5 @@
|
||||
<string name="translated_om_site_url">https://comaps.app/hr/</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/comaps.app/</string>
|
||||
<string name="wikimedia_commons">Zajednički poslužitelj</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources></resources>
|
||||
@@ -838,7 +838,7 @@
|
||||
<string name="nav_auto">Automatikus navigáció</string>
|
||||
<string name="telegram">Telegram</string>
|
||||
<string name="instagram">Instagram</string>
|
||||
<string name="wikimedia_commons">Wikimédia Commons</string>
|
||||
<string name="wikimedia_commons">Wikimedia Commons</string>
|
||||
<string name="editor_line_social_network">LINE</string>
|
||||
<string name="empty_street_name_error">Adjon meg egy utcanevet</string>
|
||||
<string name="vk">VKontakte</string>
|
||||
@@ -873,5 +873,5 @@
|
||||
<string name="error_enter_correct_twitter_page">Adjon meg egy érvényes X (Twitter) felhasználónevet vagy webcímet</string>
|
||||
<string name="error_enter_correct_instagram_page">Adjon meg egy érvényes Instagram felhasználónevet vagy webcímet</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
<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/comaps.app/</string>
|
||||
<string name="wikimedia_commons">Wikimedia Commons</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -816,7 +816,7 @@
|
||||
<string name="nav_auto">Otomatis dalam navigasi</string>
|
||||
<string name="openstreetmap">OpenStreetMap</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</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>
|
||||
<string name="tts_info_link">https://www.comaps.app/support/tts-configuration-guide-for-android/</string>
|
||||
</resources>
|
||||
|
||||
@@ -599,5 +599,5 @@
|
||||
<string name="enable_logging_warning_message">Virkjaðu þennan valkost tímabundið til að skrá og senda síðan handvirkt nákvæma greiningarskrá um vandamálið þitt með því að nota \"Tilkynna um villu\" í hjálparglugganum. Slíkar atvikaskrár geta innihaldið upplýsingar um staðsetningu.</string>
|
||||
<string name="error_no_file_manager_app">Mistókst að birta val á möppum þar sem ekkert hentugt forrit er uppsett á tækinu þínu. Settu upp skráastjóra og prófaðu svo aftur.</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||
@@ -880,7 +880,7 @@
|
||||
<string name="error_enter_correct_fediverse_page">Inserisci un nome utente o un indirizzo web Mastodon valido</string>
|
||||
<string name="bluesky">Bluesky</string>
|
||||
<string name="error_enter_correct_bluesky_page">Inserisci un nome utente o un indirizzo web Bluesky valido</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comaps.app/</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity/</string>
|
||||
<string name="telegram_url">https://t.me/CoMapsApp/</string>
|
||||
<string name="saved">Salvato</string>
|
||||
<string name="pref_left_button_title">Configurazione del bottone di sinistra</string>
|
||||
|
||||
@@ -861,6 +861,5 @@
|
||||
<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/comaps.app</string>
|
||||
<string name="wikimedia_commons">ויקישיתוף</string>
|
||||
<string name="instagram_url">https://www.instagram.com/comapscommunity</string>
|
||||
</resources>
|
||||
|
||||