Refactor custom downloads first part

This commit is contained in:
Vitaliy 2020-04-20 22:40:46 +03:00
parent 2967b8f140
commit bc15dcb8b1
7 changed files with 568 additions and 538 deletions

View file

@ -1,6 +1,7 @@
package net.osmand.plus;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@ -15,7 +16,6 @@ import net.osmand.map.ITileSource;
import net.osmand.map.TileSourceManager;
import net.osmand.map.WorldRegion;
import net.osmand.plus.SettingsHelper.AvoidRoadsSettingsItem;
import net.osmand.plus.SettingsHelper.CustomRegion;
import net.osmand.plus.SettingsHelper.MapSourcesSettingsItem;
import net.osmand.plus.SettingsHelper.PluginSettingsItem;
import net.osmand.plus.SettingsHelper.PoiUiFilterSettingsItem;
@ -66,7 +66,7 @@ public class CustomOsmandPlugin extends OsmandPlugin {
private List<String> rendererNames = new ArrayList<>();
private List<String> routerNames = new ArrayList<>();
private List<SuggestedDownloadItem> suggestedDownloadItems = new ArrayList<>();
private List<CustomRegion> customRegions = new ArrayList<>();
private List<WorldRegion> customRegions = new ArrayList<>();
public CustomOsmandPlugin(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
super(app);
@ -76,6 +76,25 @@ public class CustomOsmandPlugin extends OsmandPlugin {
loadResources();
}
@Override
public String getId() {
return pluginId;
}
@Override
public String getName() {
return getLocalizedResFromMap(app, names, app.getString(R.string.custom_osmand_plugin));
}
@Override
public String getDescription() {
return getLocalizedResFromMap(app, descriptions, null);
}
public String getResourceDirName() {
return resourceDirName;
}
@Override
public boolean init(@NonNull OsmandApplication app, @Nullable Activity activity) {
super.init(app, activity);
@ -89,6 +108,108 @@ public class CustomOsmandPlugin extends OsmandPlugin {
return true;
}
@Override
public void disable(OsmandApplication app) {
super.disable(app);
removePluginItems(null);
}
public File getPluginDir() {
return app.getAppPath(IndexConstants.PLUGINS_DIR + pluginId);
}
public File getPluginItemsFile() {
return new File(getPluginDir(), "items" + IndexConstants.OSMAND_SETTINGS_FILE_EXT);
}
public File getPluginResDir() {
File pluginDir = getPluginDir();
if (!Algorithms.isEmpty(resourceDirName)) {
return new File(pluginDir, resourceDirName);
}
return pluginDir;
}
@Override
public List<String> getRendererNames() {
return rendererNames;
}
@Override
public List<String> getRouterNames() {
return routerNames;
}
private Drawable getIconForFile(String path, Map<String, String> fileNames) {
for (Map.Entry<String, String> entry : fileNames.entrySet()) {
String value = entry.getValue();
if (value.startsWith("@")) {
value = value.substring(1);
}
if (path.endsWith(value)) {
return BitmapDrawable.createFromPath(path);
}
}
return null;
}
@NonNull
@Override
public Drawable getLogoResource() {
return icon != null ? icon : super.getLogoResource();
}
@Override
public Drawable getAssetResourceImage() {
return image;
}
@Override
public List<WorldRegion> getDownloadMaps() {
return customRegions;
}
@Override
public List<IndexItem> getSuggestedMaps() {
List<IndexItem> suggestedMaps = new ArrayList<>();
DownloadIndexesThread downloadThread = app.getDownloadThread();
if (!downloadThread.getIndexes().isDownloadedFromInternet && app.getSettings().isInternetConnectionAvailable()) {
downloadThread.runReloadIndexFiles();
}
boolean downloadIndexes = app.getSettings().isInternetConnectionAvailable()
&& !downloadThread.getIndexes().isDownloadedFromInternet
&& !downloadThread.getIndexes().downloadFromInternetFailed;
if (!downloadIndexes) {
for (SuggestedDownloadItem item : suggestedDownloadItems) {
DownloadActivityType type = DownloadActivityType.getIndexType(item.scopeId);
if (type != null) {
List<IndexItem> foundMaps = new ArrayList<>();
String searchType = item.getSearchType();
if ("latlon".equalsIgnoreCase(searchType)) {
LatLon latLon = app.getMapViewTrackingUtilities().getMapLocation();
foundMaps.addAll(getMapsForType(latLon, type));
} else if ("worldregion".equalsIgnoreCase(searchType)) {
LatLon latLon = app.getMapViewTrackingUtilities().getMapLocation();
foundMaps.addAll(getMapsForType(latLon, type));
}
if (!Algorithms.isEmpty(item.getNames())) {
foundMaps.addAll(getMapsForType(item.getNames(), type, item.getLimit()));
}
suggestedMaps.addAll(foundMaps);
}
}
}
return suggestedMaps;
}
public void setResourceDirName(String resourceDirName) {
this.resourceDirName = resourceDirName;
}
private void addPluginItemsFromFile(final File file) {
app.getSettingsHelper().collectSettings(file, "", 1, new SettingsCollectListener() {
@Override
@ -188,129 +309,23 @@ public class CustomOsmandPlugin extends OsmandPlugin {
});
}
@Override
public void disable(OsmandApplication app) {
super.disable(app);
removePluginItems(null);
}
public File getPluginDir() {
return app.getAppPath(IndexConstants.PLUGINS_DIR + pluginId);
}
public File getPluginItemsFile() {
return new File(getPluginDir(), "items" + IndexConstants.OSMAND_SETTINGS_FILE_EXT);
}
public File getPluginResDir() {
File pluginDir = getPluginDir();
if (!Algorithms.isEmpty(resourceDirName)) {
return new File(pluginDir, resourceDirName);
}
return pluginDir;
}
@Override
public String getId() {
return pluginId;
}
@Override
public String getName() {
Configuration config = app.getResources().getConfiguration();
String lang = config.locale.getLanguage();
String name = names.get(lang);
if (Algorithms.isEmpty(name)) {
name = names.get("");
}
if (Algorithms.isEmpty(name)) {
name = app.getString(R.string.custom_osmand_plugin);
}
return name;
}
@Override
public String getDescription() {
Configuration config = app.getResources().getConfiguration();
String lang = config.locale.getLanguage();
String description = descriptions.get(lang);
if (Algorithms.isEmpty(description)) {
description = descriptions.get("");
}
return description;
}
public String getResourceDirName() {
return resourceDirName;
}
public void setResourceDirName(String resourceDirName) {
this.resourceDirName = resourceDirName;
}
public void readAdditionalDataFromJson(JSONObject json) throws JSONException {
JSONObject iconJson = json.has("icon") ? json.getJSONObject("icon") : null;
if (iconJson != null) {
for (Iterator<String> it = iconJson.keys(); it.hasNext(); ) {
String iconKey = it.next();
String name = iconJson.getString(iconKey);
iconNames.put(iconKey, name);
}
}
JSONObject imageJson = json.has("image") ? json.getJSONObject("image") : null;
if (imageJson != null) {
for (Iterator<String> it = imageJson.keys(); it.hasNext(); ) {
String imageKey = it.next();
String name = imageJson.getString(imageKey);
imageNames.put(imageKey, name);
}
}
JSONObject nameJson = json.has("name") ? json.getJSONObject("name") : null;
if (nameJson != null) {
for (Iterator<String> it = nameJson.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = nameJson.getString(localeKey);
names.put(localeKey, name);
}
}
JSONObject descriptionJson = json.has("description") ? json.getJSONObject("description") : null;
if (descriptionJson != null) {
for (Iterator<String> it = descriptionJson.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = descriptionJson.getString(localeKey);
descriptions.put(localeKey, name);
}
}
JSONArray regionsJson = json.has("regionsJson") ? json.getJSONArray("regionsJson") : null;
iconNames = getLocalizedMapFromJson("icon", json);
imageNames = getLocalizedMapFromJson("image", json);
names = getLocalizedMapFromJson("name", json);
descriptions = getLocalizedMapFromJson("description", json);
JSONArray regionsJson = json.optJSONArray("regionsJson");
if (regionsJson != null) {
customRegions.addAll(collectRegionsFromJson(regionsJson));
}
}
public void writeAdditionalDataToJson(JSONObject json) throws JSONException {
JSONObject iconJson = new JSONObject();
for (Map.Entry<String, String> entry : iconNames.entrySet()) {
iconJson.put(entry.getKey(), entry.getValue());
}
json.put("icon", iconJson);
JSONObject imageJson = new JSONObject();
for (Map.Entry<String, String> entry : imageNames.entrySet()) {
imageJson.put(entry.getKey(), entry.getValue());
}
json.put("image", imageJson);
JSONObject nameJson = new JSONObject();
for (Map.Entry<String, String> entry : names.entrySet()) {
nameJson.put(entry.getKey(), entry.getValue());
}
json.put("name", nameJson);
JSONObject descriptionJson = new JSONObject();
for (Map.Entry<String, String> entry : descriptions.entrySet()) {
descriptionJson.put(entry.getKey(), entry.getValue());
}
json.put("description", descriptionJson);
writeLocalizedMapToJson("icon", json, iconNames);
writeLocalizedMapToJson("image", json, imageNames);
writeLocalizedMapToJson("name", json, names);
writeLocalizedMapToJson("description", json, descriptions);
JSONArray regionsJson = new JSONArray();
for (WorldRegion region : getFlatCustomRegions()) {
@ -322,9 +337,8 @@ public class CustomOsmandPlugin extends OsmandPlugin {
}
private List<WorldRegion> getFlatCustomRegions() {
List<WorldRegion> l = new ArrayList<>();
List<WorldRegion> l = new ArrayList<>(customRegions);
for (WorldRegion region : customRegions) {
l.add(region);
collectCustomSubregionsFromRegion(region, l);
}
return l;
@ -333,70 +347,24 @@ public class CustomOsmandPlugin extends OsmandPlugin {
private void collectCustomSubregionsFromRegion(WorldRegion region, List<WorldRegion> items) {
items.addAll(region.getSubregions());
for (WorldRegion subregion : region.getSubregions()) {
if (subregion instanceof CustomRegion) {
collectCustomSubregionsFromRegion(subregion, items);
}
collectCustomSubregionsFromRegion(subregion, items);
}
}
public void readDependentFilesFromJson(JSONObject json) throws JSONException {
JSONArray rendererNamesJson = json.has("rendererNames") ? json.getJSONArray("rendererNames") : null;
if (rendererNamesJson != null) {
for (int i = 0; i < rendererNamesJson.length(); i++) {
String renderer = rendererNamesJson.getString(i);
rendererNames.add(renderer);
}
}
JSONArray routerNamesJson = json.has("routerNames") ? json.getJSONArray("routerNames") : null;
if (routerNamesJson != null) {
for (int i = 0; i < routerNamesJson.length(); i++) {
String renderer = routerNamesJson.getString(i);
routerNames.add(renderer);
}
}
JSONObject iconNamesJson = json.has("iconNames") ? json.getJSONObject("iconNames") : null;
if (iconNamesJson != null) {
for (Iterator<String> it = iconNamesJson.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = iconNamesJson.getString(localeKey);
iconNames.put(localeKey, name);
}
}
JSONObject imageNamesJson = json.has("imageNames") ? json.getJSONObject("imageNames") : null;
if (imageNamesJson != null) {
for (Iterator<String> it = imageNamesJson.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = imageNamesJson.getString(localeKey);
imageNames.put(localeKey, name);
}
}
resourceDirName = json.has("pluginResDir") ? json.getString("pluginResDir") : null;
rendererNames = jsonArrayToList("rendererNames", json);
routerNames = jsonArrayToList("routerNames", json);
iconNames = getLocalizedMapFromJson("iconNames", json);
imageNames = getLocalizedMapFromJson("imageNames", json);
resourceDirName = json.optString("pluginResDir");
}
public void writeDependentFilesJson(JSONObject json) throws JSONException {
JSONArray rendererNamesJson = new JSONArray();
for (String render : rendererNames) {
rendererNamesJson.put(render);
}
json.put("rendererNames", rendererNamesJson);
writeStringListToJson("rendererNames", json, rendererNames);
writeStringListToJson("routerNames", json, routerNames);
JSONArray routerNamesJson = new JSONArray();
for (String render : routerNames) {
routerNamesJson.put(render);
}
json.put("routerNames", routerNamesJson);
JSONObject iconNamesJson = new JSONObject();
for (Map.Entry<String, String> entry : iconNames.entrySet()) {
iconNamesJson.put(entry.getKey(), entry.getValue());
}
json.put("iconNames", iconNamesJson);
JSONObject imageNamesJson = new JSONObject();
for (Map.Entry<String, String> entry : imageNames.entrySet()) {
imageNamesJson.put(entry.getKey(), entry.getValue());
}
json.put("imageNames", imageNamesJson);
writeLocalizedMapToJson("iconNames", json, iconNames);
writeLocalizedMapToJson("imageNames", json, imageNames);
json.put("pluginResDir", resourceDirName);
}
@ -407,11 +375,11 @@ public class CustomOsmandPlugin extends OsmandPlugin {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject regionJson = jsonArray.getJSONObject(i);
CustomRegion region = CustomRegion.fromJson(regionJson);
flatRegions.put(region.path, region);
flatRegions.put(region.getPath(), region);
}
for (CustomRegion region : flatRegions.values()) {
if (!Algorithms.isEmpty(region.parentPath)) {
CustomRegion parentReg = flatRegions.get(region.parentPath);
if (!Algorithms.isEmpty(region.getParentPath())) {
CustomRegion parentReg = flatRegions.get(region.getParentPath());
if (parentReg != null) {
parentReg.addSubregion(region);
}
@ -422,16 +390,6 @@ public class CustomOsmandPlugin extends OsmandPlugin {
return customRegions;
}
@Override
public List<String> getRendererNames() {
return rendererNames;
}
@Override
public List<String> getRouterNames() {
return routerNames;
}
public void addRouter(String fileName) {
String routerName = Algorithms.getFileWithoutDirs(fileName);
if (!routerNames.contains(routerName)) {
@ -462,80 +420,14 @@ public class CustomOsmandPlugin extends OsmandPlugin {
}
}
private Drawable getIconForFile(String path, Map<String, String> fileNames) {
for (Map.Entry<String, String> entry : fileNames.entrySet()) {
String value = entry.getValue();
if (value.startsWith("@")) {
value = value.substring(1);
}
if (path.endsWith(value)) {
return BitmapDrawable.createFromPath(path);
}
}
return null;
}
@NonNull
@Override
public Drawable getLogoResource() {
return icon != null ? icon : super.getLogoResource();
}
@Override
public Drawable getAssetResourceImage() {
return image;
}
public void updateSuggestedDownloads(List<SuggestedDownloadItem> items) {
suggestedDownloadItems = new ArrayList<>(items);
}
public void updateDownloadItems(List<CustomRegion> items) {
public void updateDownloadItems(List<WorldRegion> items) {
customRegions = new ArrayList<>(items);
}
@Override
public List<CustomRegion> getDownloadMaps() {
return customRegions;
}
@Override
public List<IndexItem> getSuggestedMaps() {
List<IndexItem> suggestedMaps = new ArrayList<>();
DownloadIndexesThread downloadThread = app.getDownloadThread();
if (!downloadThread.getIndexes().isDownloadedFromInternet && app.getSettings().isInternetConnectionAvailable()) {
downloadThread.runReloadIndexFiles();
}
boolean downloadIndexes = app.getSettings().isInternetConnectionAvailable()
&& !downloadThread.getIndexes().isDownloadedFromInternet
&& !downloadThread.getIndexes().downloadFromInternetFailed;
if (!downloadIndexes) {
for (SuggestedDownloadItem item : suggestedDownloadItems) {
DownloadActivityType type = DownloadActivityType.getIndexType(item.scopeId);
if (type != null) {
List<IndexItem> foundMaps = new ArrayList<>();
String searchType = item.getSearchType();
if ("latlon".equalsIgnoreCase(searchType)) {
LatLon latLon = app.getMapViewTrackingUtilities().getMapLocation();
foundMaps.addAll(getMapsForType(latLon, type));
} else if ("worldregion".equalsIgnoreCase(searchType)) {
LatLon latLon = app.getMapViewTrackingUtilities().getMapLocation();
foundMaps.addAll(getMapsForType(latLon, type));
}
if (!Algorithms.isEmpty(item.getNames())) {
foundMaps.addAll(getMapsForType(item.getNames(), type, item.getLimit()));
}
suggestedMaps.addAll(foundMaps);
}
}
}
return suggestedMaps;
}
private List<IndexItem> getMapsForType(LatLon latLon, DownloadActivityType type) {
try {
return DownloadResources.findIndexItemsAt(app, latLon, type);
@ -549,6 +441,65 @@ public class CustomOsmandPlugin extends OsmandPlugin {
return DownloadResources.findIndexItemsAt(app, names, type, false, limit);
}
public static String getLocalizedResFromMap(Context ctx, Map<String, String> localizedMap, String defVal) {
if (!Algorithms.isEmpty(localizedMap)) {
Configuration config = ctx.getResources().getConfiguration();
String lang = config.locale.getLanguage();
String name = localizedMap.get(lang);
if (Algorithms.isEmpty(name)) {
name = localizedMap.get("");
}
if (!Algorithms.isEmpty(name)) {
return name;
}
}
return defVal;
}
public static List<String> jsonArrayToList(String key, JSONObject json) throws JSONException {
List<String> items = new ArrayList<>();
JSONArray jsonArray = json.optJSONArray(key);
if (jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
items.add(jsonArray.getString(i));
}
}
return items;
}
public static Map<String, String> getLocalizedMapFromJson(String key, JSONObject json) throws JSONException {
Map<String, String> localizedMap = new HashMap<>();
JSONObject jsonObject = json.optJSONObject(key);
if (jsonObject != null) {
for (Iterator<String> it = jsonObject.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = jsonObject.getString(localeKey);
localizedMap.put(localeKey, name);
}
}
return localizedMap;
}
public static void writeStringListToJson(String key, JSONObject json, List<String> items) throws JSONException {
if (!Algorithms.isEmpty(items)) {
JSONArray jsonArray = new JSONArray();
for (String render : items) {
jsonArray.put(render);
}
json.put(key, jsonArray);
}
}
public static void writeLocalizedMapToJson(String jsonKey, JSONObject json, Map<String, String> map) throws JSONException {
if (!Algorithms.isEmpty(map)) {
JSONObject jsonObject = new JSONObject();
for (Map.Entry<String, String> entry : map.entrySet()) {
jsonObject.put(entry.getKey(), entry.getValue());
}
json.put(jsonKey, jsonObject);
}
}
public interface PluginItemsListener {
void onItemsRemoved();

View file

@ -0,0 +1,172 @@
package net.osmand.plus;
import androidx.annotation.ColorInt;
import net.osmand.PlatformUtil;
import net.osmand.map.WorldRegion;
import net.osmand.plus.download.CustomIndexItem;
import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.IndexItem;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CustomRegion extends WorldRegion {
private static final Log LOG = PlatformUtil.getLog(CustomRegion.class);
private String scopeId;
private String path;
private String parentPath;
private String type;
private String subfolder;
private String headerButton;
private JSONArray downloadItemsJson;
private Map<String, String> names = new HashMap<>();
private Map<String, String> icons = new HashMap<>();
private Map<String, String> headers = new HashMap<>();
private int headerColor = -1;
private CustomRegion(String scopeId, String path, String type) {
super(path, null);
this.scopeId = scopeId;
this.path = path;
this.type = type;
}
public String getScopeId() {
return scopeId;
}
public String getPath() {
return path;
}
public String getParentPath() {
return parentPath;
}
@ColorInt
public int getHeaderColor() {
return headerColor;
}
public static CustomRegion fromJson(JSONObject object) throws JSONException {
String scopeId = object.optString("scope-id", null);
String path = object.optString("path", null);
String type = object.optString("type", null);
CustomRegion region = new CustomRegion(scopeId, path, type);
region.subfolder = object.optString("subfolder", null);
int index = path.lastIndexOf(File.separator);
if (index != -1) {
region.parentPath = path.substring(0, index);
}
region.names = CustomOsmandPlugin.getLocalizedMapFromJson("name", object);
if (!Algorithms.isEmpty(region.names)) {
region.regionName = region.names.get("");
region.regionNameEn = region.names.get("");
region.regionFullName = region.names.get("");
region.regionNameLocale = region.names.get("");
}
region.icons = CustomOsmandPlugin.getLocalizedMapFromJson("icon", object);
region.headers = CustomOsmandPlugin.getLocalizedMapFromJson("header", object);
region.headerButton = object.optString("header-button", null);
region.downloadItemsJson = object.optJSONArray("items");
String headerColor = object.optString("header-color", null);
try {
region.headerColor = Algorithms.isEmpty(headerColor) ? 0 : Algorithms.parseColor(headerColor);
} catch (IllegalArgumentException e) {
region.headerColor = 0;
}
return region;
}
public List<IndexItem> loadIndexItems() {
List<IndexItem> items = new ArrayList<>();
if (downloadItemsJson != null) {
try {
for (int i = 0; i < downloadItemsJson.length(); i++) {
JSONObject itemJson = downloadItemsJson.getJSONObject(i);
long timestamp = itemJson.optLong("timestamp") * 1000;
long contentSize = itemJson.optLong("contentSize");
long containerSize = itemJson.optLong("containerSize");
String indexType = itemJson.optString("type", type);
String webUrl = itemJson.optString("weburl");
String fileName = itemJson.optString("filename");
String downloadUrl = itemJson.optString("downloadurl");
String size = new DecimalFormat("#.#").format(containerSize / (1024f * 1024f));
List<String> descrImageUrl = CustomOsmandPlugin.jsonArrayToList("image-description-url", itemJson);
Map<String, String> indexNames = CustomOsmandPlugin.getLocalizedMapFromJson("name", itemJson);
Map<String, String> descriptions = CustomOsmandPlugin.getLocalizedMapFromJson("description", itemJson);
Map<String, String> webButtonText = CustomOsmandPlugin.getLocalizedMapFromJson("web-button-text", itemJson);
DownloadActivityType type = DownloadActivityType.getIndexType(indexType);
if (type != null) {
IndexItem indexItem = new CustomIndexItem.CustomIndexItemBuilder()
.setFileName(fileName)
.setSubfolder(subfolder)
.setDownloadUrl(downloadUrl)
.setNames(indexNames)
.setDescriptions(descriptions)
.setImageDescrUrl(descrImageUrl)
.setWebUrl(webUrl)
.setWebButtonText(webButtonText)
.setTimestamp(timestamp)
.setSize(size)
.setContentSize(contentSize)
.setContainerSize(containerSize)
.setType(type)
.create();
items.add(indexItem);
}
}
} catch (JSONException e) {
LOG.error(e);
}
}
return items;
}
public JSONObject toJson() throws JSONException {
JSONObject jsonObject = new JSONObject();
jsonObject.putOpt("scope-id", scopeId);
jsonObject.putOpt("path", path);
jsonObject.putOpt("type", type);
jsonObject.putOpt("subfolder", subfolder);
jsonObject.putOpt("header-button", headerButton);
CustomOsmandPlugin.writeLocalizedMapToJson("name", jsonObject, names);
CustomOsmandPlugin.writeLocalizedMapToJson("icon", jsonObject, icons);
CustomOsmandPlugin.writeLocalizedMapToJson("header", jsonObject, headers);
jsonObject.putOpt("items", downloadItemsJson);
return jsonObject;
}
}

View file

@ -22,7 +22,6 @@ import net.osmand.Location;
import net.osmand.PlatformUtil;
import net.osmand.access.AccessibilityPlugin;
import net.osmand.map.WorldRegion;
import net.osmand.plus.SettingsHelper.CustomRegion;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.TabActivity.TabItem;
import net.osmand.plus.api.SettingsAPI;
@ -184,7 +183,7 @@ public abstract class OsmandPlugin {
return Collections.emptyList();
}
public List<CustomRegion> getDownloadMaps() {
public List<WorldRegion> getDownloadMaps() {
return Collections.emptyList();
}
@ -651,8 +650,8 @@ public abstract class OsmandPlugin {
return null;
}
public static List<CustomRegion> getCustomDownloadRegions() {
List<CustomRegion> l = new ArrayList<>();
public static List<WorldRegion> getCustomDownloadRegions() {
List<WorldRegion> l = new ArrayList<>();
for (OsmandPlugin plugin : getEnabledPlugins()) {
l.addAll(plugin.getDownloadMaps());
}
@ -661,18 +660,18 @@ public abstract class OsmandPlugin {
public static List<IndexItem> getCustomDownloadItems() {
List<IndexItem> l = new ArrayList<>();
for (CustomRegion region : getCustomDownloadRegions()) {
for (WorldRegion region : getCustomDownloadRegions()) {
collectIndexItemsFromSubregion(region, l);
}
return l;
}
public static void collectIndexItemsFromSubregion(CustomRegion region, List<IndexItem> items) {
items.addAll(region.loadIndexItems());
public static void collectIndexItemsFromSubregion(WorldRegion region, List<IndexItem> items) {
if (region instanceof CustomRegion) {
items.addAll(((CustomRegion) region).loadIndexItems());
}
for (WorldRegion subregion : region.getSubregions()) {
if (subregion instanceof CustomRegion) {
collectIndexItemsFromSubregion((CustomRegion) subregion, items);
}
collectIndexItemsFromSubregion(subregion, items);
}
}

View file

@ -23,10 +23,6 @@ import net.osmand.plus.ApplicationMode.ApplicationModeBean;
import net.osmand.plus.ApplicationMode.ApplicationModeBuilder;
import net.osmand.plus.CustomOsmandPlugin.SuggestedDownloadItem;
import net.osmand.plus.OsmandSettings.OsmandPreference;
import net.osmand.plus.download.CustomIndexItem;
import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.DownloadResourceGroup;
import net.osmand.plus.download.IndexItem;
import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.poi.PoiUIFilter;
@ -53,7 +49,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Type;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@ -566,7 +561,7 @@ public class SettingsHelper {
public static class DownloadsItem extends SettingsItem {
private List<CustomRegion> items;
private List<WorldRegion> items;
DownloadsItem(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
super(app, json);
@ -597,12 +592,7 @@ public class SettingsHelper {
return "downloads";
}
@Override
public void apply() {
super.apply();
}
public List<CustomRegion> getItems() {
public List<WorldRegion> getItems() {
return items;
}
@ -625,9 +615,11 @@ public class SettingsHelper {
JSONArray jsonArray = new JSONArray();
if (!items.isEmpty()) {
try {
for (CustomRegion customRegion : items) {
JSONObject regionJson = customRegion.toJson();
jsonArray.put(regionJson);
for (WorldRegion region : items) {
if (region instanceof CustomRegion) {
JSONObject regionJson = ((CustomRegion) region).toJson();
jsonArray.put(regionJson);
}
}
json.put("items", jsonArray);
} catch (JSONException e) {
@ -650,203 +642,6 @@ public class SettingsHelper {
}
}
public static class CustomRegion extends WorldRegion {
public String scopeId;
public String path;
public String parentPath;
public String type;
public String subfolder;
public String headerButton;
public JSONArray downloadItemsJson;
public Map<String, String> names = new HashMap<>();
public Map<String, String> icons = new HashMap<>();
public Map<String, String> headers = new HashMap<>();
public int headerColor;
private CustomRegion(String scopeId, String path, String type) {
super(path, null);
this.scopeId = scopeId;
this.path = path;
this.type = type;
}
public static CustomRegion fromJson(JSONObject object) throws JSONException {
String scopeId = object.optString("scope-id", null);
String path = object.optString("path", null);
String type = object.optString("type", null);
CustomRegion region = new CustomRegion(scopeId, path, type);
region.subfolder = object.optString("subfolder", null);
int index = path.lastIndexOf(File.separator);
if (index != -1) {
region.parentPath = path.substring(0, index);
}
JSONObject namesJson = object.optJSONObject("name");
if (namesJson != null) {
for (Iterator<String> it = namesJson.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = namesJson.getString(localeKey);
region.names.put(localeKey, name);
}
region.regionName = region.names.get("");
region.regionNameEn = region.names.get("");
region.regionFullName = region.names.get("");
region.regionNameLocale = region.names.get("");
if (Algorithms.isEmpty(region.regionName)) {
region.regionName = region.names.get("");
}
if (Algorithms.isEmpty(region.regionName)) {
region.regionName = DownloadResourceGroup.DownloadResourceGroupType.REGION.getDefaultId();
}
}
JSONObject iconJson = object.optJSONObject("icon");
if (iconJson != null) {
for (Iterator<String> it = iconJson.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = iconJson.getString(localeKey);
region.icons.put(localeKey, name);
}
}
JSONObject headerJson = object.optJSONObject("header");
if (headerJson != null) {
for (Iterator<String> it = headerJson.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = headerJson.getString(localeKey);
region.headers.put(localeKey, name);
}
}
region.headerButton = object.optString("header-button", null);
region.downloadItemsJson = object.optJSONArray("items");
String headerColor = object.optString("header-color", null);
try {
region.headerColor = Algorithms.isEmpty(headerColor) ? 0 : Algorithms.parseColor(headerColor);
} catch (IllegalArgumentException e) {
region.headerColor = 0;
}
return region;
}
public List<IndexItem> loadIndexItems() {
List<IndexItem> items = new ArrayList<>();
if (downloadItemsJson != null) {
try {
for (int i = 0; i < downloadItemsJson.length(); i++) {
JSONObject indexItemJson = downloadItemsJson.getJSONObject(i);
JSONObject indexNamesJson = indexItemJson.optJSONObject("name");
Map<String, String> indexNames = new HashMap<>();
if (indexNamesJson != null) {
for (Iterator<String> it = indexNamesJson.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = indexNamesJson.getString(localeKey);
indexNames.put(localeKey, name);
}
}
long timestamp = indexItemJson.optLong("timestamp") * 1000;
long contentSize = indexItemJson.optLong("contentSize");
long containerSize = indexItemJson.optLong("containerSize");
String fileName = indexItemJson.optString("filename");
String downloadUrl = indexItemJson.optString("downloadurl");
String size = new DecimalFormat("#.#").format(containerSize / (1024f * 1024f));
JSONObject descriptionJson = indexItemJson.optJSONObject("description");
Map<String, String> descriptions = new HashMap<>();
if (descriptionJson != null) {
for (Iterator<String> it = descriptionJson.keys(); it.hasNext(); ) {
String localeKey = it.next();
String name = descriptionJson.getString(localeKey);
descriptions.put(localeKey, name);
}
}
List<String> descrImageUrl = new ArrayList<>();
JSONArray imageDescriptionUrlJson = indexItemJson.optJSONArray("image-description-url");
if (imageDescriptionUrlJson != null) {
for (int j = 0; j < imageDescriptionUrlJson.length(); j++) {
String renderer = imageDescriptionUrlJson.getString(i);
descrImageUrl.add(renderer);
}
}
String indexType = indexItemJson.optString("type", type);
@NonNull DownloadActivityType tp = DownloadActivityType.getIndexType(indexType);
if (tp != null) {
IndexItem indexItem = new CustomIndexItem(fileName, subfolder, downloadUrl, indexNames,descriptions, descrImageUrl, timestamp, size, contentSize, containerSize, tp);
items.add(indexItem);
}
}
} catch (JSONException e) {
LOG.error(e);
}
}
return items;
}
public JSONObject toJson() throws JSONException {
JSONObject jsonObject = new JSONObject();
if (!Algorithms.isEmpty(scopeId)) {
jsonObject.put("scope-id", scopeId);
}
if (!Algorithms.isEmpty(path)) {
jsonObject.put("path", path);
}
if (!Algorithms.isEmpty(type)) {
jsonObject.put("type", type);
}
if (!Algorithms.isEmpty(subfolder)) {
jsonObject.put("subfolder", subfolder);
}
if (!Algorithms.isEmpty(headerButton)) {
jsonObject.put("header-button", headerButton);
}
if (!Algorithms.isEmpty(names)) {
JSONObject namesJson = new JSONObject();
for (Map.Entry<String, String> entry : names.entrySet()) {
namesJson.put(entry.getKey(), entry.getValue());
}
jsonObject.put("name", namesJson);
}
if (!Algorithms.isEmpty(icons)) {
JSONObject iconsJson = new JSONObject();
for (Map.Entry<String, String> entry : icons.entrySet()) {
iconsJson.put(entry.getKey(), entry.getValue());
}
jsonObject.put("icon", iconsJson);
}
if (!Algorithms.isEmpty(headers)) {
JSONObject headerJson = new JSONObject();
for (Map.Entry<String, String> entry : headers.entrySet()) {
headerJson.put(entry.getKey(), entry.getValue());
}
jsonObject.put("header", headerJson);
}
if (downloadItemsJson != null) {
jsonObject.put("items", downloadItemsJson);
}
return jsonObject;
}
}
public abstract static class CollectionSettingsItem<T> extends SettingsItem {
protected List<T> items;

View file

@ -1,9 +1,11 @@
package net.osmand.plus.download;
import android.content.Context;
import android.content.res.Configuration;
import androidx.annotation.NonNull;
import net.osmand.map.OsmandRegions;
import net.osmand.plus.CustomOsmandPlugin;
import net.osmand.plus.OsmandApplication;
import net.osmand.util.Algorithms;
@ -13,21 +15,36 @@ import java.util.Map;
public class CustomIndexItem extends IndexItem {
private String downloadUrl;
private String subfolder;
private String downloadUrl;
private String webUrl;
private List<String> imageDescrUrl;
private Map<String, String> names;
private Map<String, String> descriptions;
private List<String> descrImageUrl;
private Map<String, String> webButtonTexts;
public CustomIndexItem(String fileName, String subfolder, String downloadUrl,
Map<String, String> names, Map<String, String> descriptions, List<String> descrImageUrl, long dateModified, String size, long contentSize,
long containerSize, DownloadActivityType type) {
super(fileName, null, dateModified, size, contentSize, containerSize, type);
this.names = names;
this.descriptions = descriptions;
public CustomIndexItem(String fileName,
String subfolder,
String downloadUrl,
String webUrl,
String size,
long timestamp,
long contentSize,
long containerSize,
List<String> imageDescrUrl,
Map<String, String> names,
Map<String, String> descriptions,
Map<String, String> webButtonTexts,
@NonNull DownloadActivityType type) {
super(fileName, null, timestamp, size, contentSize, containerSize, type);
this.subfolder = subfolder;
this.downloadUrl = downloadUrl;
this.descrImageUrl = descrImageUrl;
this.webUrl = webUrl;
this.imageDescrUrl = imageDescrUrl;
this.names = names;
this.descriptions = descriptions;
this.webButtonTexts = webButtonTexts;
}
@Override
@ -36,7 +53,6 @@ public class CustomIndexItem extends IndexItem {
if (entry != null) {
entry.urlToDownload = downloadUrl;
}
return entry;
}
@ -56,38 +72,125 @@ public class CustomIndexItem extends IndexItem {
@Override
public String getVisibleName(Context ctx, OsmandRegions osmandRegions, boolean includingParent) {
if (!Algorithms.isEmpty(names)) {
Configuration config = ctx.getResources().getConfiguration();
String lang = config.locale.getLanguage();
String name = names.get(lang);
if (Algorithms.isEmpty(name)) {
name = names.get("");
}
if (!Algorithms.isEmpty(name)) {
return name;
}
}
return super.getVisibleName(ctx, osmandRegions, includingParent);
String name = super.getVisibleName(ctx, osmandRegions, includingParent);
return CustomOsmandPlugin.getLocalizedResFromMap(ctx, names, name);
}
public List<String> getDescriptionImageUrl() {
return descrImageUrl;
return imageDescrUrl;
}
public String getLocalizedDescription(Context ctx) {
if (!Algorithms.isEmpty(descriptions)) {
Configuration config = ctx.getResources().getConfiguration();
String lang = config.locale.getLanguage();
String name = descriptions.get(lang);
if (Algorithms.isEmpty(name)) {
name = descriptions.get("");
}
if (!Algorithms.isEmpty(name)) {
return name;
}
String description = super.getDescription();
return CustomOsmandPlugin.getLocalizedResFromMap(ctx, descriptions, description);
}
public String getWebUrl() {
return webUrl;
}
public String getWebButtonText(Context ctx) {
return CustomOsmandPlugin.getLocalizedResFromMap(ctx, webButtonTexts, null);
}
public static class CustomIndexItemBuilder {
private String fileName;
private String subfolder;
private String downloadUrl;
private String webUrl;
private String size;
private long timestamp;
private long contentSize;
private long containerSize;
private List<String> imageDescrUrl;
private Map<String, String> names;
private Map<String, String> descriptions;
private Map<String, String> webButtonText;
private DownloadActivityType type;
public CustomIndexItemBuilder setFileName(String fileName) {
this.fileName = fileName;
return this;
}
return super.getDescription();
public CustomIndexItemBuilder setSubfolder(String subfolder) {
this.subfolder = subfolder;
return this;
}
public CustomIndexItemBuilder setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
return this;
}
public CustomIndexItemBuilder setWebUrl(String webUrl) {
this.webUrl = webUrl;
return this;
}
public CustomIndexItemBuilder setSize(String size) {
this.size = size;
return this;
}
public CustomIndexItemBuilder setTimestamp(long timestamp) {
this.timestamp = timestamp;
return this;
}
public CustomIndexItemBuilder setContentSize(long contentSize) {
this.contentSize = contentSize;
return this;
}
public CustomIndexItemBuilder setContainerSize(long containerSize) {
this.containerSize = containerSize;
return this;
}
public CustomIndexItemBuilder setImageDescrUrl(List<String> imageDescrUrl) {
this.imageDescrUrl = imageDescrUrl;
return this;
}
public CustomIndexItemBuilder setNames(Map<String, String> names) {
this.names = names;
return this;
}
public CustomIndexItemBuilder setDescriptions(Map<String, String> descriptions) {
this.descriptions = descriptions;
return this;
}
public CustomIndexItemBuilder setWebButtonText(Map<String, String> webButtonText) {
this.webButtonText = webButtonText;
return this;
}
public CustomIndexItemBuilder setType(@NonNull DownloadActivityType type) {
this.type = type;
return this;
}
public CustomIndexItem create() {
return new CustomIndexItem(fileName,
subfolder,
downloadUrl,
webUrl,
size,
timestamp,
contentSize,
containerSize,
imageDescrUrl,
names,
descriptions,
webButtonText,
type);
}
}
}
}

View file

@ -10,7 +10,7 @@ import net.osmand.map.OsmandRegions;
import net.osmand.map.WorldRegion;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.SettingsHelper.CustomRegion;
import net.osmand.plus.CustomRegion;
import net.osmand.plus.download.DownloadOsmandIndexesHelper.AssetIndexItem;
import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.util.Algorithms;
@ -368,10 +368,10 @@ public class DownloadResources extends DownloadResourceGroup {
}
this.groupByRegion = groupByRegion;
List<CustomRegion> customRegions = OsmandPlugin.getCustomDownloadRegions();
List<WorldRegion> customRegions = OsmandPlugin.getCustomDownloadRegions();
if (!Algorithms.isEmpty(customRegions)) {
addGroup(extraMapsGroup);
for (CustomRegion region : customRegions) {
for (WorldRegion region : customRegions) {
buildRegionsGroups(region, extraMapsGroup);
}
}

View file

@ -1,6 +1,7 @@
package net.osmand.plus.download.ui;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -17,18 +18,21 @@ import com.squareup.picasso.RequestCreator;
import net.osmand.AndroidUtils;
import net.osmand.PicassoUtils;
import net.osmand.map.WorldRegion;
import net.osmand.plus.CustomRegion;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.download.CustomIndexItem;
import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.download.DownloadResourceGroup;
import net.osmand.plus.download.DownloadResources;
import net.osmand.plus.wikipedia.WikipediaDialogFragment;
import net.osmand.util.Algorithms;
import static net.osmand.plus.download.ui.DownloadResourceGroupFragment.REGION_ID_DLG_KEY;
public class DownloadItemFragment extends DialogFragment implements DownloadIndexesThread.DownloadEvents {
public class DownloadItemFragment extends DialogFragment {
public static final String ITEM_ID_DLG_KEY = "index_item_dialog_key";
@ -41,11 +45,12 @@ public class DownloadItemFragment extends DialogFragment implements DownloadInde
private CustomIndexItem indexItem;
private View view;
private TextView description;
private ImageView image;
private Toolbar toolbar;
private ImageView image;
private TextView description;
private TextView buttonTextView;
boolean nightMode;
private boolean nightMode;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -84,7 +89,16 @@ public class DownloadItemFragment extends DialogFragment implements DownloadInde
image = view.findViewById(R.id.item_image);
View dismissButton = view.findViewById(R.id.dismiss_button);
UiUtilities.setupDialogButton(nightMode, dismissButton, UiUtilities.DialogButtonType.PRIMARY, "Test");
dismissButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (indexItem != null && !Algorithms.isEmpty(indexItem.getWebUrl())) {
WikipediaDialogFragment.showFullArticle(v.getContext(), Uri.parse(indexItem.getWebUrl()), nightMode);
}
}
});
UiUtilities.setupDialogButton(nightMode, dismissButton, UiUtilities.DialogButtonType.PRIMARY, "");
buttonTextView = (TextView) dismissButton.findViewById(R.id.button_text);
return view;
}
@ -95,20 +109,6 @@ public class DownloadItemFragment extends DialogFragment implements DownloadInde
reloadData();
}
@Override
public void newDownloadIndexes() {
reloadData();
}
@Override
public void downloadHasFinished() {
}
@Override
public void downloadInProgress() {
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@ -125,7 +125,17 @@ public class DownloadItemFragment extends DialogFragment implements DownloadInde
indexItem = (CustomIndexItem) group.getItemByIndex(itemIndex);
if (indexItem != null) {
toolbar.setTitle(indexItem.getVisibleName(app, app.getRegions()));
WorldRegion region = group.getRegion();
if (region instanceof CustomRegion) {
CustomRegion customRegion = (CustomRegion) region;
int color = customRegion.getHeaderColor();
if (color != -1) {
toolbar.setBackgroundColor(color);
}
}
description.setText(indexItem.getLocalizedDescription(app));
buttonTextView.setText(indexItem.getWebButtonText(app));
final PicassoUtils picassoUtils = PicassoUtils.getPicasso(app);
Picasso picasso = Picasso.get();