mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Fix Crash in LocationPickerActivity when device configuration is changed (#5500)
* Fix Crash in LocationPickerActivity when device configuration is changed (UI Modes) * clean up * fix * fix * fix * fix * removed faulty test * cleanup * fix and tests added
This commit is contained in:
parent
161e2edc31
commit
fec6dba341
5 changed files with 111 additions and 60 deletions
|
|
@ -3,6 +3,7 @@ package fr.free.nrw.commons.LocationPicker;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||||
|
import fr.free.nrw.commons.Media;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for starting the activity
|
* Helper class for starting the activity
|
||||||
|
|
@ -52,6 +53,17 @@ public final class LocationPicker {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets and puts media in intent
|
||||||
|
* @param media Media
|
||||||
|
* @return LocationPicker.IntentBuilder
|
||||||
|
*/
|
||||||
|
public LocationPicker.IntentBuilder media(
|
||||||
|
final Media media) {
|
||||||
|
intent.putExtra(LocationPickerConstants.MEDIA, media);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets and sets the activity
|
* Gets and sets the activity
|
||||||
* @param activity Activity
|
* @param activity Activity
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,10 @@ import androidx.core.content.ContextCompat;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||||
|
import fr.free.nrw.commons.Media;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.Utils;
|
import fr.free.nrw.commons.Utils;
|
||||||
|
import fr.free.nrw.commons.coordinates.CoordinateEditHelper;
|
||||||
import fr.free.nrw.commons.filepicker.Constants;
|
import fr.free.nrw.commons.filepicker.Constants;
|
||||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||||
import fr.free.nrw.commons.location.LocationPermissionsHelper;
|
import fr.free.nrw.commons.location.LocationPermissionsHelper;
|
||||||
|
|
@ -41,6 +43,9 @@ import fr.free.nrw.commons.location.LocationPermissionsHelper.LocationPermission
|
||||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||||
import fr.free.nrw.commons.theme.BaseActivity;
|
import fr.free.nrw.commons.theme.BaseActivity;
|
||||||
import fr.free.nrw.commons.utils.SystemThemeUtils;
|
import fr.free.nrw.commons.utils.SystemThemeUtils;
|
||||||
|
import fr.free.nrw.commons.utils.ViewUtilWrapper;
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
@ -52,13 +57,22 @@ import org.osmdroid.views.overlay.Marker;
|
||||||
import org.osmdroid.views.overlay.Overlay;
|
import org.osmdroid.views.overlay.Overlay;
|
||||||
import org.osmdroid.views.overlay.ScaleDiskOverlay;
|
import org.osmdroid.views.overlay.ScaleDiskOverlay;
|
||||||
import org.osmdroid.views.overlay.TilesOverlay;
|
import org.osmdroid.views.overlay.TilesOverlay;
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helps to pick location and return the result with an intent
|
* Helps to pick location and return the result with an intent
|
||||||
*/
|
*/
|
||||||
public class LocationPickerActivity extends BaseActivity implements
|
public class LocationPickerActivity extends BaseActivity implements
|
||||||
LocationPermissionCallback {
|
LocationPermissionCallback {
|
||||||
|
/**
|
||||||
|
* coordinateEditHelper: helps to edit coordinates
|
||||||
|
*/
|
||||||
|
@Inject
|
||||||
|
CoordinateEditHelper coordinateEditHelper;
|
||||||
|
/**
|
||||||
|
* media : Media object
|
||||||
|
*/
|
||||||
|
private Media media;
|
||||||
/**
|
/**
|
||||||
* cameraPosition : position of picker
|
* cameraPosition : position of picker
|
||||||
*/
|
*/
|
||||||
|
|
@ -125,6 +139,13 @@ public class LocationPickerActivity extends BaseActivity implements
|
||||||
@Inject
|
@Inject
|
||||||
LocationServiceManager locationManager;
|
LocationServiceManager locationManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constants
|
||||||
|
*/
|
||||||
|
private static final String CAMERA_POS = "cameraPosition";
|
||||||
|
private static final String ACTIVITY = "activity";
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
|
|
@ -145,8 +166,12 @@ public class LocationPickerActivity extends BaseActivity implements
|
||||||
cameraPosition = getIntent()
|
cameraPosition = getIntent()
|
||||||
.getParcelableExtra(LocationPickerConstants.MAP_CAMERA_POSITION);
|
.getParcelableExtra(LocationPickerConstants.MAP_CAMERA_POSITION);
|
||||||
activity = getIntent().getStringExtra(LocationPickerConstants.ACTIVITY_KEY);
|
activity = getIntent().getStringExtra(LocationPickerConstants.ACTIVITY_KEY);
|
||||||
|
media = getIntent().getParcelableExtra(LocationPickerConstants.MEDIA);
|
||||||
|
}else{
|
||||||
|
cameraPosition = savedInstanceState.getParcelable(CAMERA_POS);
|
||||||
|
activity = savedInstanceState.getString(ACTIVITY);
|
||||||
|
media = savedInstanceState.getParcelable("sMedia");
|
||||||
}
|
}
|
||||||
|
|
||||||
bindViews();
|
bindViews();
|
||||||
addBackButtonListener();
|
addBackButtonListener();
|
||||||
addPlaceSelectedButton();
|
addPlaceSelectedButton();
|
||||||
|
|
@ -220,7 +245,10 @@ public class LocationPickerActivity extends BaseActivity implements
|
||||||
*/
|
*/
|
||||||
private void addBackButtonListener() {
|
private void addBackButtonListener() {
|
||||||
final ImageView backButton = findViewById(R.id.maplibre_place_picker_toolbar_back_button);
|
final ImageView backButton = findViewById(R.id.maplibre_place_picker_toolbar_back_button);
|
||||||
backButton.setOnClickListener(view -> finish());
|
backButton.setOnClickListener(v -> {
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -311,14 +339,42 @@ public class LocationPickerActivity extends BaseActivity implements
|
||||||
+ mapView.getMapCenter().getLongitude());
|
+ mapView.getMapCenter().getLongitude());
|
||||||
applicationKvStore.putString(LAST_ZOOM, mapView.getZoomLevel() + "");
|
applicationKvStore.putString(LAST_ZOOM, mapView.getZoomLevel() + "");
|
||||||
}
|
}
|
||||||
final Intent returningIntent = new Intent();
|
|
||||||
returningIntent.putExtra(LocationPickerConstants.MAP_CAMERA_POSITION,
|
if (media == null) {
|
||||||
new CameraPosition(new LatLng(mapView.getMapCenter().getLatitude(),
|
final Intent returningIntent = new Intent();
|
||||||
mapView.getMapCenter().getLongitude()), 14f, 0, 0));
|
returningIntent.putExtra(LocationPickerConstants.MAP_CAMERA_POSITION,
|
||||||
setResult(AppCompatActivity.RESULT_OK, returningIntent);
|
new CameraPosition(new LatLng(mapView.getMapCenter().getLatitude(),
|
||||||
|
mapView.getMapCenter().getLongitude()), 14f, 0, 0));
|
||||||
|
setResult(AppCompatActivity.RESULT_OK, returningIntent);
|
||||||
|
} else {
|
||||||
|
updateCoordinates(String.valueOf(mapView.getMapCenter().getLatitude()),
|
||||||
|
String.valueOf(mapView.getMapCenter().getLongitude()),
|
||||||
|
String.valueOf(0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetched coordinates are replaced with existing coordinates by a POST API call.
|
||||||
|
* @param Latitude to be added
|
||||||
|
* @param Longitude to be added
|
||||||
|
* @param Accuracy to be added
|
||||||
|
*/
|
||||||
|
public void updateCoordinates(final String Latitude, final String Longitude,
|
||||||
|
final String Accuracy) {
|
||||||
|
if (media == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
compositeDisposable.add(coordinateEditHelper.makeCoordinatesEdit(getApplicationContext(),media,
|
||||||
|
Latitude, Longitude, Accuracy)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(s -> {
|
||||||
|
Timber.d("Coordinates are added.");
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Center the camera on the last saved location
|
* Center the camera on the last saved location
|
||||||
*/
|
*/
|
||||||
|
|
@ -458,4 +514,22 @@ public class LocationPickerActivity extends BaseActivity implements
|
||||||
mapView.getOverlays().add(startMarker);
|
mapView.getOverlays().add(startMarker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the state of the activity
|
||||||
|
* @param outState Bundle
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onSaveInstanceState(@NonNull final Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
if(cameraPosition!=null){
|
||||||
|
outState.putParcelable(CAMERA_POS, cameraPosition);
|
||||||
|
}
|
||||||
|
if(activity!=null){
|
||||||
|
outState.putString(ACTIVITY, activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(media!=null){
|
||||||
|
outState.putParcelable("sMedia", media);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@ public final class LocationPickerConstants {
|
||||||
public static final String MAP_CAMERA_POSITION
|
public static final String MAP_CAMERA_POSITION
|
||||||
= "location.picker.cameraPosition";
|
= "location.picker.cameraPosition";
|
||||||
|
|
||||||
|
public static final String MEDIA
|
||||||
|
= "location.picker.media";
|
||||||
|
|
||||||
|
|
||||||
private LocationPickerConstants() {
|
private LocationPickerConstants() {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -938,12 +938,14 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
startActivityForResult(new LocationPicker.IntentBuilder()
|
|
||||||
|
startActivity(new LocationPicker.IntentBuilder()
|
||||||
.defaultLocation(new CameraPosition.Builder()
|
.defaultLocation(new CameraPosition.Builder()
|
||||||
.target(new LatLng(defaultLatitude, defaultLongitude))
|
.target(new LatLng(defaultLatitude, defaultLongitude))
|
||||||
.zoom(16).build())
|
.zoom(16).build())
|
||||||
.activityKey("MediaActivity")
|
.activityKey("MediaActivity")
|
||||||
.build(getActivity()), REQUEST_CODE);
|
.media(media)
|
||||||
|
.build(getActivity()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.description_edit)
|
@OnClick(R.id.description_edit)
|
||||||
|
|
@ -1121,32 +1123,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
@Nullable final Intent data) {
|
@Nullable final Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
|
if (requestCode == REQUEST_CODE_EDIT_DESCRIPTION && resultCode == RESULT_OK) {
|
||||||
|
|
||||||
assert data != null;
|
|
||||||
final CameraPosition cameraPosition = LocationPicker.getCameraPosition(data);
|
|
||||||
|
|
||||||
if (cameraPosition != null) {
|
|
||||||
|
|
||||||
final String latitude = String.valueOf(cameraPosition.target.getLatitude());
|
|
||||||
final String longitude = String.valueOf(cameraPosition.target.getLongitude());
|
|
||||||
final String accuracy = String.valueOf(cameraPosition.target.getAltitude());
|
|
||||||
String currentLatitude = null;
|
|
||||||
String currentLongitude = null;
|
|
||||||
|
|
||||||
if (media.getCoordinates() != null) {
|
|
||||||
currentLatitude = String.valueOf(media.getCoordinates().getLatitude());
|
|
||||||
currentLongitude = String.valueOf(media.getCoordinates().getLongitude());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!latitude.equals(currentLatitude) || !longitude.equals(currentLongitude)) {
|
|
||||||
updateCoordinates(latitude, longitude, accuracy);
|
|
||||||
} else if (media.getCoordinates() == null) {
|
|
||||||
updateCoordinates(latitude, longitude, accuracy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (requestCode == REQUEST_CODE_EDIT_DESCRIPTION && resultCode == RESULT_OK) {
|
|
||||||
final String updatedWikiText = data.getStringExtra(UPDATED_WIKITEXT);
|
final String updatedWikiText = data.getStringExtra(UPDATED_WIKITEXT);
|
||||||
compositeDisposable.add(descriptionEditHelper.addDescription(getContext(), media,
|
compositeDisposable.add(descriptionEditHelper.addDescription(getContext(), media,
|
||||||
updatedWikiText)
|
updatedWikiText)
|
||||||
|
|
@ -1174,11 +1151,6 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
progressBarEditDescription.setVisibility(GONE);
|
progressBarEditDescription.setVisibility(GONE);
|
||||||
editDescription.setVisibility(VISIBLE);
|
editDescription.setVisibility(VISIBLE);
|
||||||
|
|
||||||
} else if (requestCode == REQUEST_CODE && resultCode == RESULT_CANCELED) {
|
|
||||||
viewUtil.showShortToast(getContext(),
|
|
||||||
requireContext()
|
|
||||||
.getString(R.string.coordinates_picking_unsuccessful));
|
|
||||||
|
|
||||||
} else if (requestCode == REQUEST_CODE_EDIT_DESCRIPTION && resultCode == RESULT_CANCELED) {
|
} else if (requestCode == REQUEST_CODE_EDIT_DESCRIPTION && resultCode == RESULT_CANCELED) {
|
||||||
progressBarEditDescription.setVisibility(GONE);
|
progressBarEditDescription.setVisibility(GONE);
|
||||||
editDescription.setVisibility(VISIBLE);
|
editDescription.setVisibility(VISIBLE);
|
||||||
|
|
@ -1196,24 +1168,6 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
media.setCaptions(updatedCaptions);
|
media.setCaptions(updatedCaptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetched coordinates are replaced with existing coordinates by a POST API call.
|
|
||||||
* @param Latitude to be added
|
|
||||||
* @param Longitude to be added
|
|
||||||
* @param Accuracy to be added
|
|
||||||
*/
|
|
||||||
public void updateCoordinates(final String Latitude, final String Longitude,
|
|
||||||
final String Accuracy) {
|
|
||||||
compositeDisposable.add(coordinateEditHelper.makeCoordinatesEdit(getContext(), media,
|
|
||||||
Latitude, Longitude, Accuracy)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(s -> {
|
|
||||||
Timber.d("Coordinates are added.");
|
|
||||||
coordinates.setText(prettyCoordinates(media));
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("StringFormatInvalid")
|
@SuppressLint("StringFormatInvalid")
|
||||||
@OnClick(R.id.nominateDeletion)
|
@OnClick(R.id.nominateDeletion)
|
||||||
public void onDeleteButtonClicked(){
|
public void onDeleteButtonClicked(){
|
||||||
|
|
@ -1598,4 +1552,5 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
SharedPreferences imageBackgroundColorPref = this.getImageBackgroundColorPref();
|
SharedPreferences imageBackgroundColorPref = this.getImageBackgroundColorPref();
|
||||||
return imageBackgroundColorPref.getInt(IMAGE_BACKGROUND_COLOR, DEFAULT_IMAGE_BACKGROUND_COLOR);
|
return imageBackgroundColorPref.getInt(IMAGE_BACKGROUND_COLOR, DEFAULT_IMAGE_BACKGROUND_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package fr.free.nrw.commons.locationpicker
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
|
|
@ -20,10 +21,14 @@ import com.nhaarman.mockitokotlin2.times
|
||||||
import com.nhaarman.mockitokotlin2.verify
|
import com.nhaarman.mockitokotlin2.verify
|
||||||
import com.nhaarman.mockitokotlin2.whenever
|
import com.nhaarman.mockitokotlin2.whenever
|
||||||
import fr.free.nrw.commons.LocationPicker.LocationPickerActivity
|
import fr.free.nrw.commons.LocationPicker.LocationPickerActivity
|
||||||
|
import fr.free.nrw.commons.Media
|
||||||
import fr.free.nrw.commons.TestCommonsApplication
|
import fr.free.nrw.commons.TestCommonsApplication
|
||||||
|
import fr.free.nrw.commons.coordinates.CoordinateEditHelper
|
||||||
import fr.free.nrw.commons.kvstore.JsonKvStore
|
import fr.free.nrw.commons.kvstore.JsonKvStore
|
||||||
import fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_LOCATION
|
import fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_LOCATION
|
||||||
import fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_ZOOM
|
import fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_ZOOM
|
||||||
|
import io.reactivex.android.plugins.RxAndroidPlugins
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.*
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
|
@ -93,6 +98,7 @@ class LocationPickerActivityUnitTests {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
context = RuntimeEnvironment.getApplication().applicationContext
|
context = RuntimeEnvironment.getApplication().applicationContext
|
||||||
activity = Robolectric.buildActivity(LocationPickerActivity::class.java).get()
|
activity = Robolectric.buildActivity(LocationPickerActivity::class.java).get()
|
||||||
|
RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }
|
||||||
|
|
||||||
Whitebox.setInternalState(activity, "mapView", mapView)
|
Whitebox.setInternalState(activity, "mapView", mapView)
|
||||||
Whitebox.setInternalState(activity, "applicationKvStore", applicationKvStore)
|
Whitebox.setInternalState(activity, "applicationKvStore", applicationKvStore)
|
||||||
|
|
@ -165,4 +171,5 @@ class LocationPickerActivityUnitTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue