[android] World maps for all flavors

Signed-off-by: Andrei Shkrob <github@shkrob.dev>
This commit is contained in:
Andrei Shkrob 2025-02-06 21:43:28 +01:00
parent 2d2a27dec7
commit 8fa1c1022c
19 changed files with 9 additions and 1478 deletions

View file

@ -241,7 +241,7 @@ android {
android.applicationVariants.all { variant ->
def task = variant.name.capitalize()
project.task(type: Exec, "run${task}", dependsOn: "install${task}") {
commandLine android.getAdbExe(), 'shell', 'am', 'start', '-n', "$applicationId/app.organicmaps.DownloadResourcesActivity", '-a', 'android.intent.action.MAIN', '-c', 'android.intent.category.LAUNCHER'
commandLine android.getAdbExe(), 'shell', 'am', 'start', '-n', "$applicationId/app.organicmaps.SplashActivity", '-a', 'android.intent.action.MAIN', '-c', 'android.intent.category.LAUNCHER'
}
}
}

View file

@ -89,6 +89,11 @@
android:screenOrientation="fullUser"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
@ -343,22 +348,6 @@
</activity>
<activity
android:name="app.organicmaps.DownloadResourcesLegacyActivity"
android:configChanges="orientation|screenLayout|screenSize"
android:screenOrientation="fullUser"/>
<activity-alias
android:name="app.organicmaps.DownloadResourcesActivity"
android:label="@string/app_name"
android:targetActivity="app.organicmaps.SplashActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
<activity
android:name="app.organicmaps.MwmActivity"
android:launchMode="singleTask"

View file

