diff --git a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.java b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.java index b3fd1729d..d5b132e71 100644 --- a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.java @@ -41,6 +41,7 @@ import fr.free.nrw.commons.location.LocationPermissionsHelper.Dialog; import fr.free.nrw.commons.location.LocationPermissionsHelper.LocationPermissionCallback; import fr.free.nrw.commons.location.LocationServiceManager; import fr.free.nrw.commons.theme.BaseActivity; +import fr.free.nrw.commons.utils.DialogUtil; import fr.free.nrw.commons.utils.SystemThemeUtils; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; @@ -95,6 +96,10 @@ public class LocationPickerActivity extends BaseActivity implements * modifyLocationButton : button for start editing location */ Button modifyLocationButton; + /** + * removeLocationButton : button to remove location metadata + */ + Button removeLocationButton; /** * showInMapButton : button for showing in map */ @@ -205,6 +210,7 @@ public class LocationPickerActivity extends BaseActivity implements if ("UploadActivity".equals(activity)) { placeSelectedButton.setVisibility(View.GONE); modifyLocationButton.setVisibility(View.VISIBLE); + removeLocationButton.setVisibility(View.VISIBLE); showInMapButton.setVisibility(View.VISIBLE); largeToolbarText.setText(getResources().getString(R.string.image_location)); smallToolbarText.setText(getResources(). @@ -257,6 +263,7 @@ public class LocationPickerActivity extends BaseActivity implements markerImage = findViewById(R.id.location_picker_image_view_marker); tvAttribution = findViewById(R.id.tv_attribution); modifyLocationButton = findViewById(R.id.modify_location); + removeLocationButton = findViewById(R.id.remove_location); showInMapButton = findViewById(R.id.show_in_map); showInMapButton.setText(getResources().getString(R.string.show_in_map_app).toUpperCase()); shadow = findViewById(R.id.location_picker_image_view_shadow); @@ -275,6 +282,7 @@ public class LocationPickerActivity extends BaseActivity implements private void setupMapView() { adjustCameraBasedOnOptions(); modifyLocationButton.setOnClickListener(v -> onClickModifyLocation()); + removeLocationButton.setOnClickListener(v -> onClickRemoveLocation()); showInMapButton.setOnClickListener(v -> showInMap()); darkThemeSetup(); requestLocationPermissions(); @@ -286,6 +294,7 @@ public class LocationPickerActivity extends BaseActivity implements private void onClickModifyLocation() { placeSelectedButton.setVisibility(View.VISIBLE); modifyLocationButton.setVisibility(View.GONE); + removeLocationButton.setVisibility(View.GONE); showInMapButton.setVisibility(View.GONE); markerImage.setVisibility(View.VISIBLE); shadow.setVisibility(View.VISIBLE); @@ -301,6 +310,35 @@ public class LocationPickerActivity extends BaseActivity implements } } + /** + * Handles onclick event of removeLocationButton + */ + private void onClickRemoveLocation() { + DialogUtil.showAlertDialog(this, + getString(R.string.remove_location_warning_title), + getString(R.string.remove_location_warning_desc), + getString(R.string.continue_message), + getString(R.string.cancel), () -> removeLocationFromImage(), null); + } + + /** + * Method to remove the location from the picture + */ + private void removeLocationFromImage() { + if (media != null) { + compositeDisposable.add(coordinateEditHelper.makeCoordinatesEdit(getApplicationContext() + , media, "0.0", "0.0", "0.0f") + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(s -> { + Timber.d("Coordinates are removed from the image"); + })); + } + final Intent returningIntent = new Intent(); + setResult(AppCompatActivity.RESULT_OK, returningIntent); + finish(); + } + /** * Show the location in map app */ diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java index aa3d5bb79..2698633fd 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java @@ -20,6 +20,7 @@ import android.widget.ImageView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.exifinterface.media.ExifInterface; import androidx.recyclerview.widget.LinearLayoutManager; import fr.free.nrw.commons.CameraPosition; import fr.free.nrw.commons.LocationPicker.LocationPicker; @@ -77,6 +78,11 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements public static final String UPLOAD_MEDIA_DETAILS = "upload_media_detail_adapter"; + /** + * True when user removes location from the current image + */ + private boolean hasUserRemovedLocation; + private UploadMediaDetailAdapter uploadMediaDetailAdapter; @@ -295,7 +301,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements if (callback == null) { return; } - presenter.displayLocDialog(indexOfFragment, inAppPictureLocation); + presenter.displayLocDialog(indexOfFragment, inAppPictureLocation, hasUserRemovedLocation); } public void onPreviousButtonClicked() { @@ -634,14 +640,15 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements final double zoom = cameraPosition.getZoom(); editLocation(latitude, longitude, zoom); - /* - If isMissingLocationDialog is true, it means that the user has already tapped the - "Next" button, so go directly to the next step. - */ + // If isMissingLocationDialog is true, it means that the user has already tapped the + // "Next" button, so go directly to the next step. if (isMissingLocationDialog) { isMissingLocationDialog = false; onNextButtonClicked(); } + } else { + // If camera position is null means location is removed by the user + removeLocation(); } } if (requestCode == REQUEST_CODE_FOR_EDIT_ACTIVITY && resultCode == RESULT_OK) { @@ -673,6 +680,46 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements } } + /** + * Removes the location data from the image, by setting them to null + */ + public void removeLocation() { + editableUploadItem.getGpsCoords().setDecimalCoords(null); + try { + ExifInterface sourceExif = new ExifInterface(uploadableFile.getFilePath()); + String[] exifTags = { + ExifInterface.TAG_GPS_LATITUDE, + ExifInterface.TAG_GPS_LATITUDE_REF, + ExifInterface.TAG_GPS_LONGITUDE, + ExifInterface.TAG_GPS_LONGITUDE_REF, + }; + + for (String tag : exifTags) { + sourceExif.setAttribute(tag, null); + } + sourceExif.saveAttributes(); + + Drawable mapQuestion = getResources().getDrawable(R.drawable.ic_map_not_available_20dp); + + if (binding != null) { + binding.locationImageView.setImageDrawable(mapQuestion); + binding.locationTextView.setText(R.string.add_location); + } + + editableUploadItem.getGpsCoords().setDecLatitude(0.0); + editableUploadItem.getGpsCoords().setDecLongitude(0.0); + editableUploadItem.getGpsCoords().setImageCoordsExists(false); + hasUserRemovedLocation = true; + + Toast.makeText(getContext(), getString(R.string.location_removed), Toast.LENGTH_LONG) + .show(); + } catch (Exception e) { + Timber.d(e); + Toast.makeText(getContext(), "Location could not be removed due to internal error", + Toast.LENGTH_LONG).show(); + } + } + /** * Update the old coordinates with new one * @param latitude new latitude @@ -694,7 +741,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements binding.locationTextView.setText(R.string.edit_location); } - Toast.makeText(getContext(), "Location Updated", Toast.LENGTH_LONG).show(); + Toast.makeText(getContext(), getString(R.string.location_updated), Toast.LENGTH_LONG).show(); } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailsContract.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailsContract.java index 254b44f72..21c7eae9f 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailsContract.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailsContract.java @@ -71,13 +71,16 @@ public interface UploadMediaDetailsContract { boolean getImageQuality(int uploadItemIndex, LatLng inAppPictureLocation, Activity activity); /** - * Checks if the image has a location or not. Displays a dialog alerting user that no - * location has been to added to the image and asking them to add one + * Checks if the image has a location. Displays a dialog alerting user that no location has + * been to added to the image and asking them to add one, if location was not removed by the + * user * * @param uploadItemIndex Index of the uploadItem which has no location * @param inAppPictureLocation In app picture location (if any) + * @param hasUserRemovedLocation True if user has removed location from the image */ - void displayLocDialog(int uploadItemIndex, LatLng inAppPictureLocation); + void displayLocDialog(int uploadItemIndex, LatLng inAppPictureLocation, + boolean hasUserRemovedLocation); /** * Used to check image quality from stored qualities and display dialogs diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.java index 2e93a4d21..4f9fe7d7c 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.java @@ -202,17 +202,21 @@ public class UploadMediaPresenter implements UserActionListener, SimilarImageInt } /** - * Checks if the image has a location or not. Displays a dialog alerting user that no - * location has been to added to the image and asking them to add one + * Checks if the image has a location. Displays a dialog alerting user that no + * location has been to added to the image and asking them to add one, if location was not + * removed by the user * * @param uploadItemIndex Index of the uploadItem which has no location * @param inAppPictureLocation In app picture location (if any) + * @param hasUserRemovedLocation True if user has removed location from the image */ @Override - public void displayLocDialog(int uploadItemIndex, LatLng inAppPictureLocation) { + public void displayLocDialog(int uploadItemIndex, LatLng inAppPictureLocation, + boolean hasUserRemovedLocation) { final List uploadItems = repository.getUploads(); UploadItem uploadItem = uploadItems.get(uploadItemIndex); - if (uploadItem.getGpsCoords().getDecimalCoords() == null && inAppPictureLocation == null) { + if (uploadItem.getGpsCoords().getDecimalCoords() == null && inAppPictureLocation == null + && !hasUserRemovedLocation) { final Runnable onSkipClicked = () -> { verifyCaptionQuality(uploadItem); }; diff --git a/app/src/main/res/layout/bottom_container_location_picker.xml b/app/src/main/res/layout/bottom_container_location_picker.xml index b0fecc7c0..6887c6463 100644 --- a/app/src/main/res/layout/bottom_container_location_picker.xml +++ b/app/src/main/res/layout/bottom_container_location_picker.xml @@ -54,6 +54,28 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"> +