Merge pull request #8712 from osmandapp/custom_plugins

Custom plugins
This commit is contained in:
max-klaus 2020-03-31 16:22:07 +03:00 committed by GitHub
commit f924e7327b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 1761 additions and 751 deletions

View file

@ -73,4 +73,5 @@ public class IndexConstants {
public static final String SETTINGS_DIR = "settings/"; //$NON-NLS-1$
public static final String TEMP_DIR = "temp/";
public static final String ROUTING_PROFILES_DIR = "routing/";
public static final String PLUGINS_DIR = "plugins/";
}

View file

@ -104,6 +104,14 @@ public class Algorithms {
return name.substring(i + 1);
}
public static String getFileWithoutDirs(String name) {
int i = name.lastIndexOf(File.separator);
if (i != -1) {
return name.substring(i + 1);
}
return name;
}
public static File[] getSortedFilesVersions(File dir) {
File[] listFiles = dir.listFiles();
if (listFiles != null) {

View file

@ -11,6 +11,7 @@
Thx - Hardy
-->
<string name="custom_osmand_plugin">Custom OsmAnd plugin</string>
<string name="app_mode_ski_snowmobile">Snowmobile</string>
<string name="app_mode_ski_touring">Ski touring</string>
<string name="shared_string_min">Min</string>

View file

@ -23,12 +23,12 @@ public class AccessibilityPlugin extends OsmandPlugin {
public static final int INCLINATION_RIGHT = 3;
private static final String ID = "osmand.accessibility";
private OsmandApplication app;
private SoundPool sounds;
private Map<Integer, Integer> soundIcons = new HashMap<Integer, Integer>();
public AccessibilityPlugin(OsmandApplication app) {
this.app = app;
super(app);
OsmandSettings settings = app.getSettings();
pluginPreferences.add(settings.ACCESSIBILITY_MODE);
pluginPreferences.add(settings.SPEECH_RATE);
@ -88,11 +88,6 @@ public class AccessibilityPlugin extends OsmandPlugin {
}
}
@Override
public int getAssetResourceName() {
return 0;
}
@Override
public int getLogoResourceId() {
return R.drawable.ic_plugin_accessibility;

View file

@ -0,0 +1,409 @@
package net.osmand.plus;
import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.map.ITileSource;
import net.osmand.map.TileSourceManager;
import net.osmand.plus.SettingsHelper.AvoidRoadsSettingsItem;
import net.osmand.plus.SettingsHelper.MapSourcesSettingsItem;
import net.osmand.plus.SettingsHelper.PluginSettingsItem;
import net.osmand.plus.SettingsHelper.PoiUiFilterSettingsItem;
import net.osmand.plus.SettingsHelper.ProfileSettingsItem;
import net.osmand.plus.SettingsHelper.QuickActionsSettingsItem;
import net.osmand.plus.SettingsHelper.SettingsCollectListener;
import net.osmand.plus.SettingsHelper.SettingsItem;
import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.quickaction.QuickActionRegistry;
import net.osmand.plus.render.RendererRegistry;
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.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static net.osmand.IndexConstants.SQLITE_EXT;
public class CustomOsmandPlugin extends OsmandPlugin {
private static final Log LOG = PlatformUtil.getLog(CustomOsmandPlugin.class);
private String pluginId;
private String resourceDirName;
private Map<String, String> names = new HashMap<>();
private Map<String, String> descriptions = new HashMap<>();
private Map<String, String> iconNames = new HashMap<>();
private Map<String, String> imageNames = new HashMap<>();
private Drawable icon;
private Drawable image;
private List<String> rendererNames = new ArrayList<>();
private List<String> routerNames = new ArrayList<>();
public CustomOsmandPlugin(@NonNull OsmandApplication app, @NonNull JSONObject json) throws JSONException {
super(app);
pluginId = json.getString("pluginId");
readAdditionalDataFromJson(json);
readDependentFilesFromJson(json);
loadResources();
}
@Override
public boolean init(@NonNull OsmandApplication app, @Nullable Activity activity) {
super.init(app, activity);
if (activity != null) {
// called from UI
File pluginItemsFile = getPluginItemsFile();
if (pluginItemsFile.exists()) {
addPluginItemsFromFile(pluginItemsFile);
}
}
return true;
}
private void addPluginItemsFromFile(final File file) {
app.getSettingsHelper().collectSettings(file, "", 1, new SettingsCollectListener() {
@Override
public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List<SettingsItem> items) {
if (succeed && !items.isEmpty()) {
for (Iterator<SettingsItem> iterator = items.iterator(); iterator.hasNext(); ) {
SettingsItem item = iterator.next();
if (item instanceof ProfileSettingsItem) {
ProfileSettingsItem profileSettingsItem = (ProfileSettingsItem) item;
ApplicationMode mode = profileSettingsItem.getAppMode();
ApplicationMode savedMode = ApplicationMode.valueOfStringKey(mode.getStringKey(), null);
if (savedMode != null) {
ApplicationMode.changeProfileAvailability(savedMode, true, app);
}
iterator.remove();
} else if (item instanceof PluginSettingsItem) {
iterator.remove();
} else {
item.setShouldReplace(true);
}
}
app.getSettingsHelper().importSettings(file, items, "", 1, null);
}
}
});
}
private void removePluginItemsFromFile(final File file) {
app.getSettingsHelper().collectSettings(file, "", 1, new SettingsCollectListener() {
@Override
public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List<SettingsItem> items) {
if (succeed && !items.isEmpty()) {
for (SettingsItem item : items) {
if (item instanceof QuickActionsSettingsItem) {
QuickActionsSettingsItem quickActionsSettingsItem = (QuickActionsSettingsItem) item;
List<QuickAction> quickActions = quickActionsSettingsItem.getItems();
QuickActionRegistry actionRegistry = app.getQuickActionRegistry();
for (QuickAction action : quickActions) {
QuickAction savedAction = actionRegistry.getQuickAction(app, action.getType(), action.getName(app), action.getParams());
if (savedAction != null) {
actionRegistry.deleteQuickAction(savedAction);
}
}
} else if (item instanceof MapSourcesSettingsItem) {
MapSourcesSettingsItem mapSourcesSettingsItem = (MapSourcesSettingsItem) item;
List<ITileSource> mapSources = mapSourcesSettingsItem.getItems();
for (ITileSource tileSource : mapSources) {
if (tileSource instanceof TileSourceManager.TileSourceTemplate) {
TileSourceManager.TileSourceTemplate sourceTemplate = (TileSourceManager.TileSourceTemplate) tileSource;
File tPath = app.getAppPath(IndexConstants.TILES_INDEX_DIR);
File dir = new File(tPath, sourceTemplate.getName());
Algorithms.removeAllFiles(dir);
} else if (tileSource instanceof SQLiteTileSource) {
SQLiteTileSource sqLiteTileSource = ((SQLiteTileSource) tileSource);
sqLiteTileSource.closeDB();
File tPath = app.getAppPath(IndexConstants.TILES_INDEX_DIR);
File dir = new File(tPath, sqLiteTileSource.getName() + SQLITE_EXT);
Algorithms.removeAllFiles(dir);
}
}
} else if (item instanceof PoiUiFilterSettingsItem) {
PoiUiFilterSettingsItem poiUiFilterSettingsItem = (PoiUiFilterSettingsItem) item;
List<PoiUIFilter> poiUIFilters = poiUiFilterSettingsItem.getItems();
for (PoiUIFilter filter : poiUIFilters) {
app.getPoiFilters().removePoiFilter(filter);
}
app.getPoiFilters().reloadAllPoiFilters();
app.getPoiFilters().loadSelectedPoiFilters();
app.getSearchUICore().refreshCustomPoiFilters();
} else if (item instanceof AvoidRoadsSettingsItem) {
AvoidRoadsSettingsItem avoidRoadsSettingsItem = (AvoidRoadsSettingsItem) item;
List<AvoidSpecificRoads.AvoidRoadInfo> avoidRoadInfos = avoidRoadsSettingsItem.getItems();
for (AvoidSpecificRoads.AvoidRoadInfo avoidRoad : avoidRoadInfos) {
app.getAvoidSpecificRoads().removeImpassableRoad(avoidRoad);
}
} else if (item instanceof ProfileSettingsItem) {
ProfileSettingsItem profileSettingsItem = (ProfileSettingsItem) item;
ApplicationMode mode = profileSettingsItem.getAppMode();
ApplicationMode savedMode = ApplicationMode.valueOfStringKey(mode.getStringKey(), null);
if (savedMode != null) {
ApplicationMode.changeProfileAvailability(savedMode, false, app);
}
}
}
}
}
});
}
@Override
public void disable(OsmandApplication app) {
super.disable(app);
File pluginItemsFile = getPluginItemsFile();
if (pluginItemsFile.exists()) {
removePluginItemsFromFile(pluginItemsFile);
}
}
private File getPluginItemsFile() {
File pluginDir = new File(app.getAppPath(null), IndexConstants.PLUGINS_DIR + pluginId);
return new File(pluginDir, "items" + IndexConstants.OSMAND_SETTINGS_FILE_EXT);
}
@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);
}
}
}
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);
}
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;
}
public void writeDependentFilesJson(JSONObject json) throws JSONException {
JSONArray rendererNamesJson = new JSONArray();
for (String render : rendererNames) {
rendererNamesJson.put(render);
}
json.put("rendererNames", rendererNamesJson);
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);
json.put("pluginResDir", resourceDirName);
}
@Override
public List<String> getRendererNames() {
return rendererNames;
}
@Override
public List<String> getRouterNames() {
return routerNames;
}
public void addRouter(String fileName) {
routerNames.add(fileName);
}
public void addRenderer(String fileName) {
String renderer = RendererRegistry.formatRendererFileName(fileName);
rendererNames.add(renderer.replace('_', ' ').replace('-', ' '));
}
public void loadResources() {
if (!Algorithms.isEmpty(resourceDirName)) {
File pluginDir = new File(app.getAppPath(null), IndexConstants.PLUGINS_DIR + pluginId);
File pluginResDir = new File(pluginDir, resourceDirName);
if (pluginResDir.exists() && pluginResDir.isDirectory()) {
File[] files = pluginResDir.listFiles();
for (File resFile : files) {
String path = resFile.getAbsolutePath();
if (icon == null) {
icon = getIconForFile(path, iconNames);
}
if (image == null) {
image = getIconForFile(path, imageNames);
}
}
}
}
}
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;
}
}