@ -27,7 +27,6 @@ set(SRC
app/organicmaps/core/logging.cpp
app/organicmaps/bookmarks/data/BookmarkManager.cpp
app/organicmaps/DisplayedCategories.cpp
app/organicmaps/DownloadResourcesLegacyActivity.cpp
app/organicmaps/editor/Editor.cpp
app/organicmaps/editor/OpeningHours.cpp
app/organicmaps/editor/OsmOAuth.cpp

View file

@ -1,186 +0,0 @@
#include "Framework.hpp"
#include "defines.hpp"
#include "storage/downloader.hpp"
#include "storage/storage.hpp"
#include "platform/downloader_defines.hpp"
#include "platform/http_request.hpp"
#include "platform/platform.hpp"
#include "coding/internal/file_data.hpp"
#include "coding/reader_streambuf.hpp"
#include "base/file_name_utils.hpp"
#include "base/logging.hpp"
#include "base/string_utils.hpp"
#include "app/organicmaps/core/jni_helper.hpp"
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace downloader;
using namespace storage;
using namespace std::placeholders;
/// Special error codes to notify GUI about free space
//@{
#define ERR_DOWNLOAD_SUCCESS 0
#define ERR_DISK_ERROR -1
#define ERR_NOT_ENOUGH_FREE_SPACE -2
#define ERR_STORAGE_DISCONNECTED -3
#define ERR_DOWNLOAD_ERROR -4
#define ERR_NO_MORE_FILES -5
#define ERR_FILE_IN_PROGRESS -6
//@}
namespace
{
static std::vector<platform::CountryFile> g_filesToDownload;
static int g_totalDownloadedBytes;
static int g_totalBytesToDownload;
static std::shared_ptr<HttpRequest> g_currentRequest;
} // namespace
extern "C"
{
using Callback = HttpRequest::Callback;
static int HasSpaceForFiles(Platform & pl, std::string const & sdcardPath, size_t fileSize)
{
switch (pl.GetWritableStorageStatus(fileSize))
{
case Platform::STORAGE_DISCONNECTED:
return ERR_STORAGE_DISCONNECTED;
case Platform::NOT_ENOUGH_SPACE:
return ERR_NOT_ENOUGH_FREE_SPACE;
default:
return static_cast<int>(fileSize);
}
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_DownloadResourcesLegacyActivity_nativeGetBytesToDownload(JNIEnv * env, jclass clazz)
{
// clear all
g_filesToDownload.clear();
g_totalBytesToDownload = 0;
g_totalDownloadedBytes = 0;
using namespace storage;
Storage const & storage = g_framework->GetStorage();
auto const status = storage.GetForceDownloadWorlds(g_filesToDownload);
for (auto const & cf : g_filesToDownload)
g_totalBytesToDownload += cf.GetRemoteSize();
int res;
if (status == Storage::WorldStatus::ERROR_CREATE_FOLDER ||
status == Storage::WorldStatus::ERROR_MOVE_FILE)
{
res = ERR_DISK_ERROR;
}
else
{
Platform & pl = GetPlatform();
res = HasSpaceForFiles(pl, pl.WritableDir(), g_totalBytesToDownload);
}
if (res == ERR_STORAGE_DISCONNECTED)
LOG(LWARNING, ("External file system is not available"));
else if (res == ERR_NOT_ENOUGH_FREE_SPACE)
LOG(LWARNING, ("Not enough space to extract files"));
g_currentRequest.reset();
if (status == Storage::WorldStatus::WAS_MOVED)
{
g_framework->ReloadWorldMaps();
res = ERR_DOWNLOAD_SUCCESS; // reset possible storage error if we moved files
}
return res;
}
static void DownloadFileFinished(std::shared_ptr<jobject> obj, HttpRequest const & req)
{
auto const status = req.GetStatus();
ASSERT_NOT_EQUAL(status, DownloadStatus::InProgress, ());
int errorCode = ERR_DOWNLOAD_ERROR;
if (status == DownloadStatus::Completed)
errorCode = ERR_DOWNLOAD_SUCCESS;
g_currentRequest.reset();
if (errorCode == ERR_DOWNLOAD_SUCCESS)
{
auto const & curFile = g_filesToDownload.back();
size_t const sz = curFile.GetRemoteSize();
LOG(LDEBUG, ("finished downloading", curFile.GetName(), "size", sz, "bytes"));
g_totalDownloadedBytes += sz;
LOG(LDEBUG, ("totalDownloadedBytes:", g_totalDownloadedBytes));
g_filesToDownload.pop_back();
}
JNIEnv * env = jni::GetEnv();
jmethodID methodID = jni::GetMethodID(env, *obj, "onFinish", "(I)V");
env->CallVoidMethod(*obj, methodID, errorCode);
}
static void DownloadFileProgress(std::shared_ptr<jobject> listener, HttpRequest const & req)
{
JNIEnv * env = jni::GetEnv();
static jmethodID methodID = jni::GetMethodID(env, *listener, "onProgress", "(I)V");
env->CallVoidMethod(*listener, methodID, static_cast<jint>(g_totalDownloadedBytes + req.GetProgress().m_bytesDownloaded));
}
JNIEXPORT jint JNICALL
Java_app_organicmaps_DownloadResourcesLegacyActivity_nativeStartNextFileDownload(JNIEnv * env, jclass clazz, jobject listener)
{
if (g_filesToDownload.empty())
return ERR_NO_MORE_FILES;
/// @todo One downloader instance with cached servers. All this routine will be refactored some time.
static auto downloader = storage::GetDownloader();
storage::Storage const & storage = g_framework->GetStorage();
downloader->SetDataVersion(storage.GetCurrentDataVersion());
downloader->EnsureMetaConfigReady([&storage, ptr = jni::make_global_ref(listener)]()
{
auto const & curFile = g_filesToDownload.back();
auto const fileName = curFile.GetFileName(MapFileType::Map);
LOG(LINFO, ("Downloading file", fileName));
g_currentRequest.reset(HttpRequest::GetFile(
downloader->MakeUrlListLegacy(fileName),
storage.GetFilePath(curFile.GetName(), MapFileType::Map),
curFile.GetRemoteSize(),
std::bind(&DownloadFileFinished, ptr, _1),
std::bind(&DownloadFileProgress, ptr, _1),
512 * 1024, false));
});
return ERR_FILE_IN_PROGRESS;
}
JNIEXPORT void JNICALL
Java_app_organicmaps_DownloadResourcesLegacyActivity_nativeCancelCurrentFile(JNIEnv * env, jclass clazz)
{
LOG(LDEBUG, ("cancelCurrentFile, currentRequest=", g_currentRequest));
g_currentRequest.reset();
}
}

View file

@ -574,13 +574,6 @@ void Framework::RemoveLocalMaps()
m_work.DeregisterAllMaps();
}
void Framework::ReloadWorldMaps()
{
/// @todo Can invent more optimal routine to remove/add World files only.
RemoveLocalMaps();
AddLocalMaps();
}
void Framework::ReplaceBookmark(kml::MarkId markId, kml::BookmarkData & bm)
{
m_work.GetBookmarkManager().GetEditSession().UpdateBookmark(markId, bm);
@ -1675,12 +1668,6 @@ Java_app_organicmaps_Framework_nativeGetTransitRouteInfo(JNIEnv * env, jclass)
steps.get());
}
JNIEXPORT void JNICALL
Java_app_organicmaps_Framework_nativeReloadWorldMaps(JNIEnv * env, jclass)
{
g_framework->ReloadWorldMaps();
}
JNIEXPORT jboolean JNICALL
Java_app_organicmaps_Framework_nativeIsDayTime(JNIEnv * env, jclass, jlong utcTimeSeconds, jdouble lat, jdouble lon)
{

View file

@ -149,7 +149,6 @@ namespace android
void AddLocalMaps();
void RemoveLocalMaps();
void ReloadWorldMaps();
m2::PointD GetViewportCenter() const;

View file

@ -1,463 +0,0 @@
package app.organicmaps;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.CallSuper;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.annotation.StyleRes;
import androidx.core.view.ViewCompat;
import app.organicmaps.base.BaseMwmFragmentActivity;
import app.organicmaps.downloader.CountryItem;
import app.organicmaps.downloader.MapManager;
import app.organicmaps.intent.Factory;
import app.organicmaps.location.LocationHelper;
import app.organicmaps.location.LocationListener;
import app.organicmaps.util.Config;
import app.organicmaps.util.ConnectionState;
import app.organicmaps.util.StringUtils;
import app.organicmaps.util.UiUtils;
import app.organicmaps.util.Utils;
import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import java.util.List;
import java.util.Objects;
@SuppressLint("StringFormatMatches")
public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
{
private static final String TAG = DownloadResourcesLegacyActivity.class.getSimpleName();
// Error codes, should match the same codes in JNI
private static final int ERR_DOWNLOAD_SUCCESS = 0;
private static final int ERR_DISK_ERROR = -1;
private static final int ERR_NOT_ENOUGH_FREE_SPACE = -2;
private static final int ERR_STORAGE_DISCONNECTED = -3;
private static final int ERR_DOWNLOAD_ERROR = -4;
private static final int ERR_NO_MORE_FILES = -5;
private static final int ERR_FILE_IN_PROGRESS = -6;
private TextView mTvMessage;
private LinearProgressIndicator mProgress;
private Button mBtnDownload;
private CheckBox mChbDownloadCountry;
private String mCurrentCountry;
@Nullable
private Dialog mAlertDialog;
@NonNull
private ActivityResultLauncher<Intent> mApiRequest;
private boolean mAreResourcesDownloaded;
private static final int DOWNLOAD = 0;
private static final int PAUSE = 1;
private static final int RESUME = 2;
private static final int TRY_AGAIN = 3;
private static final int PROCEED_TO_MAP = 4;
private static final int BTN_COUNT = 5;
private View.OnClickListener[] mBtnListeners;
private String[] mBtnNames;
private int mCountryDownloadListenerSlot;
private interface Listener
{
// Called by JNI.
@Keep
@SuppressWarnings("unused")
void onProgress(int percent);
// Called by JNI.
@Keep
@SuppressWarnings("unused")
void onFinish(int errorCode);
}
private final LocationListener mLocationListener = new LocationListener()
{
@Override
public void onLocationUpdated(Location location)
{
if (mCurrentCountry != null)
return;
final double lat = location.getLatitude();
final double lon = location.getLongitude();
mCurrentCountry = MapManager.nativeFindCountry(lat, lon);
if (TextUtils.isEmpty(mCurrentCountry))
{
mCurrentCountry = null;
return;
}
int status = MapManager.nativeGetStatus(mCurrentCountry);
String name = MapManager.nativeGetName(mCurrentCountry);
if (status != CountryItem.STATUS_DONE)
{
UiUtils.show(mChbDownloadCountry);
String checkBoxText;
if (status == CountryItem.STATUS_UPDATABLE)
checkBoxText = String.format(getString(R.string.update_country_ask), name);
else
checkBoxText = String.format(getString(R.string.download_country_ask), name);
mChbDownloadCountry.setText(checkBoxText);
}
LocationHelper.from(DownloadResourcesLegacyActivity.this).removeListener(this);
}
};
private final Listener mResourcesDownloadListener = new Listener()
{
@Override
public void onProgress(final int percent)
{
if (!isFinishing())
mProgress.setProgressCompat(percent, true);
}
@Override
public void onFinish(final int errorCode)
{
if (isFinishing())
return;
if (errorCode == ERR_DOWNLOAD_SUCCESS)
{
final int res = nativeStartNextFileDownload(mResourcesDownloadListener);
if (res == ERR_NO_MORE_FILES)
finishFilesDownload(res);
}
else
finishFilesDownload(errorCode);
}
};
private final MapManager.StorageCallback mCountryDownloadListener = new MapManager.StorageCallback()
{
@Override
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
{
for (MapManager.StorageCallbackData item : data)
{
if (!item.isLeafNode)
continue;
switch (item.newStatus)
{
case CountryItem.STATUS_DONE:
mAreResourcesDownloaded = true;
showMap();
return;
case CountryItem.STATUS_FAILED:
MapManager.showError(DownloadResourcesLegacyActivity.this, item, null);
return;
}
}
}
@Override
public void onProgress(String countryId, long localSize, long remoteSize)
{
mProgress.setProgressCompat((int) localSize, true);
}
};
@CallSuper
@Override
protected void onSafeCreate(@Nullable Bundle savedInstanceState)
{
super.onSafeCreate(savedInstanceState);
UiUtils.setLightStatusBar(this, true);
setContentView(R.layout.activity_download_resources);
final View view = getWindow().getDecorView().findViewById(android.R.id.content);
ViewCompat.setOnApplyWindowInsetsListener(view, PaddingInsetsListener.allSides());
initViewsAndListeners();
mApiRequest = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
setResult(result.getResultCode(), result.getData());
finish();
});
if (prepareFilesDownload(false))
{
Utils.keepScreenOn(true, getWindow());
setAction(DOWNLOAD);
return;
}
showMap();
}
@CallSuper
@Override
protected void onSafeDestroy()
{
super.onSafeDestroy();
mApiRequest.unregister();
mApiRequest = null;
Utils.keepScreenOn(Config.isKeepScreenOnEnabled(), getWindow());
if (mCountryDownloadListenerSlot != 0)
{
MapManager.nativeUnsubscribe(mCountryDownloadListenerSlot);
mCountryDownloadListenerSlot = 0;
}
}
@CallSuper
@Override
protected void onResume()
{
super.onResume();
if (!isFinishing())
LocationHelper.from(this).addListener(mLocationListener);
}
@Override
protected void onPause()
{
super.onPause();
LocationHelper.from(this).removeListener(mLocationListener);
if (mAlertDialog != null && mAlertDialog.isShowing())
mAlertDialog.dismiss();
mAlertDialog = null;
}
private void setDownloadMessage(int bytesToDownload)
{
mTvMessage.setText(getString(R.string.download_resources,
StringUtils.getFileSizeString(this, bytesToDownload)));
}
private boolean prepareFilesDownload(boolean showMap)
{
final int bytes = nativeGetBytesToDownload();
if (bytes == 0)
{
mAreResourcesDownloaded = true;
if (showMap)
showMap();
return false;
}
if (bytes > 0)
{
setDownloadMessage(bytes);
mProgress.setMax(bytes);
mProgress.setProgressCompat(0, true);
}
else
finishFilesDownload(bytes);
return true;
}
private void initViewsAndListeners()
{
mTvMessage = findViewById(R.id.download_message);
mProgress = findViewById(R.id.progressbar);
mBtnDownload = findViewById(R.id.btn_download_resources);
mChbDownloadCountry = findViewById(R.id.chb_download_country);
mBtnListeners = new View.OnClickListener[BTN_COUNT];
mBtnNames = new String[BTN_COUNT];
mBtnListeners[DOWNLOAD] = v -> onDownloadClicked();
mBtnNames[DOWNLOAD] = getString(R.string.download);
mBtnListeners[PAUSE] = v -> onPauseClicked();
mBtnNames[PAUSE] = getString(R.string.pause);
mBtnListeners[RESUME] = v -> onResumeClicked();
mBtnNames[RESUME] = getString(R.string.continue_button);
mBtnListeners[TRY_AGAIN] = v -> onTryAgainClicked();
mBtnNames[TRY_AGAIN] = getString(R.string.try_again);
mBtnListeners[PROCEED_TO_MAP] = v -> onProceedToMapClicked();
mBtnNames[PROCEED_TO_MAP] = getString(R.string.download_resources_continue);
}
private void setAction(int action)
{
mBtnDownload.setOnClickListener(mBtnListeners[action]);
mBtnDownload.setText(mBtnNames[action]);
}
private void doDownload()
{
if (nativeStartNextFileDownload(mResourcesDownloadListener) == ERR_NO_MORE_FILES)
finishFilesDownload(ERR_NO_MORE_FILES);
}
private void onDownloadClicked()
{
setAction(PAUSE);
doDownload();
}
private void onPauseClicked()
{
setAction(RESUME);
nativeCancelCurrentFile();
}
private void onResumeClicked()
{
setAction(PAUSE);
doDownload();
}
private void onTryAgainClicked()
{
if (prepareFilesDownload(true))
{
setAction(PAUSE);
doDownload();
}
}
private void onProceedToMapClicked()
{
mAreResourcesDownloaded = true;
showMap();
}
public void showMap()
{
if (!mAreResourcesDownloaded)
return;
// Re-use original intent to retain all flags and payload.
// https://github.com/organicmaps/organicmaps/issues/6944
final Intent intent = Objects.requireNonNull(getIntent());
intent.setComponent(new ComponentName(this, MwmActivity.class));
// Disable animation because MwmActivity should appear exactly over this one
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
// See {@link SplashActivity.processNavigation()}
if (Factory.isStartedForApiResult(intent))
{
// Wait for the result from MwmActivity for API callers.
mApiRequest.launch(intent);
return;
}
startActivity(intent);
finish();
}
private void finishFilesDownload(int result)
{
if (result == ERR_NO_MORE_FILES)
{
// World and WorldCoasts has been downloaded, we should register maps again to correctly add them to the model.
Framework.nativeReloadWorldMaps();
if (mCurrentCountry != null && mChbDownloadCountry.isChecked())
{
CountryItem item = CountryItem.fill(mCurrentCountry);
UiUtils.hide(mChbDownloadCountry);
mTvMessage.setText(getString(R.string.downloading_country_can_proceed, item.name));
mProgress.setMax((int)item.totalSize);
mProgress.setProgressCompat(0, true);
mCountryDownloadListenerSlot = MapManager.nativeSubscribe(mCountryDownloadListener);
MapManager.nativeDownload(mCurrentCountry);
setAction(PROCEED_TO_MAP);
}
else
{
mAreResourcesDownloaded = true;
showMap();
}
}
else
{
showErrorDialog(result);
}
}
private void showErrorDialog(int result)
{
if (mAlertDialog != null && mAlertDialog.isShowing())
return;
@StringRes final int titleId;
@StringRes final int messageId = switch (result)
{
case ERR_NOT_ENOUGH_FREE_SPACE ->
{
titleId = R.string.routing_not_enough_space;
yield R.string.not_enough_free_space_on_sdcard;
}
case ERR_STORAGE_DISCONNECTED ->
{
titleId = R.string.disconnect_usb_cable_title;
yield R.string.disconnect_usb_cable;
}
case ERR_DOWNLOAD_ERROR ->
{
titleId = R.string.connection_failure;
yield (ConnectionState.INSTANCE.isConnected() ? R.string.download_has_failed
: R.string.common_check_internet_connection_dialog);
}
case ERR_DISK_ERROR ->
{
titleId = R.string.disk_error_title;
yield R.string.disk_error;
}
default -> throw new AssertionError("Unexpected result code = " + result);
};
mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
.setTitle(titleId)
.setMessage(messageId)
.setCancelable(true)
.setOnCancelListener((dialog) -> setAction(PAUSE))
.setPositiveButton(R.string.try_again, (dialog, which) -> {
setAction(TRY_AGAIN);
onTryAgainClicked();
})
.setOnDismissListener(dialog -> mAlertDialog = null)
.show();
}
@Override
@StyleRes
public int getThemeResourceId(@NonNull String theme)
{
return R.style.MwmTheme_DownloadResourcesLegacy;
}
private static native int nativeGetBytesToDownload();
private static native int nativeStartNextFileDownload(Listener listener);
private static native void nativeCancelCurrentFile();
}

