diff --git a/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java b/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java
index e3d162826c..7f5c008efd 100644
--- a/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java
+++ b/OsmAnd-java/src/main/java/net/osmand/osm/io/NetworkUtils.java
@@ -56,6 +56,55 @@ public class NetworkUtils {
return e.getMessage();
}
}
+
+ public static String sendPostDataRequest(String urlText, InputStream data) {
+ try {
+ log.info("POST : " + urlText);
+ HttpURLConnection conn = getHttpURLConnection(urlText);
+ conn.setDoInput(true);
+ conn.setDoOutput(false);
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("Accept", "*/*");
+ conn.setRequestProperty("User-Agent", "OsmAnd"); //$NON-NLS-1$ //$NON-NLS-2$
+ conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
+ OutputStream ous = conn.getOutputStream();
+ ous.write(("--" + BOUNDARY + "\r\n").getBytes());
+ ous.write(("content-disposition: form-data; name=\"" + "file" + "\"; filename=\"" + "image1" + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
+ ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$
+ Algorithms.streamCopy(data, ous);
+ ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
+ ous.flush();
+ log.info("Response code and message : " + conn.getResponseCode() + " " + conn.getResponseMessage());
+ if (conn.getResponseCode() != 200) {
+ return null;
+ }
+ StringBuilder responseBody = new StringBuilder();
+ InputStream is = conn.getInputStream();
+ responseBody.setLength(0);
+ if (is != null) {
+ BufferedReader in = new BufferedReader(new InputStreamReader(is, "UTF-8")); //$NON-NLS-1$
+ String s;
+ boolean first = true;
+ while ((s = in.readLine()) != null) {
+ if (first) {
+ first = false;
+ } else {
+ responseBody.append("\n"); //$NON-NLS-1$
+ }
+ responseBody.append(s);
+ }
+ is.close();
+ }
+ Algorithms.closeStream(is);
+ Algorithms.closeStream(data);
+ Algorithms.closeStream(ous);
+ return responseBody.toString();
+ } catch (IOException e) {
+ log.error(e.getMessage(), e);
+ return e.getMessage();
+ }
+ }
+
private static final String BOUNDARY = "CowMooCowMooCowCowCow"; //$NON-NLS-1$
public static String uploadFile(String urlText, File fileToUpload, String userNamePassword,
OsmOAuthAuthorizationClient client,
diff --git a/OsmAnd/build.gradle b/OsmAnd/build.gradle
index a3a613bc9a..919b243ac3 100644
--- a/OsmAnd/build.gradle
+++ b/OsmAnd/build.gradle
@@ -197,14 +197,12 @@ android {
buildTypes {
debug {
- buildConfigField "String", "OPR_BASE_URL", "\"https://test.openplacereviews.org/\""
signingConfig signingConfigs.development
debuggable false
jniDebuggable false
buildConfigField "boolean", "USE_DEBUG_LIBRARIES", "false"
}
release {
- buildConfigField "String", "OPR_BASE_URL", "\"https://test.openplacereviews.org/\""
signingConfig signingConfigs.publishing
}
}
@@ -512,4 +510,6 @@ dependencies {
implementation 'com.jaredrummler:colorpicker:1.1.0'
freehuaweiImplementation 'com.huawei.hms:iap:5.0.2.300'
+
+ implementation "org.bouncycastle:bcpkix-jdk15on:1.56"
}
diff --git a/OsmAnd/no_translate.xml b/OsmAnd/no_translate.xml
index 719b6ee8fe..20d7a424ca 100644
--- a/OsmAnd/no_translate.xml
+++ b/OsmAnd/no_translate.xml
@@ -41,4 +41,9 @@
items modified
OsmAnd Unlimited
Markers
+ https://test.openplacereviews.org/
+ v8G8r9NLJZGMV4he5lwbQlz620FNVARKjI9Bm5UJ
+ jDvM95Ne1Bq2BDTmIfB6b3ZMxvdK87WGfp6DC07J
+ Ti2qq3fo4i4Wmuox3SiWRIGq3obZisBHnxmcM05y
+ lxulb3HYoMmd2cC4xxNe1dyfRMAY8dS0eNihJ0DM
diff --git a/OsmAnd/res/layout/custom_radio_buttons.xml b/OsmAnd/res/layout/custom_radio_buttons.xml
index 460356e875..d768e58004 100644
--- a/OsmAnd/res/layout/custom_radio_buttons.xml
+++ b/OsmAnd/res/layout/custom_radio_buttons.xml
@@ -26,18 +26,27 @@
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:textSize="@dimen/default_desc_text_size"
- android:textColor="@drawable/radio_flat_text_selector_light"
osmand:typeface="@string/font_roboto_medium"
tools:text="@string/shared_string_left"/>
+ android:layout_weight="1"
+ android:visibility="gone">
+
+
@@ -53,9 +62,8 @@
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:gravity="center"
- android:textColor="@drawable/radio_flat_text_selector_light"
- osmand:typeface="@string/font_roboto_medium"
android:textSize="@dimen/default_desc_text_size"
+ osmand:typeface="@string/font_roboto_medium"
tools:text="@string/shared_string_right"/>
diff --git a/OsmAnd/res/layout/fragment_measurement_tool.xml b/OsmAnd/res/layout/fragment_measurement_tool.xml
index 82cd085ec9..2fe4dc1416 100644
--- a/OsmAnd/res/layout/fragment_measurement_tool.xml
+++ b/OsmAnd/res/layout/fragment_measurement_tool.xml
@@ -30,23 +30,22 @@
+ tools:src="@drawable/ic_action_ruler"/>
-
-
-
+
+
@@ -160,11 +150,6 @@
-
-
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?attr/bg_color"
+ android:clickable="true"
+ android:focusable="true"
+ android:orientation="vertical">
-
+
-
+
+
+
+
+ android:layout_marginLeft="@dimen/content_padding"
+ android:layout_marginTop="@dimen/content_padding"
+ android:layout_marginRight="@dimen/content_padding"
+ android:layout_marginBottom="@dimen/dashPadding"
+ android:gravity="center_horizontal"
+ android:lineSpacingMultiplier="@dimen/bottom_sheet_text_spacing_multiplier"
+ android:text="@string/register_on_openplacereviews"
+ android:textAlignment="center"
+ android:textColor="?android:textColorPrimary"
+ android:textSize="20sp"
+ app:typeface="@string/font_roboto_medium" />
-
-
-
-
-
-
-
+
+
+
+ OsmAnd shows photos from several sources:\nOpenPlaceReviews - POI photos;\nMapillary - street-level imagery;\nWeb / Wikimedia - POI photos specified in OpenStreetMap data.
Use dev.openstreetmap.org
Switch to use "dev.openstreetmap.org" instead of "openstreetmap.org" to testing uploading OSM Note / POI / GPX.
+ Add to OpenPlaceReviews
+ Add to Mapillary
Select items that will be imported.
Select groups that will be imported.
There is not enough space
@@ -21,18 +24,17 @@
Select the data to be exported to the file.
Approximate file size
Resources
- OsmAnd shows photos from several sources:\nOpenPlaceReviews - POI photos;\nMapillary - street-level imagery;\nWeb / Wikimedia - POI photos specified in OpenStreetMap data.
- Add to OpenPlaceReviews
- Add to Mapillary
+ Select picture
+ Cannot upload image, please, try again later
Motorboat
Kayak
Search history
I already have an account
Create new account
- Log in on the open data project website OpenPlaceReviews.org to upload even more photos.
+ Photos are provided by open data project OpenPlaceReviews.org. In order to upload your photos you need to sign up on website.
Register on\nOpenPlaceReviews.org
Add photo
- Log in using the safe OAuth method or use your username and password.
+ You can log in using the safe OAuth method or use your login and password.
Comment OSM Note
Close OSM Note
\"Trackable\" means the trace does not show up in any public listings, but processed trackpoints with timestamps from it (that can\'t be associated with you directly) do through downloads from the public GPS API.
@@ -47,15 +49,15 @@
OsmAnd Live subscription has been expired
There is a problem with your subscription. Click the button to go to the Google Play subscription settings to fix your payment method.
Manage subscription
- Username
+ Login
Password
Account
- Log in with username and password
- Log in to upload new or modified changes,\n\neither with OAuth or using your username and password.
+ Use login and password
+ You need to login to upload new or modified changes. \n\nYou can log in using the safe OAuth method or use your login and password.
You can view all your not yet uploaded edits or OSM bugs in %1$s. Uploaded points don’t show in OsmAnd.
- Log in with OpenStreetMap
- Login for OpenStreetMap.org
- Login for OpenStreetMap
+ Sign in with OpenStreetMap
+ Login to OpenStreetMap.org
+ Login to OpenStreetMap
These plugin setting are global, and apply to all profiles
You need to add at least two points
Travel
diff --git a/OsmAnd/src/net/osmand/plus/OsmAndConstants.java b/OsmAnd/src/net/osmand/plus/OsmAndConstants.java
index 16a5312405..aee7b58bfa 100644
--- a/OsmAnd/src/net/osmand/plus/OsmAndConstants.java
+++ b/OsmAnd/src/net/osmand/plus/OsmAndConstants.java
@@ -12,10 +12,5 @@ public interface OsmAndConstants {
public int UI_HANDLER_PROGRESS = 6000;
public int UI_HANDLER_SEARCH = 7000;
-
- String OSM_OAUTH_DEVELOPER_KEY = "v8G8r9NLJZGMV4he5lwbQlz620FNVARKjI9Bm5UJ";
- String OSM_OAUTH_DEVELOPER_SECRET = "jDvM95Ne1Bq2BDTmIfB6b3ZMxvdK87WGfp6DC07J";
- String OSM_OAUTH_CONSUMER_KEY = "Ti2qq3fo4i4Wmuox3SiWRIGq3obZisBHnxmcM05y";
- String OSM_OAUTH_CONSUMER_SECRET = "lxulb3HYoMmd2cC4xxNe1dyfRMAY8dS0eNihJ0DM";
-
+
}
diff --git a/OsmAnd/src/net/osmand/plus/UiUtilities.java b/OsmAnd/src/net/osmand/plus/UiUtilities.java
index 97ba206fb0..f818716730 100644
--- a/OsmAnd/src/net/osmand/plus/UiUtilities.java
+++ b/OsmAnd/src/net/osmand/plus/UiUtilities.java
@@ -141,7 +141,7 @@ public class UiUtilities {
}
public Drawable getLayeredIcon(@DrawableRes int bgIconId, @DrawableRes int foregroundIconId,
- @ColorRes int bgColorId, @ColorRes int foregroundColorId) {
+ @ColorRes int bgColorId, @ColorRes int foregroundColorId) {
Drawable background = getDrawable(bgIconId, bgColorId);
Drawable foreground = getDrawable(foregroundIconId, foregroundColorId);
return getLayeredIcon(background, foreground);
@@ -272,11 +272,11 @@ public class UiUtilities {
}
public void updateLocationView(UpdateLocationViewCache cache, ImageView arrow, TextView txt,
- double toLat, double toLon) {
+ double toLat, double toLon) {
updateLocationView(cache, arrow, txt, new LatLon(toLat, toLon));
}
public void updateLocationView(UpdateLocationViewCache cache, ImageView arrow, TextView txt,
- LatLon toLoc) {
+ LatLon toLoc) {
float[] mes = new float[2];
boolean stale = false;
LatLon fromLoc = cache == null ? null : cache.specialFrom;
@@ -390,7 +390,7 @@ public class UiUtilities {
}
public static void setupSnackbar(Snackbar snackbar, boolean nightMode, @ColorRes Integer backgroundColor,
- @ColorRes Integer messageColor, @ColorRes Integer actionColor, Integer maxLines) {
+ @ColorRes Integer messageColor, @ColorRes Integer actionColor, Integer maxLines) {
if (snackbar == null) {
return;
}
@@ -451,7 +451,7 @@ public class UiUtilities {
public static void updateCustomRadioButtons(Context app, View buttonsView, boolean nightMode,
- CustomRadioButtonType buttonType) {
+ CustomRadioButtonType buttonType) {
int activeColor = ContextCompat.getColor(app, nightMode
? R.color.active_color_primary_dark
: R.color.active_color_primary_light);
@@ -478,7 +478,7 @@ public class UiUtilities {
endButtonText.setTextColor(activeColor);
startButtonContainer.setBackgroundDrawable(background);
startButtonText.setTextColor(textColor);
- } else if (buttonType == CustomRadioButtonType.END) {
+ } else {
if (isLayoutRtl) {
background.setCornerRadii(new float[]{radius, radius, 0, 0, 0, 0, radius, radius});
} else {
@@ -488,11 +488,6 @@ public class UiUtilities {
endButtonText.setTextColor(textColor);
startButtonContainer.setBackgroundColor(Color.TRANSPARENT);
startButtonText.setTextColor(activeColor);
- } else if (buttonType == null) {
- endButtonContainer.setBackgroundColor(Color.TRANSPARENT);
- startButtonContainer.setBackgroundColor(Color.TRANSPARENT);
- endButtonText.setTextColor(activeColor);
- startButtonText.setTextColor(activeColor);
}
}
@@ -507,10 +502,10 @@ public class UiUtilities {
}
public static void setupCompoundButton(boolean nightMode, @ColorInt int activeColor, CompoundButton compoundButton) {
- if (compoundButton == null) {
- return;
- }
- Context ctx = compoundButton.getContext();
+ if (compoundButton == null) {
+ return;
+ }
+ Context ctx = compoundButton.getContext();
int inactiveColorPrimary = ContextCompat.getColor(ctx, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_secondary_light);
int inactiveColorSecondary = getColorWithAlpha(inactiveColorPrimary, 0.45f);
setupCompoundButton(compoundButton, activeColor, inactiveColorPrimary, inactiveColorSecondary);
@@ -589,7 +584,7 @@ public class UiUtilities {
}
public static void setupSlider(Slider slider, boolean nightMode,
- @ColorInt Integer activeColor, boolean showTicks) {
+ @ColorInt Integer activeColor, boolean showTicks) {
Context ctx = slider.getContext();
if (ctx == null) {
return;
@@ -775,9 +770,9 @@ public class UiUtilities {
}
public static ListPopupWindow createListPopupWindow(Context themedCtx,
- View v, int minWidth,
- List items,
- final AdapterView.OnItemClickListener listener) {
+ View v, int minWidth,
+ List items,
+ final AdapterView.OnItemClickListener listener) {
int contentPadding = themedCtx.getResources().getDimensionPixelSize(R.dimen.content_padding);
int contentPaddingHalf = themedCtx.getResources().getDimensionPixelSize(R.dimen.content_padding_half);
int defaultListTextSize = themedCtx.getResources().getDimensionPixelSize(R.dimen.default_list_text_size);
diff --git a/OsmAnd/src/net/osmand/plus/helpers/SearchHistoryHelper.java b/OsmAnd/src/net/osmand/plus/helpers/SearchHistoryHelper.java
index 0f4af1f68d..693227f434 100644
--- a/OsmAnd/src/net/osmand/plus/helpers/SearchHistoryHelper.java
+++ b/OsmAnd/src/net/osmand/plus/helpers/SearchHistoryHelper.java
@@ -376,7 +376,10 @@ public class SearchHistoryHelper {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
- removeQuery(e.getSerializedName(), db);
+ db.execSQL("DELETE FROM " + HISTORY_TABLE_NAME + " WHERE " +
+ HISTORY_COL_NAME + " = ? AND " +
+ HISTORY_COL_LAT + " = ? AND " + HISTORY_COL_LON + " = ?",
+ new Object[] {e.getSerializedName(), e.getLat(), e.getLon()});
} finally {
db.close();
}
@@ -385,11 +388,6 @@ public class SearchHistoryHelper {
return false;
}
- private void removeQuery(String name, SQLiteConnection db) {
- db.execSQL("DELETE FROM " + HISTORY_TABLE_NAME + " WHERE " + HISTORY_COL_NAME + " = ?",
- new Object[]{name});
- }
-
public boolean removeAll() {
SQLiteConnection db = openConnection(false);
if (db != null) {
@@ -411,9 +409,10 @@ public class SearchHistoryHelper {
"UPDATE " + HISTORY_TABLE_NAME + " SET " + HISTORY_COL_TIME + "= ? " +
", " + HISTORY_COL_FREQ_INTERVALS + " = ? " +
", " + HISTORY_COL_FREQ_VALUES + "= ? WHERE " +
- HISTORY_COL_NAME + " = ?",
- new Object[]{e.getLastAccessTime(), e.getIntervals(), e.getIntervalsValues(),
- e.getSerializedName()});
+ HISTORY_COL_NAME + " = ? AND " +
+ HISTORY_COL_LAT + " = ? AND " + HISTORY_COL_LON + " = ?",
+ new Object[] {e.getLastAccessTime(), e.getIntervals(), e.getIntervalsValues(),
+ e.getSerializedName(), e.getLat(), e.getLon()});
} finally {
db.close();
}
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java
index 67f53b96ea..0a6fa296d0 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java
@@ -6,9 +6,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.ColorStateList;
-import android.graphics.Color;
-import android.graphics.PorterDuff;
-import android.graphics.Typeface;
+import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.net.Uri;
@@ -33,11 +31,14 @@ import androidx.appcompat.view.ContextThemeWrapper;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import net.osmand.AndroidUtils;
+import net.osmand.PlatformUtil;
import net.osmand.data.Amenity;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.data.QuadRect;
+import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.*;
+import net.osmand.plus.activities.ActivityResultListener;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.mapcontextmenu.builders.cards.AbstractCard;
@@ -47,6 +48,9 @@ import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask
import net.osmand.plus.mapcontextmenu.builders.cards.NoImagesCard;
import net.osmand.plus.mapcontextmenu.controllers.TransportStopController;
import net.osmand.plus.openplacereviews.AddPhotosBottomSheetDialogFragment;
+import net.osmand.plus.openplacereviews.OPRWebviewActivity;
+import net.osmand.plus.openplacereviews.OprStartFragment;
+import net.osmand.plus.osmedit.opr.OpenDBAPI;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.transport.TransportStopRoute;
@@ -56,13 +60,21 @@ import net.osmand.plus.widgets.TextViewEx;
import net.osmand.plus.widgets.tools.ClickableSpanTouchListener;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
+import org.apache.commons.logging.Log;
+import org.openplacereviews.opendb.util.exception.FailedVerificationException;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
import java.util.*;
import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener;
public class MenuBuilder {
+ private static final int PICK_IMAGE = 1231;
+ private static final Log LOG = PlatformUtil.getLog(MenuBuilder.class);
public static final float SHADOW_HEIGHT_TOP_DP = 17f;
public static final int TITLE_LIMIT = 60;
protected static final String[] arrowChars = new String[] {"=>", " - "};
@@ -92,6 +104,34 @@ public class MenuBuilder {
private String preferredMapAppLang;
private boolean transliterateNames;
+ private final OpenDBAPI openDBAPI = new OpenDBAPI();
+ private String[] placeId = new String[0];
+ private GetImageCardsListener imageCardListener = new GetImageCardsListener() {
+ @Override
+ public void onPostProcess(List cardList) {
+ processOnlinePhotosCards(cardList);
+ }
+
+ @Override
+ public void onPlaceIdAcquired(String[] placeId) {
+ MenuBuilder.this.placeId = placeId;
+ }
+
+ @Override
+ public void onFinish(List cardList) {
+ if (!isHidden()) {
+ List cards = new ArrayList(cardList);
+ if (cardList.size() == 0) {
+ cards.add(new NoImagesCard(mapActivity));
+ }
+ if (onlinePhotoCardsRow != null) {
+ onlinePhotoCardsRow.setCards(cards);
+ }
+ onlinePhotoCards = cards;
+ }
+ }
+ };
+
public interface CollapseExpandListener {
void onCollapseExpand(boolean collapsed);
}
@@ -336,8 +376,43 @@ public class MenuBuilder {
b.setTypeface(null, Typeface.BOLD);
b.setText(context.getResources().getString(R.string.shared_string_add_photo));
b.setBackgroundResource(R.drawable.btn_border_light);
- //TODO This feature is under development
- b.setVisibility(View.VISIBLE);
+ b.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(final View view) {
+ if (false) {
+ AddPhotosBottomSheetDialogFragment.showInstance(mapActivity.getSupportFragmentManager());
+ } else {
+ registerResultListener(view);
+ final String privateKey = OPRWebviewActivity.getPrivateKeyFromCookie();
+ final String name = OPRWebviewActivity.getUsernameFromCookie();
+ if (privateKey == null || privateKey.isEmpty()) {
+ OprStartFragment.showInstance(mapActivity.getSupportFragmentManager());
+ return;
+ }
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ if (openDBAPI.checkPrivateKeyValid(name, privateKey)) {
+ app.runInUIThread(new Runnable() {
+ @Override
+ public void run() {
+ Intent intent = new Intent();
+ intent.setType("image/*");
+ intent.setAction(Intent.ACTION_GET_CONTENT);
+ mapActivity.startActivityForResult(Intent.createChooser(intent,
+ mapActivity.getString(R.string.select_picture)), PICK_IMAGE);
+ }
+ });
+ } else {
+ OprStartFragment.showInstance(mapActivity.getSupportFragmentManager());
+ }
+ }
+ }).start();
+ }
+ }
+ });
+ //TODO feature under development
+ b.setVisibility(View.GONE);
b.setTextColor(ContextCompat.getColor(context, R.color.preference_category_title));
return b;
}
@@ -351,33 +426,84 @@ public class MenuBuilder {
false, null, false);
}
+ private void registerResultListener(final View view) {
+ mapActivity.registerActivityResultListener(new ActivityResultListener(PICK_IMAGE, new ActivityResultListener.
+ OnActivityResultListener() {
+ @Override
+ public void onResult(int resultCode, Intent resultData) {
+ handleSelectedImage(view, resultData.getData());
+ }
+ }));
+ }
+
+ private void handleSelectedImage(final View view, final Uri uri) {
+ Thread t = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ InputStream inputStream = null;
+ try {
+ inputStream = app.getContentResolver().openInputStream(uri);
+ if (inputStream != null) {
+ uploadImageToPlace(view, inputStream);
+ }
+ } catch (Exception e) {
+ LOG.error(e);
+ } finally {
+ Algorithms.closeStream(inputStream);
+ }
+ }
+ });
+ t.start();
+ }
+
+ private void uploadImageToPlace(View view, InputStream image) {
+ InputStream serverData = new ByteArrayInputStream(compressImage(image));
+ String url = BuildConfig.OPR_BASE_URL + "api/ipfs/image";
+ String response = NetworkUtils.sendPostDataRequest(url, serverData);
+ if (response != null) {
+ int res = 0;
+ try {
+ res = openDBAPI.uploadImage(
+ placeId,
+ OPRWebviewActivity.getPrivateKeyFromCookie(),
+ OPRWebviewActivity.getUsernameFromCookie(),
+ response);
+ } catch (FailedVerificationException e) {
+ LOG.error(e);
+ app.showToastMessage(R.string.cannot_upload_image);
+ }
+ if (res != 200) {
+ //image was uploaded but not added to blockchain
+ app.showToastMessage(R.string.cannot_upload_image);
+ } else {
+ app.showToastMessage(R.string.successfully_uploaded_pattern, 1, 1);
+ //refresh the image
+ execute(new GetImageCardsTask(mapActivity, getLatLon(), getAdditionalCardParams(), imageCardListener));
+ }
+ } else {
+ app.showToastMessage(R.string.cannot_upload_image);
+ }
+ }
+
+ private byte[] compressImage(InputStream image) {
+ BufferedInputStream bufferedInputStream = new BufferedInputStream(image);
+ Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ bmp.compress(Bitmap.CompressFormat.PNG, 70, os);
+ return os.toByteArray();
+ }
+
private void startLoadingImages() {
if (onlinePhotoCardsRow == null) {
return;
}
+ startLoadingImagesTask();
+ }
+
+ private void startLoadingImagesTask() {
onlinePhotoCards = new ArrayList<>();
onlinePhotoCardsRow.setProgressCard();
- execute(new GetImageCardsTask(mapActivity, getLatLon(), getAdditionalCardParams(),
- new GetImageCardsListener() {
- @Override
- public void onPostProcess(List cardList) {
- processOnlinePhotosCards(cardList);
- }
-
- @Override
- public void onFinish(List cardList) {
- if (!isHidden()) {
- List cards = new ArrayList(cardList);
- if (cardList.size() == 0) {
- cards.add(new NoImagesCard(mapActivity));
- }
- if (onlinePhotoCardsRow != null) {
- onlinePhotoCardsRow.setCards(cards);
- }
- onlinePhotoCards = cards;
- }
- }
- }));
+ execute(new GetImageCardsTask(mapActivity, getLatLon(), getAdditionalCardParams(), imageCardListener));
}
protected Map getAdditionalCardParams() {
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java
index 26c81f03a7..33feb6c5a3 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/cards/ImageCard.java
@@ -21,6 +21,7 @@ import net.osmand.Location;
import net.osmand.PlatformUtil;
import net.osmand.data.Amenity;
import net.osmand.data.LatLon;
+import net.osmand.plus.BuildConfig;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.Version;
@@ -39,13 +40,7 @@ import org.json.JSONObject;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;
public abstract class ImageCard extends AbstractCard {
@@ -408,6 +403,28 @@ public abstract class ImageCard extends AbstractCard {
}
}
+ private static String[] getIdFromResponse(String response) {
+ try {
+ JSONArray obj = new JSONObject(response).getJSONArray("objects");
+ JSONArray images = (JSONArray) ((JSONObject) obj.get(0)).get("id");
+ return toStringArray(images);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return new String[0];
+ }
+
+ private static String[] toStringArray(JSONArray array) {
+ if (array == null)
+ return null;
+
+ String[] arr = new String[array.length()];
+ for (int i = 0; i < arr.length; i++) {
+ arr[i] = array.optString(i);
+ }
+ return arr;
+ }
+
public static class GetImageCardsTask extends AsyncTask> {
private MapActivity mapActivity;
@@ -421,11 +438,13 @@ public abstract class ImageCard extends AbstractCard {
public interface GetImageCardsListener {
void onPostProcess(List cardList);
+ void onPlaceIdAcquired(String[] placeId);
+
void onFinish(List cardList);
}
public GetImageCardsTask(@NonNull MapActivity mapActivity, LatLon latLon,
- @Nullable Map params, GetImageCardsListener listener) {
+ @Nullable Map params, GetImageCardsListener listener) {
this.mapActivity = mapActivity;
this.app = mapActivity.getMyApplication();
this.latLon = latLon;
@@ -441,7 +460,14 @@ public abstract class ImageCard extends AbstractCard {
if (o instanceof Amenity) {
Amenity am = (Amenity) o;
long amenityId = am.getId() >> 1;
- getPicturesForPlace(result, amenityId);
+ String url = BuildConfig.OPR_BASE_URL + "api/objects-by-index?type=opr.place&index=osmid&key=" + amenityId;
+ String response = AndroidNetworkUtils.sendRequest(app, url, Collections.emptyMap(),
+ "Requesting location images...", false, false);
+ if (response != null) {
+ getPicturesForPlace(result, response);
+ String[] id = getIdFromResponse(response);
+ listener.onPlaceIdAcquired(id);
+ }
}
try {
final Map pms = new LinkedHashMap<>();
@@ -503,26 +529,27 @@ public abstract class ImageCard extends AbstractCard {
return result;
}
- private void getPicturesForPlace(List result, long l) {
- String url = "https://test.openplacereviews.org/api/objects-by-index?type=opr.place&index=osmid&limit=1&key=" + l;
- String response = AndroidNetworkUtils.sendRequest(app, url, Collections.emptyMap(),
- "Requesting location images...", false, false);
+ private void getPicturesForPlace(List result, String response) {
try {
if (!Algorithms.isEmpty(response)) {
JSONArray obj = new JSONObject(response).getJSONArray("objects");
- JSONArray images = ((JSONObject) ((JSONObject) obj.get(0)).get("images")).getJSONArray("outdoor");
- if (images.length() > 0) {
- for (int i = 0; i < images.length(); i++) {
- try {
- JSONObject imageObject = (JSONObject) images.get(i);
- if (imageObject != JSONObject.NULL) {
- ImageCard imageCard = ImageCard.createCardOpr(mapActivity, imageObject);
- if (imageCard != null) {
- result.add(imageCard);
+ JSONObject imagesWrapper = ((JSONObject) ((JSONObject) obj.get(0)).get("images"));
+ Iterator it = imagesWrapper.keys();
+ while (it.hasNext()) {
+ JSONArray images = imagesWrapper.getJSONArray(it.next());
+ if (images.length() > 0) {
+ for (int i = 0; i < images.length(); i++) {
+ try {
+ JSONObject imageObject = (JSONObject) images.get(i);
+ if (imageObject != JSONObject.NULL) {
+ ImageCard imageCard = ImageCard.createCardOpr(mapActivity, imageObject);
+ if (imageCard != null) {
+ result.add(imageCard);
+ }
}
+ } catch (JSONException e) {
+ LOG.error(e);
}
- } catch (JSONException e) {
- LOG.error(e);
}
}
}
diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java
index 28cea2eb1e..06783d6f50 100644
--- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java
+++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/HorizontalSelectionAdapter.java
@@ -64,8 +64,6 @@ public class HorizontalSelectionAdapter extends RecyclerView.Adapter= Build.VERSION_CODES.P) {
+ Security.removeProvider("BC");
+ Security.addProvider(new BouncyCastleProvider());
+ }
+ KeyPair kp = SecUtils.getKeyPair(ALGO_EC, privateKey, null);
+ String signed = username + ":opr-web";
+
+ JsonFormatter formatter = new JsonFormatter();
+ OPRImage oprImage = new GsonBuilder().create().fromJson(image, OPRImage.class);
+ OpOperation opOperation = new OpOperation();
+ opOperation.setType("opr.place");
+ List