diff --git a/CHANGELOG.json b/CHANGELOG.json
index 39f1664..ef8eadc 100644
--- a/CHANGELOG.json
+++ b/CHANGELOG.json
@@ -16,6 +16,7 @@
,"49ee98cf1acc59441b01a2b9505cbdee367ff317": "Update Privacy Policy to include Nominatim and ArcGIS World Imagery."
,"c370065a08cf78836e5e052912bdd331d634f143": "Add progress circle when the search is running so users know when it is done."
,"8043699f99a2d8ce7d862f51d49f15ef1b7a360e": "Fix the search of the main map. It would not open the map at the search location but now does."
+ ,"1a81d2208e95ebff35ca2c3ba49d28fd8a45204e": "Add the ability to upload plants to self-hosted servers using the na-ovoce.cz API."
,"13a52d003db6088b7cc445eec5fab04df5935514": "Add a text if the search has no results."
,"607ff6a9c8c6d841ba407c15911e8ef4fea4fc42": "Fix bug: The search order of the saved results is kept and not reversed."
}
diff --git a/app/src/main/java/eu/quelltext/mundraub/activities/SettingsActivity.java b/app/src/main/java/eu/quelltext/mundraub/activities/SettingsActivity.java
index 60fb1a5..882bf35 100644
--- a/app/src/main/java/eu/quelltext/mundraub/activities/SettingsActivity.java
+++ b/app/src/main/java/eu/quelltext/mundraub/activities/SettingsActivity.java
@@ -47,6 +47,7 @@
public class SettingsActivity extends MundraubBaseActivity {
private static BackgroundDownloadTask mapDownload = null;
+ private static final String NA_OVOCE_GITHUB_URL = "https://github.com/jsmesami/naovoce";
private ProgressBar updateProgress;
final Handler handler = new Handler();
@@ -231,7 +232,27 @@ public void onClick(View v) {
});
updateProgressMap = (ProgressBar) findViewById(R.id.update_progress_map);
updateMapOfflineButtons();
+ EditText customNaOvoceDomain = (EditText) findViewById(R.id.my_na_ovoce_server_domain);
+ customNaOvoceDomain.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+ @Override
+ public void afterTextChanged(Editable s) {
+ String url = s.toString();
+ Settings.setCustomNaOvoceHost(url.isEmpty() ? Settings.DEFAULT_CUSTOM_NA_OVOCE_DOMAIN : url);
+ }
+ });
+ customNaOvoceDomain.setHint(Settings.DEFAULT_CUSTOM_NA_OVOCE_DOMAIN);
+ Button setupNaOvoce = (Button) findViewById(R.id.button_setup_na_ovoce);
+ setupNaOvoce.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ openURLInBrowser(NA_OVOCE_GITHUB_URL);
+ }
+ });
}
private void buttonStartMapDownloadClicked(){
@@ -410,7 +431,8 @@ protected void onPause() {
}
private void update() {
- apiRadioGroup.check(API.instance().radioButtonId());
+ API api = API.instance();
+ apiRadioGroup.check(api.radioButtonId());
apiRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
@@ -422,6 +444,8 @@ public void onCheckedChanged(RadioGroup group, int checkedId) {
update();
}
});
+ View customInputs = findViewById(R.id.custom_na_ovoce_inputs);
+ customInputs.setVisibility(api.isCustomNaOvoceAPI() ? View.VISIBLE : View.GONE);
synchronizeBooleanSetting(R.id.toggle_secure_connection, new Toggled() {
@Override
public int onToggle(boolean checked) {
diff --git a/app/src/main/java/eu/quelltext/mundraub/api/API.java b/app/src/main/java/eu/quelltext/mundraub/api/API.java
index 1b38979..1ecf85d 100644
--- a/app/src/main/java/eu/quelltext/mundraub/api/API.java
+++ b/app/src/main/java/eu/quelltext/mundraub/api/API.java
@@ -25,7 +25,10 @@ public abstract class API extends AsyncNetworkInteraction implements BackgroundD
private boolean isLoggedIn;
public static API[] all() {
- return new API[]{DUMMY, MUNDRAUB, FRUITMAP, NA_OVOCE};
+ return new API[]{
+ DUMMY, MUNDRAUB, FRUITMAP, NA_OVOCE,
+ new CustomNaOvoceAPI(Settings.getCustomNaOvoceHost())
+ };
}
public static API instance() {
@@ -157,5 +160,7 @@ public Set getDownloadUrls() {
public abstract String getPlantUrl(String id);
public abstract int nameResourceId();
-
+ public boolean isCustomNaOvoceAPI() {
+ return false;
+ }
}
diff --git a/app/src/main/java/eu/quelltext/mundraub/api/CustomNaOvoceAPI.java b/app/src/main/java/eu/quelltext/mundraub/api/CustomNaOvoceAPI.java
new file mode 100644
index 0000000..50ead74
--- /dev/null
+++ b/app/src/main/java/eu/quelltext/mundraub/api/CustomNaOvoceAPI.java
@@ -0,0 +1,39 @@
+package eu.quelltext.mundraub.api;
+
+import eu.quelltext.mundraub.R;
+import eu.quelltext.mundraub.common.Settings;
+
+public class CustomNaOvoceAPI extends NaOvoceAPI {
+
+
+ private final String host;
+
+ public CustomNaOvoceAPI(String host) {
+ this.host = host;
+ }
+
+ @Override
+ protected String host() {
+ return host;
+ }
+
+ @Override
+ public String id() {
+ return Settings.API_ID_MY_NA_OVOCE;
+ }
+
+ @Override
+ public int nameResourceId() {
+ return R.string.login_api_name_my_na_ovoce;
+ }
+
+ @Override
+ public boolean isCustomNaOvoceAPI() {
+ return true;
+ }
+
+ @Override
+ public int radioButtonId() {
+ return R.id.radioButton_my_na_ovoce;
+ }
+}
diff --git a/app/src/main/java/eu/quelltext/mundraub/api/NaOvoceAPI.java b/app/src/main/java/eu/quelltext/mundraub/api/NaOvoceAPI.java
index bad8ec7..36e14c2 100644
--- a/app/src/main/java/eu/quelltext/mundraub/api/NaOvoceAPI.java
+++ b/app/src/main/java/eu/quelltext/mundraub/api/NaOvoceAPI.java
@@ -232,7 +232,7 @@ public int radioButtonId(){
}
public String getPlantUrl(String id) {
- return "https://na-ovoce.cz/fruit/detail/" + id + "/";
+ return host() + "/fruit/detail/" + id + "/";
};
@Override
diff --git a/app/src/main/java/eu/quelltext/mundraub/common/Settings.java b/app/src/main/java/eu/quelltext/mundraub/common/Settings.java
index 3ea96ae..fcc4a11 100644
--- a/app/src/main/java/eu/quelltext/mundraub/common/Settings.java
+++ b/app/src/main/java/eu/quelltext/mundraub/common/Settings.java
@@ -48,12 +48,14 @@ public class Settings {
public static final String API_ID_MUNDRAUB = "mundraub";
public static final String API_ID_NA_OVOCE = "na-ovoce";
+ public static final String API_ID_MY_NA_OVOCE = "my-na-ovoce";
public static final String API_ID_DUMMY = "dummy";
public static final String API_ID_FRUITMAP = "fruitmap";
public static final String API_ID_COMMUNITY = "community"; // only for markers
public static final String TILES_OSM = "osm";
public static final String TILES_SATELLITE = "satellite";
+ public static final String DEFAULT_CUSTOM_NA_OVOCE_DOMAIN = "http://na-ovoce.cz";
private static final String PLANT_STORAGE_DIRECTORY_NAME = "eu.quelltext.mundraub";
public static final String INVALID_HASH = "0000000000000000000000000000000000000000";
@@ -139,6 +141,7 @@ public void setChecked(String apiId, boolean checked) {
* https://github.com/niccokunzmann/mundraub-android/commit/1d8bf40aa68d71cd35eb65e0e25986f6a8a1913e#diff-6cf4fcc1ccb27f70ca10a1b54612d568
*/
private static String useAPIId = API_ID_MUNDRAUB;
+ private static String customNaOvoceHost = DEFAULT_CUSTOM_NA_OVOCE_DOMAIN;
private static boolean useInsecureConnections = false;
private static boolean useCacheForPlants = true;
private static File persistentPathForPlants = new File(Environment.getExternalStorageDirectory(), PLANT_STORAGE_DIRECTORY_NAME);
@@ -181,6 +184,7 @@ public static void print() {
log.d("Permissions.CAN_ASK_FOR_PERMISSIONS", Permissions.CAN_ASK_FOR_PERMISSIONS);
log.d("useInsecureConnections", useInsecureConnections);
log.d("useAPIId", useAPIId);
+ log.d("customNaOvoceHost", customNaOvoceHost);
log.d("useCacheForPlants", useCacheForPlants);
log.d("useErrorReport", useErrorReport);
log.d("useOfflineMapAPI", useOfflineMapAPI);
@@ -213,6 +217,7 @@ private static void load() {
useOfflineMapAPI = preferences.getBoolean("useOfflineMapAPI", useOfflineMapAPI);
debugMundraubMapAPI = preferences.getBoolean("debugMundraubMapAPI", debugMundraubMapAPI);
vibrateWhenPlantIsInRange = preferences.getBoolean("vibrateWhenPlantIsInRange", vibrateWhenPlantIsInRange);
+ customNaOvoceHost = preferences.getString("customNaOvoceHost", customNaOvoceHost);
useFruitRadarNotifications = preferences.getBoolean("useFruitRadarNotifications", useFruitRadarNotifications);
maximumDisplayedMarkers = preferences.getInt("maximumDisplayedMarkers", maximumDisplayedMarkers);
radarPlantRangeMeters = preferences.getInt("radarPlantRangeMeters", radarPlantRangeMeters);
@@ -248,6 +253,7 @@ private static int commit() {
editor.putBoolean("useOfflineMapAPI", useOfflineMapAPI);
editor.putBoolean("debugMundraubMapAPI", debugMundraubMapAPI);
editor.putBoolean("vibrateWhenPlantIsInRange", vibrateWhenPlantIsInRange);
+ editor.putString("customNaOvoceHost", customNaOvoceHost);
editor.putBoolean("useFruitRadarNotifications", useFruitRadarNotifications);
editor.putInt("maximumDisplayedMarkers", maximumDisplayedMarkers);
editor.putInt("radarPlantRangeMeters", radarPlantRangeMeters);
@@ -366,6 +372,15 @@ public static int vibrateWhenPlantIsInRange(boolean isChecked) {
return commit();
}
+ public static String getCustomNaOvoceHost() {
+ return customNaOvoceHost;
+ }
+
+ public static int setCustomNaOvoceHost(String customNaOvoceHost) {
+ Settings.customNaOvoceHost = customNaOvoceHost;
+ return commit();
+ }
+
public static boolean useCacheForPlants() {
return useCacheForPlants;
}
diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml
index fb24d91..59ee4f2 100644
--- a/app/src/main/res/layout/activity_settings.xml
+++ b/app/src/main/res/layout/activity_settings.xml
@@ -297,6 +297,38 @@
android:layout_weight="1"
android:text="@string/settings_use_na_ovoce" />
+
+
+
+
+
+
+
+
+
Mundraub.org
Na-Ovoce.cz
+
+ Custom Na-Ovoce Server
Local Dummy API
@@ -412,6 +414,8 @@
If this is enabled, this app publishes the plants to Na-Ovoce.cz.
+ If this is enabled, this app publishes the plants to a self-hosted Na-Ovoce server.
+
If this is enabled, this app publishes the plants to FruitMap.org.
If this is enabled, this app does not publish the plants but instead simulates a local API for testing.
@@ -535,6 +539,8 @@
All selected parts of the map have been downloaded and are now available offline.
Maximum of %1$d markers will be displayed on map.
+
+ Setup