View file

@ -348,10 +348,6 @@ public class Framework
public static native RouteMarkData[] nativeGetRoutePoints();
@NonNull
public static native TransitRouteInfo nativeGetTransitRouteInfo();
/**
* Registers all maps(.mwms). Adds them to the models, generates indexes and does all necessary stuff.
*/
public static native void nativeReloadWorldMaps();
/**
* Determines if currently is day or night at the given location. Used to switch day/night styles.

View file

@ -243,8 +243,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
public static Intent createShowMapIntent(@NonNull Context context, @Nullable String countryId)
{
return new Intent(context, DownloadResourcesLegacyActivity.class)
.putExtra(EXTRA_COUNTRY_ID, countryId);
return new Intent(context, SplashActivity.class).putExtra(EXTRA_COUNTRY_ID, countryId);
}
@Override

View file

@ -183,7 +183,7 @@ public class SplashActivity extends AppCompatActivity
if (isManageSpaceActivity(intent)) {
intent.setComponent(new ComponentName(this, DownloaderActivity.class));
} else {
intent.setComponent(new ComponentName(this, DownloadResourcesLegacyActivity.class));
intent.setComponent(new ComponentName(this, MwmActivity.class));
}
// FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_RESET_TASK_IF_NEEDED break the cold start.

View file

@ -22,8 +22,6 @@ import app.organicmaps.car.screens.MapScreen;
import app.organicmaps.car.screens.PlaceScreen;
import app.organicmaps.car.screens.base.BaseMapScreen;
import app.organicmaps.car.screens.download.DownloadMapsScreen;
import app.organicmaps.car.screens.download.DownloadMapsScreenBuilder;
import app.organicmaps.car.screens.download.DownloaderHelpers;
import app.organicmaps.car.screens.permissions.RequestPermissionsScreenBuilder;
import app.organicmaps.car.util.CarSensorsManager;
import app.organicmaps.car.util.CurrentCountryChangedListener;
@ -163,11 +161,7 @@ public final class CarAppSession extends Session implements DefaultLifecycleObse
mInitFailed = false;
try
{
MwmApplication.from(getCarContext()).init(() -> {
Config.setFirstStartDialogSeen(getCarContext());
if (DownloaderHelpers.isWorldMapsDownloadNeeded())
mScreenManager.push(new DownloadMapsScreenBuilder(getCarContext()).setDownloaderType(DownloadMapsScreenBuilder.DownloaderType.FirstLaunch).build());
});
MwmApplication.from(getCarContext()).init(() -> Config.setFirstStartDialogSeen(getCarContext()));
} catch (IOException e)
{
mInitFailed = true;

View file

@ -1,60 +0,0 @@
package app.organicmaps.car.screens.download;
import android.location.Location;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.car.app.model.Action;
import androidx.lifecycle.LifecycleOwner;
import app.organicmaps.R;
import app.organicmaps.downloader.CountryItem;
import app.organicmaps.downloader.MapManager;
import app.organicmaps.location.LocationHelper;
class DownloadMapsForFirstLaunchScreen extends DownloadMapsScreen
{
DownloadMapsForFirstLaunchScreen(@NonNull final DownloadMapsScreenBuilder builder)
{
super(builder);
disableCancelAction();
getMissingMaps().add(CountryItem.fill(DownloaderHelpers.WORLD_MAPS[0]));
getMissingMaps().add(CountryItem.fill(DownloaderHelpers.WORLD_MAPS[1]));
}
@Override
public void onResume(@NonNull LifecycleOwner owner)
{
// Attempting to streamline initial download by including the current country in the list of missing maps for simultaneous retrieval.
final Location location = LocationHelper.from(getCarContext()).getSavedLocation();
if (location == null)
return;
final String countryId = MapManager.nativeFindCountry(location.getLatitude(), location.getLongitude());
if (TextUtils.isEmpty(countryId))
return;
final CountryItem countryItem = CountryItem.fill(countryId);
if (!countryItem.present)
getMissingMaps().add(countryItem);
}
@NonNull
@Override
protected String getTitle()
{
return getCarContext().getString(R.string.download_map_title);
}
@NonNull
@Override
protected String getText(@NonNull String mapsSize)
{
return getCarContext().getString(R.string.download_resources, mapsSize);
}
@NonNull
@Override
protected Action getHeaderAction()
{
return Action.APP_ICON;
}
}

View file

@ -12,7 +12,6 @@ public class DownloadMapsScreenBuilder
{
public enum DownloaderType
{
FirstLaunch,
BuildRoute,
View
}
@ -68,12 +67,9 @@ public class DownloadMapsScreenBuilder
assert mMissingMaps != null;
assert mMissingMaps.length == 1;
}
else if (mDownloaderType == DownloaderType.FirstLaunch)
assert mMissingMaps == null;
return switch (mDownloaderType)
{
case FirstLaunch -> new DownloadMapsForFirstLaunchScreen(this);
case BuildRoute -> new DownloadMapsForRouteScreen(this);
case View -> new DownloadMapsForViewScreen(this);
};

View file

@ -14,17 +14,6 @@ import java.util.List;
public final class DownloaderHelpers
{
static final String[] WORLD_MAPS = new String[]{"World", "WorldCoasts"};
// World maps may be missing only in the F-Droid build.
@SuppressWarnings("ConstantConditions")
public static boolean isWorldMapsDownloadNeeded()
{
if (BuildConfig.FLAVOR.equals("fdroid"))
return !CountryItem.fill(WORLD_MAPS[0]).present || !CountryItem.fill(WORLD_MAPS[1]).present;
return false;
}
@NonNull
static List<CountryItem> getCountryItemsFromIds(@Nullable final String[] countryIds)
{

View file

@ -1,55 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?cardBackground">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/button_container"
android:layout_gravity="center">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="90dp"
android:layout_height="90dp"
app:srcCompat="@drawable/ic_download"
app:tint="?android:colorAccent"/>
<TextView
android:id="@+id/head_message"
style="?fontHeadline6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_base"
android:gravity="center"
android:text="@string/download_map_title" />
<TextView
android:id="@+id/download_message"
style="?fontBody2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_base"
android:layout_marginTop="@dimen/margin_base"
android:layout_marginEnd="@dimen/margin_base"
android:gravity="center"
android:textColor="?android:textColorSecondary"
tools:text="@string/download_resources" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<include
android:id="@+id/button_container"
layout="@layout/button_with_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
</RelativeLayout>

View file

@ -31,11 +31,6 @@
<item name="android:windowTranslucentNavigation">false</item>
</style>
<style name="MwmTheme.DownloadResourcesLegacy">
<item name="android:statusBarColor">@android:color/white</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
<style name="MwmTheme.CardBg">
<item name="android:windowBackground">@color/bg_cards</item>
</style>

View file

@ -239,54 +239,6 @@
zh-Hans = 下载地图
zh-Hant = 下載地圖
[download_has_failed]
comment = Settings/Downloader - info for country when download fails
tags = android
en = Download has failed. Touch to try again.
af = Aflaai het misluk. Tik om weer te probeer.
ar = فشلت عملية التنزيل، انقر لإعادة المحاولة
az = Yükləmə uğursuz oldu. Yenidən cəhd etmək üçün toxunun.
be = Не атрымалася спампаваць. Націсніце, каб паспрабаваць зноў.
bg = Изтеглянето се провали. Натиснете, за да опитате отново.
ca = La baixada ha fallat. Toqueu per a tornar-ho a intentar.
cs = Stahování selhalo, zkuste to znovu.
da = Der skete en fejl ved download, tryk for at prøve igen.
de = Herunterladen fehlgeschlagen. Antippen für einen neuen Versuch.
el = Η λήψη απέτυχε. Αγγίξτε για να προσπαθήσετε ξανά.
es = Error durante la descarga. Pulse para intentarlo de nuevo.
et = Allalaadimine ebaõnnestus. Puuduta uuesti proovimiseks.
eu = Errore bat gertatu da deskargatzean. Klik egin berriz saiatzeko.
fa = دانلود ناموفق بود. برای تلاش مجدد لمس کنید
fi = Lataus epäonnistui, yritä uudelleen koskettamalla
fr = Échec lors du téléchargement. Appuyer pour réessayer.
he = .הורדת הקובץ נכשלה. לחץ לניסיון נוסף
hi = डाउनलोड विफल हो गया है. पुनः प्रयास करने के लिए स्पर्श करें.
hu = Letöltés sikertelen. Kérjük próbálja újra!
id = Pengunduhan gagal, sentuh untuk mencoba sekali lagi
it = Download fallito. Riprova.
ja = ダウンロードが失敗しました。もう一度試すには画面をタッチしてください。
ko = 다운로드에 실패하였습니다. 다시 시도하려면 터치하세요.
lt = Atsisiuntimas nepavyko. Bakstelėkite, kad bandytumėte iš naujo.
lv = Lejupielāde neizdevās. Pieskarieties, lai mēģinātu vēlreiz.
mr = डाउनलोड अयशस्वी झाले. पुन्हा प्रयत्न करण्यासाठी स्पर्श करा.
mt = It-tniżżil falla. Għaffas biex terġa tipprova.
nb = Nedlastingen mislyktes trykk på nytt for å prøve en gang til
nl = Downloaden is mislukt. Tik om het opnieuw te proberen.
pl = Nie udało się pobrać. Proszę nacisnąć, aby spróbować ponownie.
pt = O descarregamento falhou, toque novamente para tentar de novo.
pt-BR = O download falhou, toque para tentar de novo.
ro = Descărcarea a eșuat. Atinge pentru a încerca din nou.
ru = Ошибка загрузки. Нажмите, чтобы повторить попытку
sk = Sťahovanie zlyhalo, skúste to znova.
sr = Преузимање није успело. Додирни за поновни покушај.
sv = Nedladdningen misslyckades, tryck för att försöka igen
th = การดาวน์โหลดล้มเหลว แตะอีกครั้งเพื่อลองใหม่
tr = İndirme başarısız oldu. Tekrar denemek için dokunun.
uk = Помилка завантаження. Натисніть, щоб повторити спробу
vi = Tải xuống thất bại, hãy chạm lại để thử một lần nữa
zh-Hans = 下载失败,点击以再试一次
zh-Hant = 下載失敗,點擊後再試一次
[downloading]
comment = Settings/Downloader - info for country which started downloading
tags = android,ios
@ -953,54 +905,6 @@
zh-Hans = 下载失败
zh-Hant = 下載失敗
[try_again]
comment = Button text for the button under the country_status_download_failed message
tags = android
en = Try Again
af = Probeer weer
ar = محاولة مرة أخرى
az = Yenidən cəhd et
be = Паспрабаваць зноў
bg = Опитайте отново
ca = Torna-ho a intentar
cs = Zkusit znovu
da = Prøv igen
de = Erneut versuchen
el = Δοκιμάστε ξανά
es = Intentar otra vez
et = Proovi uuesti
eu = Saiatu berriro
fa = تلاش مجدد
fi = Yritä uudelleen
fr = Réessayer
he = נסה שוב
hi = पुनः प्रयास करें
hu = Újrapróbálkozás
id = Coba Lagi
it = Riprova
ja = 再実行
ko = 다시 시도
lt = Bandyti dar kartą
lv = Mēģināt vēlreiz
mr = पुन्हा प्रयत्न करा
mt = Erġa prova
nb = Prøv på nytt
nl = Probeer opnieuw
pl = Spróbuj ponownie
pt = Tentar novamente
pt-BR = Tentar novamente
ro = Mai încearcă
ru = Попробуйте ещё раз
sk = Skúsiť znova
sr = Покушај поново
sv = Försök igen
th = ลองอีกครั้ง
tr = Tekrar Dene
uk = Спробуйте ще раз
vi = Thử lại
zh-Hans = 再试一次
zh-Hant = 再試一次
[about_menu_title]
tags = android
en = About Organic Maps
@ -1474,242 +1378,6 @@
zh-Hans = 下载
zh-Hant = 下載
[disconnect_usb_cable]
comment = Used in DownloadResources startup screen
tags = android
en = Please disconnect USB cable or insert memory card to use Organic Maps
af = Ontkoppel die USB-kabel of gebruik n geheuekaart om Organic Maps te gebruik
ar = الرجاء فصل كابل الناقل التسلسلي الشامل أو إدخال بطاقة الذاكرة من أجل استخدام Organic Maps.
az = Organic Maps'dan istifadə etmək üçün zəhmət olmasa USB kabeli ayırın və ya yaddaş kartı daxil edin
be = Адключыце USB кабель або ўстаўце карту памяці, каб карыстацца Organic Maps
bg = Моля, изключете USB кабела или поставете карта с памет.
ca = Desconnecteu el cable USB o inseriu una targeta de memòria per a usar lOrganic Maps
cs = Prosím, odpojte USB kabel nebo vložte paměťovou kartu pro použití s Organic Maps
da = Frakobl venligst USB-kabel eller indsæt et memory kort for at bruge Organic Maps
de = Bitte USB-Kabel entfernen oder Speicherkarte einsetzen, um Organic Maps zu verwenden
el = Αποσυνδέστε το καλώδιο USB ή τοποθετήστε την κάρτα μνήμης για να χρησιμοποιήσετε το Organic Maps
es = Desconecte el cable USB o inserte una tarjeta de memoria SD para usar Organic Maps
et = Organic Maps kasutamiseks palun ühenda USB kaabel lahti või sisesta mälukaart
eu = Mesedez, deskonektatu USB kablea edo sartu SD memoria Organic Maps erabiltzeko
fi = Irrota USB-kaapeli tai syötä muistikortti käyttääksesi Organic Maps -sovellusta
fr = Veuillez débrancher le câble USB ou insérer la carte SD pour utiliser Organic Maps
he = אנא נתק כבל USB או הכנס כרטיס זכרון כדי להשתמש ב-Organic Maps.
hi = ऑर्गेनिक मैप्स का उपयोग करने के लिए कृपया यूएसबी केबल को डिस्कनेक्ट करें या मेमोरी कार्ड डालें
hu = Kérjük bontsa az USB kapcsolatot vagy helyezzen be memóriakártyát a Organic Maps használatához
id = Mohon lepas kabel USB atau masukkan kartu memori untuk menggunakan Organic Maps
it = Si prega di scollegare il cavo USB o inserire la scheda di memoria per utilizzare Organic Maps
ja = Organic Mapsを利用するにはUSBケーブルを抜くかメモリーカードを挿入してください
ko = Organic Maps를 사용하려면 USB 케이블이나 삽입 메모리 카드를 분리하십시오
lt = Atjunkite USB laidą arba įdėkite atminties kortelę, kad naudotumėte Organic Maps
lv = Lai lietotu „Organic Maps“, atvienojiet USB kabeli vai ievietojiet atmiņas karti.
mr = Organic Maps वापरण्यासाठी कृपया USB केबल काढून टाका किंवा मेमरी कार्ड घाला
mt = Jekk jogħġbok neħħi il-USB kejbil jew daħħal karta tal-memorja biex tuża Organic Maps
nb = Koble fra USB-kabelen eller sett inn minnekortet for å bruke Organic Maps
nl = Verwijder de USB-kabel of plaats een geheugenkaart om Organic Maps te gebruiken
pl = Proszę odłączyć kabel USB albo włożyć kartę pamięci, aby korzystać z Organic Maps
pt = Por favor desligue o cabo USB ou introduza um cartão de memória para utilizar o Organic Maps
pt-BR = Por favor desconecte o cabo USB ou insira um cartão de memória para utilizar o Organic Maps
ro = Deconectează cablul USB sau introdu un card de memorie pentru a utiliza Organic Maps
ru = Отключите USB кабель или вставьте SD-карту
sk = Prosím, odpojte USB kábel alebo vložte pamäťovú kartu pre použitie s Organic Maps
sr = Молим вас откачите USB кабл, или убаците меморијску картицу да бисте користили Organic Maps
sv = Vänligen koppla ifrån USB-kabeln eller sätt in ett minneskort för att använda Organic Maps
th = โปรดยกเลิกการเชื่อมต่อสาย USB หรือใส่การ์ดหน่วยความจำเพื่อใช้ Organic Maps
tr = Organic Mapsi kullanabilmek için lütfen USB kablosunun bağlantısını kesin veya hafıza kartı takın
uk = Вимкніть USB кабель або вставте SD-карту
vi = Bạn vui lòng tháo cáp USB hoặc lắp thẻ nhớ vào để sử dụng Organic Maps
zh-Hans = 请拔除 USB 线或插入 SD 卡以使用 Organic Maps
zh-Hant = 請拔除 USB 線或插入 SD 卡以使用 Organic Maps
[not_enough_free_space_on_sdcard]
comment = Used in DownloadResources startup screen
tags = android
en = Please free up some space on the SD card/USB storage first in order to use the app
af = Maak asb. eers spasie op die SD-kaart/USB-berging beskikbaar om die kaart te kan gebruik
ar = الرجاء إخلاء بعض المساحة في تخزين البطاقة الرقمية الآمنة\الناقل التسلسلي الشامل أولا من أجل استخدام هذا التطبيق.
az = Tətbiqdən istifadə etmək üçün SD kartda/USB yaddaş cihazında bir qədər yer boşaldın.
be = Вызваліце месца на SD-карце/USB-сховішчы, каб карыстацца праграмай
bg = Моля, първо освободете място на SD картата/USB паметта, за да можете да използвате приложението.
ca = Allibereu espai en la targeta SD o emmagatzematge USB per a poder usar laplicació
cs = Prosím, uvolněte nejprve místo na SD kartě/USB uložišti
da = Frigør venligst plads på dit SD-kort/USB lager først for at bruge denne app
de = Bitte zuerst Speicherplatz auf SD-Karte/USB-Speicher freigeben, um die Anwendung zu nutzen
el = Ελευθερώσετε χώρο αποθήκευσης στην SD κάρτα/USB πρώτα προκειμένου να χρησιμοποιήσετε την εφαρμογή
es = Libere primero espacio en la memoria SD o almacenamiento USB para usar la aplicación
et = Rakenduse kasutamiseks palun vabasta kõigepealt piisavalt ruumi mälukaardil/USB salvestusseadmel
eu = Mesedez, egin lekua SD memorian/USB biltegian aplikazioa erabiltzeko
fa = لطفا مقداری از فضای ذخیره‌سازی را آزاد نمایید
fi = Vapauta ensin tilaa SD-kortilta/USB-massamuistilta käyttääksesi sovellusta
fr = Veuillez d'abord libérer de l'espace sur la carte SD/le stockage USB afin d'utiliser l'appli
he = אנא פנה שטח אחסון בכרטיס הזיכרון או בכונן USB כדי להשתמש בישום
hi = ऐप का उपयोग करने के लिए कृपया पहले एसडी कार्ड/यूएसबी स्टोरेज पर कुछ जगह खाली कर लें
hu = Kérjük szabadítson fel helyet az SD kártyán / USB tárolón az alkalmazás használatához!
id = Mohon bebaskan sejumlah ruang pada kartu SD/penyimpanan USB terlebih dahulu untuk menggunakan aplikasi
it = Libera prima dello spazio sulla scheda Sd/ memoria USB per usare l'app
ja = アプリを起動するにはSDカード/USBストレージの空き容量を確保する必要があります
ko = 앱을 사용하려면 먼저 SD 카드/USB 저장소의 여유 공간을 확보하세요
lt = Atlaisvinkite vietos jūsų saugykloje, kad galėtumėte naudotis programėle
lv = Lietotnes izmantošanai atbrīvojiet vietu ierīces krātuvē
mr = कृपया ऍप वापरण्यासाठी प्रथम SD कार्ड/USB स्टोरेजवरील काही जागा मोकळी करा
mt = Jekk jogħġbok żid ftit spazju fuq il-karta tal-memorja jew il-ħażna tal-USB biex tkun tista tuża l-applikazzjoni
nb = Frigjør plass på SD-kortet/USB-enheten først for å bruke appen
nl = Maak eerst ruimte vrij op de SD-kaart/USB-opslag om de app te gebruiken
pl = Proszę zwolnić trochę pamięci na karcie SD/pamięci USB, aby korzystać z aplikacji
pt = Por favor liberte primeiro algum espaço no cartão SD ou armazenamento USB para utilizar a aplicação
pt-BR = Por favor libere primeiro algum espaço no cartão SD/armazenamento USB para utilizar o app
ro = Spațiul de stocare de pe cardul SD/memoria USB este insuficient pentru a putea utiliza aplicația
ru = Недостаточно свободного места на SD карте/в памяти устройства для использования программы
sk = Prosím, uvoľnite najprv miesto na SD karte/USB úložisku
sr = Молим вас, прво ослободите нешто простора на SD картици или на USB меморији да бисте користили апликацију
sv = Vänligen frigör utrymme på SD-kortet/USB-lagringen först för att använda appen.
th = โปรดเพิ่มพื้นที่บางส่วนบนการ์ด SD /พื้นที่จัดเก็บ USB ก่อนเพื่อใช้แอป
tr = Uygulamayı kullanabilmek için lütfen SD kart/USB depolama aygıtında biraz alan boşaltın
uk = Недостатньо вільного місця на SD карті / в пам'яті пристрою для використання програми
vi = Bạn vui lòng giải phóng dung lượng trên ổ lưu trữ thẻ SD/USB để có thể sử dụng ứng dụng
zh-Hans = 请先释放一些 SD 卡 / USB 存储空间以使用 Organic Maps。
zh-Hant = 請先釋放一些 SD 卡 / USB 儲存空間以使用 Organic Maps。
[download_resources]
tags = android
en = Before you start using the app, please download the general world map to your device.\nIt will use %@ of storage.
af = Voordat u die toep begin gebruik, moet u asb. die algemene wêreldkaart na u toestel aflaai.\nDit sal %@ se spasie opneem.
ar = قبل أن تبدأ باستخدام التطبيق، سنقوم بتنزيل خريطة العالم العامة على جهازك.\nستحتاج إلى %@ من البيانات.
az = Başlamazdan əvvəl gəlin ümumi dünya xəritəsini cihazınıza endirək.\n%@ yer tələb olunur.
be = Перад пачаткам працы дазвольце нам спампаваць агульную мапу свету на вашу прыладу.\nГэта патрабуе %@ сховішча.
bg = Преди да започнете да използвате приложението, позволете ни да изтеглим общата карта на света на вашето устройство.\nТова ще използва %@ от паметта.
ca = Abans dusar laplicació, autoritzeu que baixem el mapa del món general al vostre aparell.\nUsarà %@ demmagatzematge.
cs = Ještě než začnete, bude třeba stáhnout obecnou mapu světa.\nZabere to %@.
da = Før du starter, så lad os downloade det generelle verdenskort til din enhed.\nIt behøver %@ af data.
de = Bevor Sie starten, laden Sie die allgemeine Weltkarte auf Ihr Gerät herunter.\nEs werden %@ Speicherplatz benötigt.
el = Πριν ξεκινήσετε τη χρήση της εφαρμογής, επιτρέψτε μας να κατεβάσουμε το γενικό παγκόσμιο χάρτη στη συσκευή σας.\nΘα χρησιμοποιήσει %@ αποθηκευτικού χώρου.
es = Antes de comenzar, permita que descarguemos en su dispositivo un mapamundi general.\nSe requieren %@ de almacenamiento.
et = Ennem rakenduse kasutamise alustamist luba meil laadida seadmesse alla maailma üldkaart.\nSee kasutab %@ mälumahtu.
eu = Hasi aurretik deskargatu mesedez mundu-mapa orokorra zure gailura.\nMemorian %@ erabiliko ditu.
fa = قبل از استفاده از اپلیکیشن, اجازه دهید تا ما نقشه جهانی را بر روی موبایل شما دانلود کنیم.\nمقدار %@ از حافظه شما اشغال می شود.
fi = Ennen aloitusta laitteelle tulee ladata yleinen maailmankartta.\nSe tarvitsee yhteensä %@ tilaa.
fr = Avant de commencer, permettez-nous de télécharger la carte générale du monde dans votre appareil.\n%@ de données sont nécessaires.
he = תחילה, נוריד למכשירך מפה כללית של העולם.\nמפה זו דורשת נפח אחסון של %@.
hi = ऐप का उपयोग शुरू करने से पहले, कृपया अपने डिवाइस पर सामान्य विश्व मानचित्र डाउनलोड करें।\nयह %@ स्टोरेज का उपयोग करेगा।
hu = Első használat előtt letöltjük a világtérképet.\n%@ tárolóhely szükséges.
id = Sebelum Anda mulai izinkan kami mengunduh peta dunia secara umum ke perangkat Anda.\nHal ini memerlukan data %@.
it = Prima di iniziare è necessario scaricare la mappa generale del mondo sul tuo dispositivo.\nLa dimensione del download è di %@.
ja = 利用を開始する前におおまかな世界地図をダウンロードします。これには%@の空き容量が必要です。
ko = 시작하시기 전에 일반 세계 지도를 귀하의 장치로 다운로드하겠습니다.\n%@ 데이터가 필요합니다.
lt = Leiskite mums atsisiųsti bendrąjį pasaulio žemėlapį į jūsų įrenginį prieš pradėdami naudotis programėle.\nTai užims %@ saugyklos.
lv = Pirms lietotnes izmantošanas lejupielādējiet kopējo pasaules karti.\nTā ierīce krātuvē aizņems %@ vietas.
mr = ऍपचा वापर सुरू करण्यापूर्वी, आम्हाला तुमच्या उपकरणावर जगाचा सामान्य नकाशा डाउनलोड करण्याची परवानगी द्या.\nते %@ जागा वापरेल.
mt = Qabel ma tibda tuża l-applikazzjoni, niżżel il-mappa ġenerali tad-dinja fuq l-apparat. \nDan ser juża %@ ta' storage.
nb = Før du begynner, la oss laste ned det generelle verdenskartet til enheten. Det trengs %@ med data.
nl = Voordat u start, laten we de algemene wereldkaart naar uw apparaat downloaden.\nDeze neemt %@ in beslag.
pl = Przed rozpoczęciem prosimy o pobranie ogólnej mapy świata na urządzenie.\nWymaga to %@ danych.
pt = Antes de começar, é recomendável descarregar o mapa mundial geral para o seu dispositivo.\nÉ necessário %@ de espaço disponível.
pt-BR = Antes de começar, vamos baixar um mapa mundial geral para o seu dispositivo.\n%@ de memória serão utilizados.
ro = Înainte de a începe, trebuie descărcată harta generală a lumii în dispozitivul tău.\nSe vor descărca %@.
ru = Перед началом работы разрешите нам загрузить общую карту мира на ваше устройство.\nЭто потребует %@ данных.
sk = Skôr ako začnete, bude treba stiahnuť základnú mapu sveta.\nZaberie to %@.
sr = Пре него што почнете да користите апликацију, прво преузмите на ваш уређај општу мапу света.\nЗа то ће бити потребно %@ меморије.
sv = Innan du startar, låt oss ladda ner den allmäna världskartan på din enhet.\nDen behöver %@ data.
th = ก่อนที่คุณจะเริ่มต้น โปรดให้เราดาวน์โหลดแผนที่โลกลงในอุปกรณ์ของคุณ\nจำเป็นต้องใช้ %@ ของข้อมูล
tr = Başlamadan önce cihazınıza genel dünya haritasını indirelim.\n%@ alan gerekli.
uk = Перш ніж розпочати дозвольте нам завантажити мапу світу на ваш пристрій.\nВона потребує %@ даних.
vi = Trước khi bạn bắt đầu, hãy để chúng tôi tải bản đồ thế giới vào thiết bị của bạn.\nBản đồ này cần %@ dữ liệu.
zh-Hans = 在您开始使用此应用程序之前,请下载全球地图到您的设备。\n它将使用 %@ 的存储空间。
zh-Hant = 在您開始使用此應用程式之前,請下載全球地圖到您的裝置。\n它將使用 %@ 的儲存空間。
[download_resources_continue]
tags = android
en = Go to Map
af = Gaan na kaart
ar = الذهاب الى الخريطة
az = Xəritəyə keçin
be = Перайсці да мапы
bg = Към картата
ca = Ves al mapa
cs = Přejít na mapu
da = Gå til kort
de = Zur Karte
el = Μετάβαση στο χάρτη
es = Ir al mapa
et = Mine kaardile
eu = Joan mapara
fa = برو به نقشه
fi = Siirry karttaan
fr = Aller sur la carte
he = עבור למפה
hi = मानचित्र पर जाएं
hu = Térképhez ugrás
id = Pergi ke Peta
it = Vai alla mappa
ja = マップを表示
ko = 지도로 이동
lt = Eiti į žemėlapį
lv = Iet uz karti
mr = नकाशावर जा
mt = Mur għal Mappa
nb = Gå til kart
nl = Ga naar de kaart
pl = Przejdź do mapy
pt = Ir ao mapa
pt-BR = Ir para o mapa
ro = Mergi la hartă
ru = Перейти на карту
sk = Prejsť na mapu
sr = Иди на мапу
sv = Gå till karta
th = ไปยังแผนที่
tr = Haritaya Git
uk = Перейти на мапу
vi = Đến Bản đồ
zh-Hans = 前往地图
zh-Hant = 前往地圖
[downloading_country_can_proceed]
tags = android
en = Downloading %@. You can now\nproceed to the map.
af = Laai tans %@ af. U kan nou\nna die kaart gaan.
ar = تنزيل %@. يمكنك الآن\nالمتابعة الى الخريطة.
az = %@ endirilir. İndi xəritəyə gedə bilərsiniz.
be = Спампоўванне %@. Цяпер вы можаце\nперайсці да мапы.
bg = Изтегляне на %@. Вече можете да преминете към картата.
ca = Sestà baixant %@. Mentrestant, podeu\nanar al mapa.
cs = Stahování %@. Nyní můžete\npřejít na mapu.
da = Downloader %@. Du kan nu\nfortsætte til kortet.
de = %@ wird heruntergeladen. Sie können jetzt\nzur Karte weitergehen.
el = Λήψη %@. Μπορείτε τώρα να\nμεταβείτε στο χάρτη.
es = Descargando %@. Puede ahora\nproceder al mapa
et = Allalaadimine %@. Võid nüüd\nkaardiga jätkata.
eu = %@ deskargatzen. Orain mapara\n joan zaitezke.
fa = درحال دانلود %@. شما اکنون می توانید\nبه نقشه بروید.
fi = Ladataan %@. Voit nyt jatkaa kartalle.
fr = %@ en téléchargement. Vous pouvez\nmaintenant aller sur la carte.
he = מוריד %@. תוכל עתה\nלהמשיך למפה.
hi = डाउनलोड हो रहा है %@. अब तुम यह कर सकते हो\nमानचित्र पर आगे बढ़ें.
hu = %@ letöltése. Mos továbbléphet\na térképhez.
id = Sedang mengunduh %@. Sekarang Anda dapat melanjutkan ke peta.
it = Sto scaricando %@. Puoi ora\nprocedere con la mappa.
ja = %@をダウンロードしました\nマップを表示可能です
ko = %@다운로드. 이제지도를 진행할 수 있습니다.
lt = Atsisiunčiama %@. Dabar galite\neiti į žemėlapį.
lv = Lejupielādē „%@“. Tagad varat\niet uz karti.
mr = %@ डाउनलोड करत आहे.\nतुम्ही आता नकाशावर जाऊ शकता.
mt = Tniżżil %@. Issa tista\ntkompli għal mappa.
nb = Laster ned %@. Du kan nå\nfortsette til kartet.
nl = %@ aan het downloaden. U kunt nu\ndoorgaan naar de kaart.
pl = Pobieranie %@. Można teraz\nprzejść do mapy.
pt = A descarregar %@. Agora pode\nver o mapa.
pt-BR = Baixando %@. Você pode\ncontinuar para o mapa agora.
ro = Se descarcă %@. Acum poți\ntrece la hartă.
ru = Пока загружается %@,\nвы можете пользоваться картой.
sk = Sťahovanie %@. Teraz môžete\nprejsť na mapu.
sr = Преузимање %@. Можете\nотићи на мапу.
sv = Laddar ner %@. Du kan nu\n fortsätta till kartan.
th = กำลังดาวน์โหลด %@ ตอนนี้คุณสามารถ\nดำเนินการต่อไปยังแผนที่
tr = %@ indiriliyor. Şimdi haritaya\ngidebilirsiniz.
uk = Поки завантажується %@\nви можете користуватися програмою.
vi = Đang tải xuống %@. Bây giờ bạn đã có thể\nvào bản đồ.
zh-Hans = 正在下载%@。您现在可以\n继续查看地图。
zh-Hant = 正在下載%@。您現在可以\n繼續查看地圖。
[download_country_ask]
tags = android
en = Download %@?
@ -1757,101 +1425,6 @@
zh-Hans = 下载%@的地图吗?
zh-Hant = 下載%@的地圖嗎?
[update_country_ask]
tags = android
en = Update %@?
af = Werk %@ by?
ar = هل تريد تحديث %@ ؟
az = %@ yenilənsin?
be = Абнавіць %@?
bg = Обновяване на %@?
ca = Voleu actualitzar %@?
cs = Aktualizovat %@?
da = Opdater %@?
de = %@ aktualisieren?
el = Να γίνει ενημέρωση %@;
es = ¿Actualizar %@?
et = Värskendada %@?
eu = %@ eguneratu?
fa = آپدیت %@?
fi = Päivitetäänkö %@?
fr = Mettre %@ à jour ?
he = לעדכן %@?
hi = अद्यतन %@?
hu = Frissítsem %@-t?
id = Perbarui %@?
it = Vuoi aggiornare %@?
ja = %@を更新しますか?
ko = %@업데이트?
lt = Naujinti %@?
lv = Vai atjaunināt „%@“?
mr = %@ अद्ययावत करायचे?
mt = Aġġorna %@?
nb = Vil du oppdatere %@?
nl = %@ updaten?
pl = Uaktualnić %@?
pt = Atualizar %@?
pt-BR = Atualizar %@?
ro = Actualizezi %@?
ru = Обновить %@?
sk = Aktualizovať %@?
sr = Ажурирати %@?
sv = Uppdatera %@?
th = อัปเดต %@?
tr = %@ güncelle?
uk = Oновити %@?
vi = Cập nhật %@?
zh-Hans = 更新%@的地图吗?
zh-Hant = 更新%@的地圖嗎?
[pause]
comment = REMOVE THIS STRING AFTER REFACTORING
tags = android
en = Pause
af = Wag
ar = توقيف مؤقت
az = Dayan
be = Прыпыніць
bg = Пауза
ca = Pausa
cs = Pauza
da = Pause
de = Pause
el = Παύση
es = Pausar
et = Peata
eu = Pausa
fa = مکث
fi = Pysäytä
fr = Pause
he = הפסק
hi = विराम
hu = Szünet
id = Jeda
it = Pausa
ja = 一時停止
ko = 중지
lt = Pristabdyti
lv = Pauze
mr = विराम द्या
mt = Pawsa
nb = Pause
nl = Pauzeer
pl = Wstrzymaj
pt = Pausar
pt-BR = Pausar
ro = Pauză
ru = Приостановить
sk = Pauza
sr = Пауза
sv = Pausa
th = หยุดชั่วคราว
tr = Duraklat
uk = Призупинити
vi = Tạm dừng
zh-Hans = 暂停
zh-Hant = 暫停
[continue_button]
comment = REMOVE THIS STRING AFTER REFACTORING
tags = android,ios
@ -8829,52 +8402,6 @@
zh-Hans = 规划路线需要下载并更新好所有从您的位置到目的地的地图。
zh-Hant = 規劃路線需要下載並更新好所有從您的位置到目的地的地圖。
[routing_not_enough_space]
comment = Text for routing error dialog
tags = android
en = Not enough space
af = Nie genoeg spasie nie
ar = لا يوجد مساحة كافية
az = Kifayət qədər yer yoxdur
be = Не хапае месца
bg = Недостатъчно място
ca = No hi ha prou espai
cs = Nedostatek místa
da = Ikke nok plads
de = Nicht genügend Speicherplatz
el = Δεν υπάρχει αρκετός χώρος
es = No hay suficiente espacio
et = Ei ole piisavalt ruumi
eu = Leku nahikorik ez
fa = فضای کافی موجود نیست
fi = Ei tarpeeksi tilaa
fr = Pas assez d'espace
he = אין מספיק מקום
hu = Nincs elég hely
id = Ruang simpan tidak cukup
it = Spazio insufficiente
ja = 空き容量が足りません
ko = 여유 공간 부족
lt = Nepakanka vietos
lv = Trūkst vietas
mr = पुरेशी जागा नाही
nb = Ikke nok ledig minne
nl = Niet genoeg ruimte
pl = Brak wolnego miejsca
pt = Espaço insuficiente
pt-BR = Espaço insuficiente
ro = Spațiu insuficient
ru = Недостаточно места
sk = Nedostatok miesta
sr = Нема довољно простора
sv = För lite utrymme kvar
th = มีพื้นที่ไม่เพียงพอ
tr = Yeterli alan yok
uk = Недостатньо місця
vi = Không đủ không gian
zh-Hans = 空间不足
zh-Hant = 空間不足
[bookmark]
comment = bookmark button text
tags = ios
@ -29963,181 +29490,6 @@
zh-Hans = 正在下载
zh-Hant = 正在下載
[download_map_title]
tags = android
en = Download the world map
af = Laai die wêreldkaart af
ar = تنزيل خريطة العالم
az = Dünya xəritəsini yükləyin
be = Спампаваць мапу света
bg = Изтегляне на картата на света
ca = Baixa el mapa mundial
cs = Stáhnout mapu světa
de = Herunterladen der Weltkarte
el = Κατέβασμα παγκόσμιου χάρτη
es = Descarga el mapa mundial
et = Maailma kaardi allalaadimine
eu = Deskargatu munduko mapa
fi = Lataa maailmankartta
fr = Télécharger la carte du monde
he = הורד את מפת העולם
hi = विश्व मानचित्र डाउनलोड करें
it = Scarica la mappa del mondo
ja = 世界地図をダウンロード
lt = Atsisiųsti pasaulio žemėlapį
lv = Lejupielādēt pasaules karti
mr = जगाचा नकाशा डाउनलोड करा
nb = Last ned verdenskart
nl = Download de wereldkaart
pl = Pobierz mapę świata
pt = Descarregar o mapa mundial
pt-BR = Baixar mapa mundial
ro = Descarcă harta lumii
ru = Скачать карту мира
sk = Stiahnuť mapu sveta
sr = Преузми мапу света
tr = Dünya haritasını indir
uk = Завантажити карту світу
zh-Hans = 下载世界地图
zh-Hant = 下載世界地圖
[disk_error]
tags = android
comment = Used in DownloadResources startup screen
en = Unable to create folder and move files on internal device's memory or sdcard
af = Kan nie vouer skep en lêers op internetoestelgeheue of SD-kaart skuif nie
ar = تعذر إنشاء المجلد ونقل الملفات على الذاكرة الداخلية للجهاز أو على بطاقة SD
az = Qovluq yaratmaq və faylları daxili cihazın yaddaşında və ya SD kartda köçürmək mümkün deyil
ca = No s'ha pogut crear la carpeta ni moure els fitxers a la memòria interna de l'aparell o targeta SD
de = Ordner kann nicht erstellt und Dateien können nicht auf den Gerätespeicher oder die SD-Karte verschoben werden
el = Δεν μπόρεσε να δημιουργηθεί φάκελος και να μεταφερθούν τα αρχεία στην εσωτερική ή εξωτερική μνήμη
es = No se ha podido crear la carpeta y mover los ficheros en la memoria interna del dispositivo o en la tarjeta SD
et = Seadme sisemällu või mälukaardile ei saa kausta luua ja faile teisaldada
eu = Ezin da karpeta sortu eta fitxategiak mugitu barneko gailuaren memorian edo sd txartelan
fi = Kansion luonti ja tiedoston siirto ei onnistu laitteen muistissa tai SD-koritlla
fr = Impossible de créer un dossier et de déplacer les fichiers vers la mémoire interne de l'appareil ou la carte SD
he = לא ניתן ליצור תיקייה ולהעביר קבצים בזיכרון הפנימי או בכרטיס הזיכרון
ja = フォルダーの作成と内部ストレージまたはSDカードへのファイルの移動に失敗しました
lt = Nepavyko sukurti aplanko ir perkelti failus į įrenginio vidinę atmintį ar SD kortelę
lv = Neizdevās izveidot mapi un pārvietot datnes iekšējā atmiņā vai SD kartē
mr = उपकरणाच्या अंतर्गत मेमरी किंवा SD-card वर फोल्डर तयार करण्यात आणि फायली हलविण्यात अक्षम
nb = Klarte ikke opprette mappe og flytte filer i enhetens minne eller SD-kort
nl = Het lukt niet om een map aan te maken en bestanden naar het interne geheugen of een SD-kaart te verplaatsen
pl = Nie udało się stworzyć folderu i przenieść plików do pamięci wewnętrznej lub karty SD
pt-BR = Não foi possível criar a pasta e mover os arquivos à memória interna ou sdcard do dispositivo
ru = Не могу создать папку и переместить файлы на устройстве
sk = Nepodarilo sa vytvoriť priečinok a presunúť súbory do internej pamäte alebo na SD kartu
sr = Не могу да направим фолдер и пременстим фајлове на интерну меморију уређаја или на SD картицу
tr = Dahili aygıtın belleğinde veya SD kartta klasör oluşturulamıyor ve dosyalar taşınamıyor
uk = Неможливо створити папку та перемістити файли до внутрішньої памʼяті або SD карти
zh-Hans = 无法在内部存储或 SD 卡上创建文件夹和移动文件
zh-Hant = 無法在內部儲存或 SD 卡上建立資料夾和移動檔案
[disk_error_title]
tags = android
comment = Used in DownloadResources startup screen
en = Disk error
af = Skyffout
ar = حدث خطأ في التخزين
az = Disk xətası
ca = Error de disc
de = Speicherfehler
el = Σφάλμα δίσκου
es = Error de disco
et = Salvestusseadme viga
eu = Diskoaren akatsa
fi = Tallennusvirhe
fr = Erreur disque
he = שגיאת כונן
hi = डिस्क त्रुटि
ja = ディスクエラー
lt = Disko klaida
lv = Diska kļūda
mr = डिस्क त्रुटी
nb = Diskfeil
nl = Schijffout
pl = Błąd pamięci
pt-BR = Erro do armazenamento
ru = Ошибка диска
sr = Грешка са меморијом
tr = Disk hatası
uk = Помилка диска
zh-Hans = 磁盘错误
zh-Hant = 磁碟錯誤
[connection_failure]
comment = Used in DownloadResources startup screen
tags = android
en = Connection failure
af = Koppelingsfout
ar = فشل الاتصال
az = Əlaqə xətası
be = Памылка падлучэння
bg = Неуспешно свързване
ca = Error de connexió
de = Verbindungsfehler
el = Σφάλμα σύνδεσης
es = Fallo de conexión
et = Ühenduse viga
eu = Konexio arazoa
fi = Yhteysvirhe
fr = Erreur de connexion
he = כשל חיבור
it = Errore di connessione
ja = 接続エラー
lt = Tinklo klaida
lv = Savienojuma kļūda
mr = जोडणी अयशस्वी
nb = Tilkoblingsfeil
nl = Verbindingsfout
pl = Błąd połączenia
pt = Falha na coneção
pt-BR = Falha na coneção
ro = Eroare de conectare
ru = Ошибка подключения
sk = Chyba spojenia
sr = Повезивање није успело
tr = Bağlantı hatası
uk = Помилка підключення
zh-Hans = 磁盘错误
zh-Hant = 磁碟錯誤
[disconnect_usb_cable_title]
comment = Used in DownloadResources startup screen
tags = android
en = Disconnect USB cable
af = Ontkoppel USB-kabel
ar = إفصل سلك USB
az = USB kabelini ayırın
be = Адлучыце USB кабель
bg = Изключване на USB кабел
ca = Desconnecteu el cable USB
de = USB-Kabel trennen
el = Αποσυνδέστε το καλώδιο USB
es = Desconecte el cable USB
et = Ühenda USB kaabel lahti
eu = Deskonektatu USB kablea
fi = Irrota USB-kaapeli
fr = Déconnectez le câble USB
he = נתק כבל USB
it = Scollegare il cavo USB
ja = USBケーブルを抜いてください
lt = Atjungti USB laidą
lv = Atvienojiet USB kabeli
mr = USB केबल काढा
nb = Fjern USB-kabelen
nl = USB-kabel losmaken
pl = Odłącz kabel USB
pt-BR = Desconecte o cabo USB
ro = Deconectează cablul USB
ru = Отсоедините USB кабель
sk = Odpojte USB kábel
sr = Откачите USB кабл
tr = USB kablosunu çıkarın
uk = Від'єднайте кабель USB
zh-Hans = 断开 USB 线缆
zh-Hant = 斷開 USB 線路
[enable_keep_screen_on]
tags = android
en = Keep the screen on