View file

@ -6,6 +6,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.View;
@ -22,6 +23,7 @@ import net.osmand.PlatformUtil;
import net.osmand.access.AccessibilityPlugin;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.TabActivity.TabItem;
import net.osmand.plus.api.SettingsAPI;
import net.osmand.plus.audionotes.AudioVideoNotesPlugin;
import net.osmand.plus.dashboard.tools.DashFragmentData;
import net.osmand.plus.development.OsmandDevelopmentPlugin;
@ -42,8 +44,12 @@ import net.osmand.plus.settings.BaseSettingsFragment;
import net.osmand.plus.skimapsplugin.SkiMapsPlugin;
import net.osmand.plus.srtmplugin.SRTMPlugin;
import net.osmand.plus.views.OsmandMapTileView;
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.util.ArrayList;
import java.util.Collection;
@ -56,27 +62,45 @@ public abstract class OsmandPlugin {
public static final String PLUGIN_ID_KEY = "plugin_id";
private static List<OsmandPlugin> allPlugins = new ArrayList<OsmandPlugin>();
private static final String PLUGINS_PREFERENCES_NAME = "net.osmand.plugins";
private static final String CUSTOM_PLUGINS_KEY = "custom_plugins";
private static final Log LOG = PlatformUtil.getLog(OsmandPlugin.class);
private static List<OsmandPlugin> allPlugins = new ArrayList<OsmandPlugin>();
protected OsmandApplication app;
protected List<OsmandSettings.OsmandPreference> pluginPreferences = new ArrayList<>();
private boolean active;
private String installURL = null;
public OsmandPlugin(OsmandApplication app) {
this.app = app;
}
public abstract String getId();
public abstract String getName();
public abstract String getDescription();
public abstract int getAssetResourceName();
@Nullable
public Drawable getAssetResourceImage() {
return null;
}
@DrawableRes
public int getLogoResourceId() {
return R.drawable.ic_extension_dark;
}
@NonNull
public Drawable getLogoResource() {
return app.getUIUtilities().getIcon(getLogoResourceId());
}
public Class<? extends Activity> getSettingsActivity() {
return null;
}
@ -101,6 +125,12 @@ public abstract class OsmandPlugin {
* Initialize plugin runs just after creation
*/
public boolean init(@NonNull OsmandApplication app, @Nullable Activity activity) {
if (activity != null) {
// called from UI
for (ApplicationMode appMode: getAddedAppModes()) {
ApplicationMode.changeProfileAvailability(appMode, true, app);
}
}
return true;
}
@ -152,32 +182,42 @@ public abstract class OsmandPlugin {
return Collections.emptyList();
}
public List<String> getRendererNames() {
return Collections.emptyList();
}
public List<String> getRouterNames() {
return Collections.emptyList();
}
/**
* Plugin was installed
*/
public void onInstall(@NonNull OsmandApplication app, @Nullable Activity activity) {
for (ApplicationMode appMode : getAddedAppModes()) {
ApplicationMode.changeProfileAvailability(appMode, true, app);
}
showInstallDialog(activity);
}
public void showInstallDialog(@Nullable Activity activity) {
if (activity instanceof FragmentActivity) {
FragmentManager fragmentManager = ((FragmentActivity) activity).getSupportFragmentManager();
if (fragmentManager != null) {
PluginInstalledBottomSheetDialog.showInstance(fragmentManager, getId(), activity instanceof MapActivity);
}
PluginInstalledBottomSheetDialog.showInstance(fragmentManager, getId(), activity instanceof MapActivity);
}
}
public void showDisableDialog(@Nullable Activity activity) {
if (activity instanceof FragmentActivity) {
FragmentManager fragmentManager = ((FragmentActivity) activity).getSupportFragmentManager();
if (fragmentManager != null) {
PluginDisabledBottomSheet.showInstance(fragmentManager, getId(), activity instanceof MapActivity);
}
PluginDisabledBottomSheet.showInstance(fragmentManager, getId(), activity instanceof MapActivity);
}
}
public void disable(OsmandApplication app) {
for (ApplicationMode appMode : getAddedAppModes()) {
ApplicationMode.changeProfileAvailability(appMode, false, app);
}
}
public String getHelpFileName() {
@ -229,9 +269,62 @@ public abstract class OsmandPlugin {
allPlugins.add(new OsmEditingPlugin(app));
allPlugins.add(new OsmandDevelopmentPlugin(app));
loadCustomPlugins(app);
activatePlugins(app, enabledPlugins);
}
public static void addCustomPlugin(@NonNull OsmandApplication app, @NonNull CustomOsmandPlugin plugin) {
OsmandPlugin oldPlugin = OsmandPlugin.getPlugin(plugin.getId());
if (oldPlugin != null) {
allPlugins.remove(oldPlugin);
}
allPlugins.add(plugin);
enablePlugin(null, app, plugin, true);
saveCustomPlugins(app);
}
private static void loadCustomPlugins(@NonNull OsmandApplication app) {
SettingsAPI settingsAPI = app.getSettings().getSettingsAPI();
Object pluginPrefs = settingsAPI.getPreferenceObject(PLUGINS_PREFERENCES_NAME);
String customPluginsJson = settingsAPI.getString(pluginPrefs, CUSTOM_PLUGINS_KEY, "");
if (!Algorithms.isEmpty(customPluginsJson)) {
try {
JSONArray jArray = new JSONArray(customPluginsJson);
for (int i = 0; i < jArray.length(); i++) {
JSONObject json = jArray.getJSONObject(i);
CustomOsmandPlugin plugin = new CustomOsmandPlugin(app, json);
allPlugins.add(plugin);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
private static void saveCustomPlugins(OsmandApplication app) {
List<CustomOsmandPlugin> customOsmandPlugins = getCustomPlugins();
if (!customOsmandPlugins.isEmpty()) {
SettingsAPI settingsAPI = app.getSettings().getSettingsAPI();
Object pluginPrefs = settingsAPI.getPreferenceObject(PLUGINS_PREFERENCES_NAME);
JSONArray itemsJson = new JSONArray();
for (CustomOsmandPlugin plugin : customOsmandPlugins) {
try {
JSONObject json = new JSONObject();
json.put("pluginId", plugin.getId());
plugin.writeAdditionalDataToJson(json);
plugin.writeDependentFilesJson(json);
itemsJson.put(json);
} catch (JSONException e) {
e.printStackTrace();
}
}
String jsonStr = itemsJson.toString();
if (!jsonStr.equals(settingsAPI.getString(pluginPrefs, CUSTOM_PLUGINS_KEY, ""))) {
settingsAPI.edit(pluginPrefs).putString(CUSTOM_PLUGINS_KEY, jsonStr).commit();
}
}
}
private static void activatePlugins(OsmandApplication app, Set<String> enabledPlugins) {
for (OsmandPlugin plugin : allPlugins) {
if (enabledPlugins.contains(plugin.getId()) || plugin.isActive()) {
@ -499,6 +592,16 @@ public abstract class OsmandPlugin {
return lst;
}
public static List<CustomOsmandPlugin> getCustomPlugins() {
ArrayList<CustomOsmandPlugin> lst = new ArrayList<CustomOsmandPlugin>(allPlugins.size());
for (OsmandPlugin plugin : allPlugins) {
if (plugin instanceof CustomOsmandPlugin) {
lst.add((CustomOsmandPlugin) plugin);
}
}
return lst;
}
@SuppressWarnings("unchecked")
public static <T extends OsmandPlugin> T getEnabledPlugin(Class<T> clz) {
for (OsmandPlugin lr : getEnabledPlugins()) {

File diff suppressed because it is too large Load diff

View file

@ -65,12 +65,13 @@ public class PluginActivity extends OsmandActionBarActivity implements Download
setContentView(R.layout.plugin);
//noinspection ConstantConditions
getSupportActionBar().setTitle(plugin.getName());
if(plugin.getAssetResourceName() != 0 && Build.VERSION.SDK_INT >= 14) {
Drawable pluginImage = plugin.getAssetResourceImage();
if (pluginImage != null) {
ImageView img = (ImageView) findViewById(R.id.plugin_image);
img.setImageResource(plugin.getAssetResourceName());
img.setImageDrawable(pluginImage);
}
TextView descriptionView = (TextView)findViewById(R.id.plugin_description);
TextView descriptionView = (TextView) findViewById(R.id.plugin_description);
descriptionView.setText(plugin.getDescription());
Button settingsButton = (Button)findViewById(R.id.plugin_settings);

View file

@ -22,6 +22,7 @@ import net.osmand.aidl.ConnectedApp;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.dialogs.PluginInstalledBottomSheetDialog;
import net.osmand.plus.download.DownloadIndexesThread;
@ -180,7 +181,7 @@ public class PluginsActivity extends OsmandListActivity implements DownloadIndex
OsmandApplication app = getMyApplication();
int color = AndroidUtils.getColorFromAttr(app, R.attr.list_background_color);
pluginLogo.setImageDrawable(app.getUIUtilities().getPaintedIcon(plugin.getLogoResourceId(), color));
pluginLogo.setImageDrawable(UiUtilities.tintDrawable(plugin.getLogoResource(), color));
pluginLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

View file

@ -10,6 +10,7 @@ import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
@ -105,11 +106,12 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
public static final String THREEGP_EXTENSION = "3gp";
public static final String MPEG4_EXTENSION = "mp4";
public static final String IMG_EXTENSION = "jpg";
private static final Log log = PlatformUtil.getLog(AudioVideoNotesPlugin.class);
public static final int CAMERA_FOR_VIDEO_REQUEST_CODE = 101;
public static final int CAMERA_FOR_PHOTO_REQUEST_CODE = 102;
public static final int AUDIO_REQUEST_CODE = 103;
private static final Log log = PlatformUtil.getLog(AudioVideoNotesPlugin.class);
// Constants for determining the order of items in the additional actions context menu
private static final int TAKE_AUDIO_NOTE_ITEM_ORDER = 4100;
private static final int TAKE_VIDEO_NOTE_ITEM_ORDER = 4300;
@ -117,7 +119,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
// private static Method mRegisterMediaButtonEventReceiver;
// private static Method mUnregisterMediaButtonEventReceiver;
private OsmandApplication app;
private TextInfoWidget recordControl;
public final CommonPreference<Boolean> AV_EXTERNAL_RECORDER;
@ -539,7 +541,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
}
public AudioVideoNotesPlugin(OsmandApplication app) {
this.app = app;
super(app);
ApplicationMode.regWidgetVisibility("audionotes", (ApplicationMode[]) null);
AV_EXTERNAL_RECORDER = registerBooleanPreference(app, "av_external_recorder", false);
AV_EXTERNAL_PHOTO_CAM = registerBooleanPreference(app, "av_external_cam", true);
@ -2108,8 +2110,8 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
}
@Override
public int getAssetResourceName() {
return R.drawable.audio_video_notes;
public Drawable getAssetResourceImage() {
return app.getUIUtilities().getIcon(R.drawable.audio_video_notes);
}
@Override

View file

@ -2,6 +2,7 @@ package net.osmand.plus.development;
import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.widget.ArrayAdapter;
import net.osmand.plus.ContextMenuAdapter;
@ -22,11 +23,11 @@ import net.osmand.plus.views.mapwidgets.TextInfoWidget;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_BUILDS_ID;
public class OsmandDevelopmentPlugin extends OsmandPlugin {
private static final String ID = "osmand.development";
private OsmandApplication app;
public OsmandDevelopmentPlugin(OsmandApplication app) {
this.app = app;
super(app);
//ApplicationMode.regWidgetVisibility("fps", new ApplicationMode[0]);
}
@ -136,8 +137,8 @@ public class OsmandDevelopmentPlugin extends OsmandPlugin {
}
@Override
public int getAssetResourceName() {
return R.drawable.osmand_development;
public Drawable getAssetResourceImage() {
return app.getUIUtilities().getIcon(R.drawable.osmand_development);
}
@Override

View file

@ -91,7 +91,7 @@ public class PluginInstalledBottomSheetDialog extends MenuBottomSheetDialogFragm
BaseBottomSheetItem pluginTitle = new SimpleBottomSheetItem.Builder()
.setTitle(pluginTitleSpan)
.setTitleColorId(nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light)
.setIcon(getContentIcon(R.drawable.ic_extension_dark))
.setIcon(plugin.getLogoResource())
.setLayoutId(R.layout.bottom_sheet_item_simple_56dp)
.create();
items.add(pluginTitle);

View file

@ -29,7 +29,6 @@ import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemTitleWithDescrAndButton;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.SubtitleDividerItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.openseamapsplugin.NauticalMapsPlugin;
import net.osmand.plus.render.RendererRegistry;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.render.RenderingRulesStorage;
@ -178,8 +177,10 @@ public class SelectMapStyleBottomSheetDialogFragment extends MenuBottomSheetDial
});
List<String> names = new ArrayList<>(getMyApplication().getRendererRegistry().getRendererNames());
if (OsmandPlugin.getEnabledPlugin(NauticalMapsPlugin.class) == null) {
names.remove(RendererRegistry.NAUTICAL_RENDER);
for (OsmandPlugin plugin : OsmandPlugin.getNotEnabledPlugins()) {
for (String name : plugin.getRendererNames()) {
names.remove(name);
}
}
for (String name : names) {
String translation = RendererRegistry.getTranslatedRendererName(context, name);

View file

@ -41,14 +41,18 @@ import net.osmand.data.FavouritePoint;
import net.osmand.plus.AppInitializer;
import net.osmand.plus.AppInitializer.AppInitializeListener;
import net.osmand.plus.AppInitializer.InitEvents;
import net.osmand.plus.CustomOsmandPlugin;
import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.GPXDatabase;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.CheckDuplicatesListener;
import net.osmand.plus.SettingsHelper.PluginSettingsItem;
import net.osmand.plus.SettingsHelper.SettingsCollectListener;
import net.osmand.plus.SettingsHelper.SettingsImportListener;
import net.osmand.plus.SettingsHelper.SettingsItem;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.ActivityResultListener;
import net.osmand.plus.activities.MapActivity;
@ -746,7 +750,7 @@ public class ImportHelper {
}
}
private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, CallbackWithObject<List<SettingsHelper.SettingsItem>> callback) {
private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, CallbackWithObject<List<SettingsItem>> callback) {
if (extras != null && extras.containsKey(SettingsHelper.SETTINGS_VERSION_KEY) && extras.containsKey(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY)) {
int version = extras.getInt(SettingsHelper.SETTINGS_VERSION_KEY, -1);
String latestChanges = extras.getString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY);
@ -758,7 +762,7 @@ public class ImportHelper {
@SuppressLint("StaticFieldLeak")
private void handleOsmAndSettingsImport(final Uri uri, final String name, final String latestChanges, final int version,
final CallbackWithObject<List<SettingsHelper.SettingsItem>> callback) {
final CallbackWithObject<List<SettingsItem>> callback) {
final AsyncTask<Void, Void, String> settingsImportTask = new AsyncTask<Void, Void, String>() {
ProgressDialog progress;
@ -787,12 +791,27 @@ public class ImportHelper {
if (error == null && file.exists()) {
app.getSettingsHelper().collectSettings(file, latestChanges, version, new SettingsCollectListener() {
@Override
public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
public void onSettingsCollectFinished(boolean succeed, boolean empty, @NonNull List<SettingsItem> items) {
if (progress != null && AndroidUtils.isActivityNotDestroyed(activity)) {
progress.dismiss();
}
if (succeed) {
ImportSettingsFragment.showInstance(activity.getSupportFragmentManager(), items, file);
List<SettingsItem> pluginIndependentItems = new ArrayList<>();
List<PluginSettingsItem> pluginSettingsItems = new ArrayList<>();
for (SettingsItem item : items) {
if (item instanceof PluginSettingsItem) {
pluginSettingsItems.add((PluginSettingsItem) item);
} else if (Algorithms.isEmpty(item.getPluginId())) {
pluginIndependentItems.add(item);
}
}
for (PluginSettingsItem pluginItem : pluginSettingsItems) {
handlePluginImport(pluginItem, file);
}
if (!pluginIndependentItems.isEmpty()) {
FragmentManager fragmentManager = activity.getSupportFragmentManager();
ImportSettingsFragment.showInstance(fragmentManager, pluginIndependentItems, file);
}
} else if (empty) {
app.showShortToastMessage(app.getString(R.string.file_import_error, name, app.getString(R.string.shared_string_unexpected_error)));
}
@ -822,6 +841,34 @@ public class ImportHelper {
}
}
private void handlePluginImport(final PluginSettingsItem pluginItem, final File file) {
final SettingsImportListener importListener = new SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, @NonNull List<SettingsItem> items) {
CustomOsmandPlugin plugin = pluginItem.getPlugin();
plugin.loadResources();
if (activity != null) {
plugin.onInstall(app, activity);
}
String pluginId = pluginItem.getPluginId();
File pluginDir = new File(app.getAppPath(null), IndexConstants.PLUGINS_DIR + pluginId);
app.getSettingsHelper().exportSettings(pluginDir, "items", null, items, false);
}
};
List<SettingsItem> pluginItems = new ArrayList<>(pluginItem.getPluginDependentItems());
pluginItems.add(0, pluginItem);
app.getSettingsHelper().checkDuplicates(file, pluginItems, pluginItems, new CheckDuplicatesListener() {
@Override
public void onDuplicatesChecked(@NonNull List<Object> duplicates, List<SettingsItem> items) {
for (SettingsItem item : items) {
item.setShouldReplace(true);
}
app.getSettingsHelper().importSettings(file, items, "", 1, importListener);
}
});
}
private void handleXmlFileImport(final Uri intentUri, final String fileName) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);

View file

@ -3,6 +3,7 @@ package net.osmand.plus.mapillary;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
@ -44,10 +45,11 @@ import static android.content.Intent.ACTION_VIEW;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAPILLARY;
public class MapillaryPlugin extends OsmandPlugin {
public static final String ID = "osmand.mapillary";
private static final String MAPILLARY_PACKAGE_ID = "app.mapillary";
private OsmandSettings settings;
private OsmandApplication app;
private MapillaryRasterLayer rasterLayer;
private MapillaryVectorLayer vectorLayer;
@ -55,7 +57,7 @@ public class MapillaryPlugin extends OsmandPlugin {
private MapWidgetRegInfo mapillaryWidgetRegInfo;
public MapillaryPlugin(OsmandApplication app) {
this.app = app;
super(app);
settings = app.getSettings();
}
@ -70,8 +72,8 @@ public class MapillaryPlugin extends OsmandPlugin {
}
@Override
public int getAssetResourceName() {
return R.drawable.mapillary;
public Drawable getAssetResourceImage() {
return app.getUIUtilities().getIcon(R.drawable.mapillary);
}
@Override

View file

@ -4,6 +4,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
@ -50,16 +51,17 @@ import gnu.trove.list.array.TIntArrayList;
import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT;
public class OsmandMonitoringPlugin extends OsmandPlugin {
public static final String ID = "osmand.monitoring";
public final static String OSMAND_SAVE_SERVICE_ACTION = "OSMAND_SAVE_SERVICE_ACTION";
private OsmandSettings settings;
private OsmandApplication app;
private TextInfoWidget monitoringControl;
private LiveMonitoringHelper liveMonitoringHelper;
private boolean isSaving;
public OsmandMonitoringPlugin(OsmandApplication app) {
this.app = app;
super(app);
liveMonitoringHelper = new LiveMonitoringHelper(app);
final List<ApplicationMode> am = ApplicationMode.allPossibleValues();
ApplicationMode.regWidgetVisibility("monitoring", am.toArray(new ApplicationMode[am.size()]));
@ -96,8 +98,8 @@ public class OsmandMonitoringPlugin extends OsmandPlugin {
}
@Override
public int getAssetResourceName() {
return R.drawable.trip_recording;
public Drawable getAssetResourceImage() {
return app.getUIUtilities().getIcon(R.drawable.trip_recording);
}
@Override

View file

@ -1,14 +1,12 @@
package net.osmand.plus.openseamapsplugin;
import android.app.Activity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.graphics.drawable.Drawable;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.render.RendererRegistry;
import java.util.Collections;
import java.util.List;
@ -19,20 +17,18 @@ public class NauticalMapsPlugin extends OsmandPlugin {
public static final String ID = "nauticalPlugin.plugin";
public static final String COMPONENT = "net.osmand.nauticalPlugin";
private OsmandApplication app;
public NauticalMapsPlugin(OsmandApplication app) {
this.app = app;
super(app);
}
@Override
public int getLogoResourceId() {
return R.drawable.ic_plugin_nautical_map;
}
@Override
public int getAssetResourceName() {
return R.drawable.nautical_map;
public Drawable getAssetResourceImage() {
return app.getUIUtilities().getIcon(R.drawable.nautical_map);
}
@Override
@ -60,30 +56,19 @@ public class NauticalMapsPlugin extends OsmandPlugin {
return "feature_articles/nautical-charts.html";
}
@Override
public boolean init(@NonNull final OsmandApplication app, final Activity activity) {
if (activity != null) {
// called from UI
ApplicationMode.changeProfileAvailability(ApplicationMode.BOAT, true, app);
}
return true;
}
@Override
public void onInstall(@NonNull OsmandApplication app, @Nullable Activity activity) {
ApplicationMode.changeProfileAvailability(ApplicationMode.BOAT, true, app);
super.onInstall(app, activity);
}
@Override
public List<ApplicationMode> getAddedAppModes() {
return Collections.singletonList(ApplicationMode.BOAT);
}
@Override
public void disable(OsmandApplication app) {
super.disable(app);
ApplicationMode.changeProfileAvailability(ApplicationMode.BOAT, false, app);
public List<String> getRendererNames() {
return Collections.singletonList(RendererRegistry.NAUTICAL_RENDER);
}
@Override
public List<String> getRouterNames() {
return Collections.singletonList("boat");
}
@Override

View file

@ -5,6 +5,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
@ -72,7 +73,6 @@ public class OsmEditingPlugin extends OsmandPlugin {
private static final int MODIFY_OSM_NOTE_ITEM_ORDER = 7600;
private OsmandSettings settings;
private OsmandApplication app;
private OpenstreetmapsDbHelper dbpoi;
private OsmBugsDbHelper dbbug;
private OpenstreetmapLocalUtil localUtil;
@ -81,7 +81,7 @@ public class OsmEditingPlugin extends OsmandPlugin {
private OsmBugsLocalUtil localNotesUtil;
public OsmEditingPlugin(OsmandApplication app) {
this.app = app;
super(app);
settings = app.getSettings();
}
@ -506,11 +506,10 @@ public class OsmEditingPlugin extends OsmandPlugin {
}
@Override
public int getAssetResourceName() {
return R.drawable.osm_editing;
public Drawable getAssetResourceImage() {
return app.getUIUtilities().getIcon(R.drawable.osm_editing);
}
@Override
public String getHelpFileName() {
return "feature_articles/osm-editing-plugin.html";

View file

@ -4,6 +4,7 @@ package net.osmand.plus.parkingpoint;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.text.format.Time;
@ -55,29 +56,28 @@ public class ParkingPositionPlugin extends OsmandPlugin {
public static final String ID = "osmand.parking.position";
public static final String PARKING_PLUGIN_COMPONENT = "net.osmand.parkingPlugin"; //$NON-NLS-1$
public final static String PARKING_POINT_LAT = "parking_point_lat"; //$NON-NLS-1$
public final static String PARKING_POINT_LON = "parking_point_lon"; //$NON-NLS-1$
public final static String PARKING_TYPE = "parking_type"; //$NON-NLS-1$
public final static String PARKING_TIME = "parking_limit_time"; //$//$NON-NLS-1$
public final static String PARKING_START_TIME = "parking_time"; //$//$NON-NLS-1$
public final static String PARKING_EVENT_ADDED = "parking_event_added"; //$//$NON-NLS-1$
public static final String PARKING_POINT_LAT = "parking_point_lat"; //$NON-NLS-1$
public static final String PARKING_POINT_LON = "parking_point_lon"; //$NON-NLS-1$
public static final String PARKING_TYPE = "parking_type"; //$NON-NLS-1$
public static final String PARKING_TIME = "parking_limit_time"; //$//$NON-NLS-1$
public static final String PARKING_START_TIME = "parking_time"; //$//$NON-NLS-1$
public static final String PARKING_EVENT_ADDED = "parking_event_added"; //$//$NON-NLS-1$
// Constants for determining the order of items in the additional actions context menu
private static final int MARK_AS_PARKING_POS_ITEM_ORDER = 10500;
private LatLon parkingPosition;
private OsmandApplication app;
private TextInfoWidget parkingPlaceControl;
private final CommonPreference<Float> parkingLat;
private final CommonPreference<Float> parkingLon;
private CommonPreference<Boolean> parkingType;
private CommonPreference<Boolean> parkingEvent;
private CommonPreference<Long> parkingTime;
private CommonPreference<Long> parkingStartTime;
private final CommonPreference<Boolean> parkingType;
private final CommonPreference<Boolean> parkingEvent;
private final CommonPreference<Long> parkingTime;
private final CommonPreference<Long> parkingStartTime;
public ParkingPositionPlugin(OsmandApplication app) {
this.app = app;
super(app);
OsmandSettings set = app.getSettings();
ApplicationMode.regWidgetVisibility("parking", (ApplicationMode[]) null);
parkingLat = set.registerFloatPreference(PARKING_POINT_LAT, 0f).makeGlobal();
@ -506,8 +506,8 @@ public class ParkingPositionPlugin extends OsmandPlugin {
}
@Override
public int getAssetResourceName() {
return R.drawable.parking_position;
public Drawable getAssetResourceImage() {
return app.getUIUtilities().getIcon(R.drawable.parking_position);
}
@Override

View file

@ -13,6 +13,7 @@ import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.reflect.TypeToken;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
@ -136,6 +137,17 @@ public class QuickActionRegistry {
return null;
}
public QuickAction getQuickAction(OsmandApplication app, int type, String name, Map<String, String> params) {
for (QuickAction action : quickActions) {
if (action.getType() == type
&& (action.hasCustomName(app) && action.getName(app).equals(name) || !action.hasCustomName(app))
&& action.getParams().equals(params)) {
return action;
}
}
return null;
}
public boolean isNameUnique(QuickAction action, Context context) {
for (QuickAction a : quickActions) {
if (action.id != a.id) {

View file

@ -27,7 +27,6 @@ import net.osmand.util.Algorithms;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class MapStyleAction extends SwitchableAction<String> {
@ -160,20 +159,19 @@ public class MapStyleAction extends SwitchableAction<String> {
final List<String> visibleNamesList = new ArrayList<>();
final ArrayList<String> items = new ArrayList<>(app.getRendererRegistry().getRendererNames());
final boolean nauticalPluginDisabled = OsmandPlugin.getEnabledPlugin(NauticalMapsPlugin.class) == null;
Iterator<String> iterator = items.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (nauticalPluginDisabled && item.equals(RendererRegistry.NAUTICAL_RENDER)) {
iterator.remove();
} else {
String translation = RendererRegistry.getTranslatedRendererName(activity, item);
visibleNamesList.add(translation != null ? translation
: item.replace('_', ' ').replace('-', ' '));
for (OsmandPlugin plugin : OsmandPlugin.getNotEnabledPlugins()) {
for (String name : plugin.getRendererNames()) {
items.remove(name);
}
}
for (String item : items) {
String translation = RendererRegistry.getTranslatedRendererName(activity, item);
visibleNamesList.add(translation != null ? translation
: item.replace('_', ' ').replace('-', ' '));
}
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(themedContext, R.layout.dialog_text_item);
arrayAdapter.addAll(visibleNamesList);

View file

@ -2,6 +2,7 @@ package net.osmand.plus.rastermaps;
import android.app.Activity;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.view.ContextThemeWrapper;
import android.view.View;
@ -62,20 +63,20 @@ import static net.osmand.aidlapi.OsmAndCustomizationConstants.UNDERLAY_MAP;
import static net.osmand.plus.UiUtilities.CompoundButtonType.PROFILE_DEPENDENT;
public class OsmandRasterMapsPlugin extends OsmandPlugin {
public static final String ID = "osmand.rastermaps";
// Constants for determining the order of items in the additional actions context menu
private static final int UPDATE_MAP_ITEM_ORDER = 12300;
private static final int DOWNLOAD_MAP_ITEM_ORDER = 12600;
private OsmandSettings settings;
private OsmandApplication app;
private MapTileLayer overlayLayer;
private MapTileLayer underlayLayer;
private StateChangedListener<Integer> overlayLayerListener;
public OsmandRasterMapsPlugin(OsmandApplication app) {
this.app = app;
super(app);
settings = app.getSettings();
}
@ -85,8 +86,8 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin {
}
@Override
public int getAssetResourceName() {
return R.drawable.online_maps;
public Drawable getAssetResourceImage() {
return app.getUIUtilities().getIcon(R.drawable.online_maps);
}
@Override

View file

@ -260,9 +260,9 @@ public class RendererRegistry {
if (lf != null) {
for (File f : lf) {
if (f != null && f.getName().endsWith(IndexConstants.ROUTING_AND_RENDERING_FILE_EXT)) {
if(!internalRenderers.containsValue(f.getName())) {
String name = f.getName().substring(0, f.getName().length() - IndexConstants.ROUTING_AND_RENDERING_FILE_EXT.length());
externalRenderers.put(name.replace('_', ' ').replace('-', ' '), f);
if (!internalRenderers.containsValue(f.getName())) {
String name = formatRendererFileName(f.getName());
externalRenderers.put(name, f);
}
}
}
@ -270,7 +270,12 @@ public class RendererRegistry {
}
this.externalRenderers = externalRenderers;
}
public static String formatRendererFileName(String fileName) {
String name = fileName.substring(0, fileName.length() - IndexConstants.ROUTING_AND_RENDERING_FILE_EXT.length());
return name.replace('_', ' ').replace('-', ' ');
}
public Collection<String> getRendererNames(){
LinkedHashSet<String> names = new LinkedHashSet<String>();
names.add(DEFAULT_RENDER);

View file

@ -31,6 +31,8 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.SQLiteTileSource;
import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.FileSettingsItem;
import net.osmand.plus.SettingsHelper.SettingsItem;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
@ -40,8 +42,8 @@ import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.quickaction.QuickActionRegistry;
import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet;
import net.osmand.plus.settings.ExportImportSettingsAdapter.Type;
import net.osmand.plus.settings.bottomsheets.BasePreferenceBottomSheet;
import org.apache.commons.logging.Log;
@ -241,7 +243,7 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
} else {
template = TileSourceManager.createTileSourceTemplate(f);
}
if (template != null && template.getUrlTemplate() != null) {
if (template.getUrlTemplate() != null) {
iTileSources.add(template);
}
}
@ -270,8 +272,8 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
return dataList;
}
private List<SettingsHelper.SettingsItem> prepareSettingsItemsForExport() {
List<SettingsHelper.SettingsItem> settingsItems = new ArrayList<>();
private List<SettingsItem> prepareSettingsItemsForExport() {
List<SettingsItem> settingsItems = new ArrayList<>();
settingsItems.add(new SettingsHelper.ProfileSettingsItem(app, profile));
if (includeAdditionalData) {
settingsItems.addAll(prepareAdditionalSettingsItems());
@ -279,8 +281,8 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
return settingsItems;
}
private List<SettingsHelper.SettingsItem> prepareAdditionalSettingsItems() {
List<SettingsHelper.SettingsItem> settingsItems = new ArrayList<>();
private List<SettingsItem> prepareAdditionalSettingsItems() {
List<SettingsItem> settingsItems = new ArrayList<>();
List<QuickAction> quickActions = new ArrayList<>();
List<PoiUIFilter> poiUIFilters = new ArrayList<>();
List<ITileSource> tileSourceTemplates = new ArrayList<>();
@ -294,13 +296,17 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
|| object instanceof SQLiteTileSource) {
tileSourceTemplates.add((ITileSource) object);
} else if (object instanceof File) {
settingsItems.add(new SettingsHelper.FileSettingsItem(app, (File) object));
try {
settingsItems.add(new FileSettingsItem(app, (File) object));
} catch (IllegalArgumentException e) {
LOG.warn("Trying to export unsuported file type", e);
}
} else if (object instanceof AvoidRoadInfo) {
avoidRoads.add((AvoidRoadInfo) object);
}
}
if (!quickActions.isEmpty()) {
settingsItems.add(new SettingsHelper.QuickActionSettingsItem(app, quickActions));
settingsItems.add(new SettingsHelper.QuickActionsSettingsItem(app, quickActions));
}
if (!poiUIFilters.isEmpty()) {
settingsItems.add(new SettingsHelper.PoiUiFilterSettingsItem(app, poiUIFilters));
@ -320,7 +326,7 @@ public class ExportProfileBottomSheet extends BasePreferenceBottomSheet {
showExportProgressDialog();
File tempDir = getTempDir();
String fileName = profile.toHumanString();
app.getSettingsHelper().exportSettings(tempDir, fileName, getSettingsExportListener(), prepareSettingsItemsForExport());
app.getSettingsHelper().exportSettings(tempDir, fileName, getSettingsExportListener(), prepareSettingsItemsForExport(), true);
}
}

View file

@ -112,7 +112,7 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
if (settingsItems != null) {
ImportedSettingsItemsAdapter adapter = new ImportedSettingsItemsAdapter(
app,
getSettingsToOperate(settingsItems),
getSettingsToOperate(settingsItems, true),
nightMode,
new ImportedSettingsItemsAdapter.OnItemClickListener() {
@Override

View file

@ -26,7 +26,6 @@ import androidx.fragment.app.FragmentManager;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.map.ITileSource;
import net.osmand.map.TileSourceManager;
@ -36,16 +35,25 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.SQLiteTileSource;
import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.*;
import net.osmand.plus.SettingsHelper.AvoidRoadsSettingsItem;
import net.osmand.plus.SettingsHelper.FileSettingsItem;
import net.osmand.plus.SettingsHelper.FileSettingsItem.FileSubtype;
import net.osmand.plus.SettingsHelper.ImportAsyncTask;
import net.osmand.plus.SettingsHelper.ImportType;
import net.osmand.plus.SettingsHelper.MapSourcesSettingsItem;
import net.osmand.plus.SettingsHelper.PoiUiFilterSettingsItem;
import net.osmand.plus.SettingsHelper.ProfileSettingsItem;
import net.osmand.plus.SettingsHelper.QuickActionsSettingsItem;
import net.osmand.plus.SettingsHelper.SettingsItem;
import net.osmand.plus.SettingsHelper.SettingsItemType;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.widgets.TextViewEx;
import net.osmand.plus.settings.ExportImportSettingsAdapter.Type;
import net.osmand.plus.widgets.TextViewEx;
import org.apache.commons.logging.Log;
@ -166,7 +174,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
adapter = new ExportImportSettingsAdapter(app, nightMode, true);
Map<Type, List<?>> itemsMap = new HashMap<>();
if (settingsItems != null) {
itemsMap = getSettingsToOperate(settingsItems);
itemsMap = getSettingsToOperate(settingsItems, false);
adapter.updateSettingsList(itemsMap);
}
expandableList.setAdapter(adapter);
@ -327,13 +335,13 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
|| object instanceof SQLiteTileSource) {
tileSourceTemplates.add((ITileSource) object);
} else if (object instanceof File) {
settingsItems.add(new SettingsHelper.FileSettingsItem(app, (File) object));
settingsItems.add(new FileSettingsItem(app, (File) object));
} else if (object instanceof AvoidRoadInfo) {
avoidRoads.add((AvoidRoadInfo) object);
}
}
if (!quickActions.isEmpty()) {
settingsItems.add(new SettingsHelper.QuickActionSettingsItem(app, quickActions));
settingsItems.add(new QuickActionsSettingsItem(app, quickActions));
}
if (!poiUIFilters.isEmpty()) {
settingsItems.add(new SettingsHelper.PoiUiFilterSettingsItem(app, poiUIFilters));
@ -347,7 +355,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
return settingsItems;
}
public static Map<Type, List<?>> getSettingsToOperate(List<SettingsItem> settingsItems) {
public static Map<Type, List<?>> getSettingsToOperate(List<SettingsItem> settingsItems, boolean importComplete) {
Map<Type, List<?>> settingsToOperate = new HashMap<>();
List<ApplicationMode.ApplicationModeBean> profiles = new ArrayList<>();
List<QuickAction> quickActions = new ArrayList<>();
@ -360,24 +368,41 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
for (SettingsItem item : settingsItems) {
if (item.getType().equals(SettingsItemType.PROFILE)) {
profiles.add(((ProfileSettingsItem) item).getModeBean());
} else if (item.getType().equals(SettingsItemType.QUICK_ACTION)) {
quickActions.addAll(((QuickActionSettingsItem) item).getItems());
quickActions.addAll(((QuickActionSettingsItem) item).getDuplicateItems());
} else if (item.getType().equals(SettingsItemType.QUICK_ACTIONS)) {
QuickActionsSettingsItem quickActionsItem = (QuickActionsSettingsItem) item;
if (importComplete) {
quickActions.addAll(quickActionsItem.getAppliedItems());
} else {
quickActions.addAll(quickActionsItem.getItems());
}
} else if (item.getType().equals(SettingsItemType.POI_UI_FILTERS)) {
poiUIFilters.addAll(((PoiUiFilterSettingsItem) item).getItems());
poiUIFilters.addAll(((PoiUiFilterSettingsItem) item).getDuplicateItems());
PoiUiFilterSettingsItem poiUiFilterItem = (PoiUiFilterSettingsItem) item;
if (importComplete) {
poiUIFilters.addAll(poiUiFilterItem.getAppliedItems());
} else {
poiUIFilters.addAll(poiUiFilterItem.getItems());
}
} else if (item.getType().equals(SettingsItemType.MAP_SOURCES)) {
tileSourceTemplates.addAll(((MapSourcesSettingsItem) item).getItems());
tileSourceTemplates.addAll(((MapSourcesSettingsItem) item).getDuplicateItems());
MapSourcesSettingsItem mapSourcesItem = (MapSourcesSettingsItem) item;
if (importComplete) {
tileSourceTemplates.addAll(mapSourcesItem.getAppliedItems());
} else {
tileSourceTemplates.addAll(mapSourcesItem.getItems());
}
} else if (item.getType().equals(SettingsItemType.FILE)) {
if (item.getName().contains(IndexConstants.RENDERERS_DIR)) {
renderFilesList.add(((FileSettingsItem) item).getFile());
} else if (item.getName().contains(IndexConstants.ROUTING_PROFILES_DIR)) {
routingFilesList.add(((FileSettingsItem) item).getFile());
FileSettingsItem fileItem = (FileSettingsItem) item;
if (fileItem.getSubtype() == FileSubtype.RENDERING_STYLE) {
renderFilesList.add(fileItem.getFile());
} else if (fileItem.getSubtype() == FileSubtype.ROUTING_CONFIG) {
routingFilesList.add(fileItem.getFile());
}
} else if (item.getType().equals(SettingsItemType.AVOID_ROADS)) {
avoidRoads.addAll(((AvoidRoadsSettingsItem) item).getItems());
avoidRoads.addAll(((AvoidRoadsSettingsItem) item).getDuplicateItems());
AvoidRoadsSettingsItem avoidRoadsItem = (AvoidRoadsSettingsItem) item;
if (importComplete) {
avoidRoads.addAll(avoidRoadsItem.getAppliedItems());
} else {
avoidRoads.addAll(avoidRoadsItem.getItems());
}
}
}

View file

@ -8,6 +8,7 @@ import androidx.preference.SwitchPreferenceCompat;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.profiles.ProfileDataObject;
@ -221,17 +222,23 @@ public class NavigationFragment extends BaseSettingsFragment {
false, null));
}
List<String> disabledRouterNames = new ArrayList<>();
for (OsmandPlugin plugin : OsmandPlugin.getNotEnabledPlugins()) {
disabledRouterNames.addAll(plugin.getRouterNames());
}
for (RoutingConfiguration.Builder builder : context.getAllRoutingConfigs()) {
collectRoutingProfilesFromConfig(context, builder, profilesObjects);
collectRoutingProfilesFromConfig(context, builder, profilesObjects, disabledRouterNames);
}
return profilesObjects;
}
private static void collectRoutingProfilesFromConfig(OsmandApplication app, RoutingConfiguration.Builder builder, Map<String, RoutingProfileDataObject> profilesObjects) {
private static void collectRoutingProfilesFromConfig(OsmandApplication app, RoutingConfiguration.Builder builder,
Map<String, RoutingProfileDataObject> profilesObjects, List<String> disabledRouterNames) {
for (Map.Entry<String, GeneralRouter> entry : builder.getAllRouters().entrySet()) {
String routerKey = entry.getKey();
GeneralRouter router = entry.getValue();
if (!routerKey.equals("geocoding")) {
if (!routerKey.equals("geocoding") && !disabledRouterNames.contains(router.getFilename())) {
int iconRes = R.drawable.ic_action_gdirections_dark;
String name = router.getProfileName();
String description = app.getString(R.string.osmand_default_routing);

View file

@ -770,7 +770,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment {
tempDir.mkdirs();
}
app.getSettingsHelper().exportSettings(tempDir, mode.getStringKey(),
getSettingsExportListener(), new SettingsHelper.ProfileSettingsItem(app, mode));
getSettingsExportListener(), true, new SettingsHelper.ProfileSettingsItem(app, mode));
}
}

View file

@ -1,14 +1,12 @@
package net.osmand.plus.skimapsplugin;
import android.app.Activity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.graphics.drawable.Drawable;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.render.RendererRegistry;
import java.util.Collections;
import java.util.List;
@ -18,10 +16,8 @@ public class SkiMapsPlugin extends OsmandPlugin {
public static final String ID = "skimaps.plugin";
public static final String COMPONENT = "net.osmand.skimapsPlugin";
private OsmandApplication app;
public SkiMapsPlugin(OsmandApplication app) {
this.app = app;
super(app);
}
@Override
@ -40,8 +36,8 @@ public class SkiMapsPlugin extends OsmandPlugin {
}
@Override
public int getAssetResourceName() {
return R.drawable.ski_map;
public Drawable getAssetResourceImage() {
return app.getUIUtilities().getIcon(R.drawable.ski_map);
}
@Override
@ -59,30 +55,19 @@ public class SkiMapsPlugin extends OsmandPlugin {
return "feature_articles/ski-plugin.html";
}
@Override
public boolean init(@NonNull final OsmandApplication app, final Activity activity) {
if (activity != null) {
// called from UI
ApplicationMode.changeProfileAvailability(ApplicationMode.SKI, true, app);
}
return true;
}
@Override
public void onInstall(@NonNull OsmandApplication app, @Nullable Activity activity) {
ApplicationMode.changeProfileAvailability(ApplicationMode.SKI, true, app);
super.onInstall(app, activity);
}
@Override
public List<ApplicationMode> getAddedAppModes() {
return Collections.singletonList(ApplicationMode.SKI);
}
@Override
public void disable(OsmandApplication app) {
super.disable(app);
ApplicationMode.changeProfileAvailability(ApplicationMode.SKI, false, app);
public List<String> getRendererNames() {
return Collections.singletonList(RendererRegistry.WINTER_SKI_RENDER);
}
@Override
public List<String> getRouterNames() {
return Collections.singletonList("ski");
}
@Override

View file

@ -3,6 +3,7 @@ package net.osmand.plus.srtmplugin;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.widget.ArrayAdapter;
@ -62,19 +63,17 @@ public class SRTMPlugin extends OsmandPlugin {
public static final int TERRAIN_MIN_ZOOM = 3;
public static final int TERRAIN_MAX_ZOOM = 19;
private OsmandApplication app;
private OsmandSettings settings;
private boolean paid;
private TerrainLayer terrainLayer;
@Override
public String getId() {
return paid ? ID : FREE_ID;
return FREE_ID;
}
public SRTMPlugin(OsmandApplication app) {
this.app = app;
super(app);
settings = app.getSettings();
}
@ -84,8 +83,8 @@ public class SRTMPlugin extends OsmandPlugin {
}
@Override
public int getAssetResourceName() {
return R.drawable.contour_lines;
public Drawable getAssetResourceImage() {
return app.getUIUtilities().getIcon(R.drawable.contour_lines);
}
@Override

View file

@ -1,8 +1,8 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
compileSdkVersion 28
buildToolsVersion "28.0.3"
signingConfigs {
development {

View file

@ -1,8 +1,8 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
compileSdkVersion 28
buildToolsVersion "28.0.3"
signingConfigs {
development {

View file

@ -1,8 +1,8 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
compileSdkVersion 28
buildToolsVersion "28.0.3"
signingConfigs {
development {

View file

@ -1,8 +1,8 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
compileSdkVersion 28
buildToolsVersion "28.0.3"
signingConfigs {
development {