diff --git a/android/src/com/mapswithme/maps/settings/StorageItem.java b/android/src/com/mapswithme/maps/settings/StorageItem.java index fa80f6f655..9c1dd3a3a5 100644 --- a/android/src/com/mapswithme/maps/settings/StorageItem.java +++ b/android/src/com/mapswithme/maps/settings/StorageItem.java @@ -5,16 +5,11 @@ package com.mapswithme.maps.settings; */ public class StorageItem { - // Path to the root of writable directory. - private final String mPath; - // Free size. - private final long mFreeSize; - // Total size. - private final long mTotalSize; - // User-visible description. - private final String mLabel; - // Is it read-only storage? - private final boolean mReadonly; + public final String mPath; + public final long mFreeSize; + public final long mTotalSize; + public final String mLabel; + public final boolean mIsReadonly; public StorageItem(String path, long freeSize, long totalSize, final String label, boolean isReadonly) { @@ -22,7 +17,7 @@ public class StorageItem mFreeSize = freeSize; mTotalSize = totalSize; mLabel = label; - mReadonly = isReadonly; + mIsReadonly = isReadonly; } @Override @@ -33,9 +28,7 @@ public class StorageItem if (o == null || !(o instanceof StorageItem)) return false; StorageItem other = (StorageItem) o; - // Storage equal is considered equal, either its path OR size equals to another one's. - // Size of storage free space can change dynamically, so that hack provides us with better results identifying the same storages. - return mFreeSize == other.getFreeSize() || mPath.equals(other.getFullPath()); + return mPath.equals(other.mPath); } @Override @@ -45,29 +38,4 @@ public class StorageItem // At least such hash is compatible with hacky equals. return 0; } - - public String getFullPath() - { - return mPath; - } - - public long getFreeSize() - { - return mFreeSize; - } - - public long getTotalSize() - { - return mTotalSize; - } - - public String getLabel() - { - return mLabel; - } - - public boolean isReadonly() - { - return mReadonly; - } } diff --git a/android/src/com/mapswithme/maps/settings/StoragePathAdapter.java b/android/src/com/mapswithme/maps/settings/StoragePathAdapter.java index 8381c6fd31..6b934343bc 100644 --- a/android/src/com/mapswithme/maps/settings/StoragePathAdapter.java +++ b/android/src/com/mapswithme/maps/settings/StoragePathAdapter.java @@ -30,13 +30,13 @@ class StoragePathAdapter extends BaseAdapter @Override public int getCount() { - return (mPathManager.getStorageItems() == null ? 0 : mPathManager.getStorageItems().size()); + return (mPathManager.mStorages == null ? 0 : mPathManager.mStorages.size()); } @Override public StorageItem getItem(int position) { - return mPathManager.getStorageItems().get(position); + return mPathManager.mStorages.get(position); } @Override @@ -51,23 +51,23 @@ class StoragePathAdapter extends BaseAdapter if (convertView == null) convertView = mActivity.getLayoutInflater().inflate(R.layout.item_storage, parent, false); - StorageItem item = mPathManager.getStorageItems().get(position); - final boolean isCurrent = position == mPathManager.getCurrentStorageIndex(); + StorageItem item = mPathManager.mStorages.get(position); + final boolean isCurrent = position == mPathManager.mCurrentStorageIndex; CheckedTextView checkedView = (CheckedTextView) convertView; checkedView.setChecked(isCurrent); - checkedView.setEnabled(!item.isReadonly() && (isStorageBigEnough(position) || isCurrent)); + checkedView.setEnabled(!item.mIsReadonly && (isStorageBigEnough(position) || isCurrent)); final String size = mActivity.getString(R.string.maps_storage_free_size, - Formatter.formatShortFileSize(mActivity, item.getFreeSize()), - Formatter.formatShortFileSize(mActivity, item.getTotalSize())); + Formatter.formatShortFileSize(mActivity, item.mFreeSize), + Formatter.formatShortFileSize(mActivity, item.mTotalSize)); - SpannableStringBuilder sb = new SpannableStringBuilder(item.getLabel() + "\n" + size); + SpannableStringBuilder sb = new SpannableStringBuilder(item.mLabel + "\n" + size); sb.setSpan(new ForegroundColorSpan(ThemeUtils.getColor(mActivity, android.R.attr.textColorSecondary)), sb.length() - size.length(), sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); sb.setSpan(new AbsoluteSizeSpan(UiUtils.dimen(mActivity, R.dimen.text_size_body_3)), sb.length() - size.length(), sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - final String path = item.getFullPath() + (item.isReadonly() ? " (read-only)" : ""); + final String path = item.mPath + (item.mIsReadonly ? " (read-only)" : ""); sb.append("\n" + path); sb.setSpan(new ForegroundColorSpan(ThemeUtils.getColor(mActivity, android.R.attr.textColorSecondary)), sb.length() - path.length(), sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); @@ -87,6 +87,6 @@ class StoragePathAdapter extends BaseAdapter public boolean isStorageBigEnough(int index) { - return mPathManager.getStorageItems().get(index).getFreeSize() >= mSizeNeeded; + return mPathManager.mStorages.get(index).mFreeSize >= mSizeNeeded; } } diff --git a/android/src/com/mapswithme/maps/settings/StoragePathFragment.java b/android/src/com/mapswithme/maps/settings/StoragePathFragment.java index a9193d71d4..8eb1da8125 100644 --- a/android/src/com/mapswithme/maps/settings/StoragePathFragment.java +++ b/android/src/com/mapswithme/maps/settings/StoragePathFragment.java @@ -2,13 +2,12 @@ package com.mapswithme.maps.settings; import android.app.ProgressDialog; import android.os.Bundle; +import android.text.format.Formatter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.CheckedTextView; import android.widget.ListView; import android.widget.TextView; -import android.text.format.Formatter; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; @@ -99,14 +98,14 @@ public class StoragePathFragment extends BaseSettingsFragment */ public void changeStorage(int newIndex) { - final int currentIndex = mPathManager.getCurrentStorageIndex(); - final List items = mPathManager.getStorageItems(); - if (newIndex == currentIndex || currentIndex == -1 || items.get(newIndex).isReadonly() + final int currentIndex = mPathManager.mCurrentStorageIndex; + final List storages = mPathManager.mStorages; + if (newIndex == currentIndex || currentIndex == -1 || storages.get(newIndex).mIsReadonly || !mAdapter.isStorageBigEnough(newIndex)) return; - final String oldPath = items.get(currentIndex).getFullPath(); - final String newPath = items.get(newIndex).getFullPath(); + final String oldPath = storages.get(currentIndex).mPath; + final String newPath = storages.get(newIndex).mPath; new AlertDialog.Builder(requireActivity()) .setCancelable(false) @@ -125,27 +124,25 @@ public class StoragePathFragment extends BaseSettingsFragment final ProgressDialog dialog = DialogUtils.createModalProgressDialog(requireActivity(), R.string.wait_several_minutes); dialog.show(); - ThreadPool.getStorage().execute(() -> - { - final boolean result = mPathManager.moveStorage(newPath, oldPath); + ThreadPool.getStorage().execute(() -> { + final boolean result = mPathManager.moveStorage(newPath, oldPath); - UiThread.run(() -> - { - if (dialog.isShowing()) - dialog.dismiss(); + UiThread.run(() -> { + if (dialog.isShowing()) + dialog.dismiss(); - if (!result) - { - new AlertDialog.Builder(requireActivity()) - .setTitle(R.string.move_maps_error) - .setPositiveButton(R.string.report_a_bug, - (dlg, which) -> Utils.sendBugReport(requireActivity(), "Error moving map files")) - .show(); - } - mPathManager.scanAvailableStorages(); - updateList(); - }); + if (!result) + { + new AlertDialog.Builder(requireActivity()) + .setTitle(R.string.move_maps_error) + .setPositiveButton(R.string.report_a_bug, + (dlg, which) -> Utils.sendBugReport(requireActivity(), "Error moving map files")) + .show(); + } + mPathManager.scanAvailableStorages(); + updateList(); }); + }); } @Override diff --git a/android/src/com/mapswithme/maps/settings/StoragePathManager.java b/android/src/com/mapswithme/maps/settings/StoragePathManager.java index fe83dd8a00..b47b943b25 100644 --- a/android/src/com/mapswithme/maps/settings/StoragePathManager.java +++ b/android/src/com/mapswithme/maps/settings/StoragePathManager.java @@ -33,8 +33,7 @@ public class StoragePathManager static final String TAG = StoragePathManager.class.getName(); private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.STORAGE); private static final String[] MOVABLE_EXTS = Framework.nativeGetMovableFilesExts(); - static final FilenameFilter MOVABLE_FILES_FILTER = (dir, filename) -> - { + static final FilenameFilter MOVABLE_FILES_FILTER = (dir, filename) -> { for (String ext : MOVABLE_EXTS) if (filename.endsWith(ext)) return true; @@ -50,8 +49,9 @@ public class StoragePathManager private OnStorageListChangedListener mStoragesChangedListener; private BroadcastReceiver mInternalReceiver; private Context mContext; - private final List mItems = new ArrayList<>(); - private int mCurrentStorageIndex = -1; + + public final List mStorages = new ArrayList<>(); + public int mCurrentStorageIndex = -1; public StoragePathManager(@NonNull Context context) { @@ -81,7 +81,7 @@ public class StoragePathManager scanAvailableStorages(); if (mStoragesChangedListener != null) - mStoragesChangedListener.onStorageListChanged(mItems, mCurrentStorageIndex); + mStoragesChangedListener.onStorageListChanged(mStorages, mCurrentStorageIndex); } }; @@ -115,16 +115,6 @@ public class StoragePathManager } } - public List getStorageItems() - { - return mItems; - } - - public int getCurrentStorageIndex() - { - return mCurrentStorageIndex; - } - /** * Adds a storage into the list if it passes sanity checks. */ @@ -239,10 +229,10 @@ public class StoragePathManager : (isEmulated ? mContext.getString(R.string.maps_storage_shared) : mContext.getString(R.string.maps_storage_external))); - StorageItem item = new StorageItem(path, freeSize, totalSize, label, isReadonly); - mItems.add(item); + StorageItem storage = new StorageItem(path, freeSize, totalSize, label, isReadonly); + mStorages.add(storage); if (isCurrent) - mCurrentStorageIndex = mItems.size() - 1; + mCurrentStorageIndex = mStorages.size() - 1; LOGGER.i(TAG, "Accepted " + commentedPath); } catch (SecurityException | IOException ex) @@ -264,7 +254,7 @@ public class StoragePathManager LOGGER.i(TAG, "Currently configured storage: " + (TextUtils.isEmpty(configPath) ? "N/A" : configPath)); LOGGER.i(TAG, "Begin scanning storages"); - mItems.clear(); + mStorages.clear(); mCurrentStorageIndex = -1; // External storages (SD cards and other). @@ -278,7 +268,7 @@ public class StoragePathManager LOGGER.i(TAG, "End scanning storages"); - if (mItems.isEmpty()) + if (mStorages.isEmpty()) // Shut down the app. throw new AssertionError("Can't find available storages"); @@ -301,26 +291,25 @@ public class StoragePathManager private static boolean containsMapData(String storagePath) { File path = new File(storagePath); - File[] candidates = path.listFiles((pathname) -> + File[] candidates = path.listFiles((pathname) -> { + if (!pathname.isDirectory()) + return false; + + try { - if (!pathname.isDirectory()) - return false; + String name = pathname.getName(); + if (name.length() != 6) + return false; - try - { - String name = pathname.getName(); - if (name.length() != 6) - return false; + int version = Integer.valueOf(name); + return (version > 120000 && version <= 999999); + } + catch (NumberFormatException ignored) + { + } - int version = Integer.valueOf(name); - return (version > 120000 && version <= 999999); - } - catch (NumberFormatException ignored) - { - } - - return false; - }); + return false; + }); return (candidates != null && candidates.length > 0 && candidates[0].list().length > 0); @@ -337,11 +326,12 @@ public class StoragePathManager StoragePathManager mgr = new StoragePathManager(application); mgr.scanAvailableStorages(); String path = null; - final int currentIdx = mgr.getCurrentStorageIndex(); + final List storages = mgr.mStorages; + final int currentIdx = mgr.mCurrentStorageIndex; if (currentIdx != -1) { - path = mgr.getStorageItems().get(currentIdx).getFullPath(); + path = storages.get(currentIdx).mPath; if (containsMapData(path)) { LOGGER.i(TAG, "Found map files at the currently configured " + path); @@ -354,11 +344,11 @@ public class StoragePathManager } LOGGER.i(TAG, "Looking for map files in available storages..."); - for (int idx = 0; idx < mgr.getStorageItems().size(); ++idx) + for (int idx = 0; idx < storages.size(); ++idx) { if (idx == currentIdx) continue; - path = mgr.getStorageItems().get(idx).getFullPath(); + path = storages.get(idx).mPath; if (containsMapData(path)) { LOGGER.i(TAG, "Found map files at " + path); @@ -371,7 +361,7 @@ public class StoragePathManager } // Use the first storage by default. - path = mgr.getStorageItems().get(0).getFullPath(); + path = storages.get(0).mPath; LOGGER.i(TAG, "Using default storage: " + path); return path; } diff --git a/data/strings/strings.txt b/data/strings/strings.txt index 03213649d8..74caee4832 100644 --- a/data/strings/strings.txt +++ b/data/strings/strings.txt @@ -1838,9 +1838,10 @@ [maps_storage_internal] comment = Internal storage type in Maps Storage settings (not accessible by the user) tags = android - en = Internal hidden storage + en = Internal private storage + be = Унутранае прыватнае сховішча ru = Внутренний скрытый накопитель - uk = Внутрішнє зховане сховище + uk = Внутрішнє приватне сховище [maps_storage_shared] comment = Shared storage type in Maps Storage settings (a primary storage usually) @@ -1862,14 +1863,17 @@ comment = Generic external storage type in Maps Storage settings tags = android en = External shared storage + be = Знешняе абагульнае сховішча ru = Внешний общий накопитель uk = Зовнiшне спільне сховище [maps_storage_free_size] - comment = Free space out of total storage size in Maps Storage settings, e.g. "300 MB free (of 2 GB)" + comment = Free space out of total storage size in Maps Storage settings, e.g. "300 MB free of 2 GB" tags = android - en = %1$@ free (of %2$@) - ru = %1$@ свободно (из %2$@) + en = %1$@ free of %2$@ + be = %1$@ вольна з %2$@ + ru = %1$@ свободно из %2$@ + uk = %1$@ вільно з %2$@ [move_maps] comment = Question dialog for transferring maps from one storage to another