Fixes Location related flow of the app #5256 , #5461, #5490 (#5494)

* Resolved merged conflicts

* Resolved merge conflicts and updated workflow

* Updated Location Flow and merged conflicts

* Update flow and merge conflicts

* Fixed LocationPicker's location flow

* Removed redundant code from  LocationPermissionsHelper

* Fixed Explore fragment crashing and incorrect behaviour

* Updated LocationPicker Flow

* Fixed Nearby not working as intended

* Final update to location flow of all maps

* Added the reqested changes and fixed bugs

* Resolved requested change in in-app camera location flow

* Fixed In-app camera location flow

* Resolved conflicts in ContributionsListFragment

* Updated java doc as requested

* Resolved nearby card dialog not being shown

* Optimised LocationPermissionsHelper javadoc

* Made requested changes for preference check

* Added javadoc and requested comment for later reference

* Implemented requested code changes

* Fixed failing test due to changes made during PR

* Added string resource for ExploreMapFragment

* Changed string resource for rationale dialog

* Added standard location flow information in LocationPermissionsHelper

* Added javadoc for doNotAskForLocationPermission

* Removed unused import

* Updated javadoc

* Removed values-yue-hant

* Fix some merge conflict errors

* Fix minor errors due to mergre conflicts

* Fix some refactor errors

* Fixed minor bug due to merging conflicts

* Delete app/src/main/res/values-yue-hant directory

* Final changes to NearbyParentFragment

* Fixes #5686 map coordinates set to image coords

* Removed some redundant code from recenterMap

* Removed one test whose method no longer exists

* Removed unused method from contract of nearby

* Removed redundant method from NearbyParentFragment

* nearby: add a FIXME about the possibly redudant code

---------

Co-authored-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com>
This commit is contained in:
Shashwat Kedia 2024-04-17 09:18:34 +05:30 committed by GitHub
parent 1f2e31d45b
commit 04f9ef4819
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 421 additions and 297 deletions

View file

@ -4,12 +4,14 @@ import static fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.
import static fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_ZOOM;
import static fr.free.nrw.commons.utils.MapUtils.ZOOM_LEVEL;
import android.Manifest.permission;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.location.LocationManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Html;
@ -21,12 +23,14 @@ import android.view.animation.OvershootInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import fr.free.nrw.commons.CameraPosition;
@ -39,9 +43,9 @@ import fr.free.nrw.commons.auth.csrf.CsrfTokenClient;
import fr.free.nrw.commons.auth.csrf.InvalidLoginTokenException;
import fr.free.nrw.commons.coordinates.CoordinateEditHelper;
import fr.free.nrw.commons.filepicker.Constants;
import fr.free.nrw.commons.kvstore.BasicKvStore;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.location.LocationPermissionsHelper;
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;
@ -135,6 +139,7 @@ public class LocationPickerActivity extends BaseActivity implements
@Named("default_preferences")
public
JsonKvStore applicationKvStore;
BasicKvStore store;
/**
* isDarkTheme: for keeping a track of the device theme and modifying the map theme accordingly
*/
@ -145,6 +150,8 @@ public class LocationPickerActivity extends BaseActivity implements
@Inject
LocationServiceManager locationManager;
LocationPermissionsHelper locationPermissionsHelper;
@Inject
SessionManager sessionManager;
@ -163,6 +170,7 @@ public class LocationPickerActivity extends BaseActivity implements
isDarkTheme = systemThemeUtils.isDeviceInNightMode();
moveToCurrentLocation = false;
store = new BasicKvStore(this, "LocationPermissions");
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
final ActionBar actionBar = getSupportActionBar();
@ -482,19 +490,10 @@ public class LocationPickerActivity extends BaseActivity implements
* Center the map at user's current location
*/
private void requestLocationPermissions() {
LocationPermissionsHelper.Dialog locationAccessDialog = new Dialog(
R.string.location_permission_title,
R.string.upload_map_location_access
);
LocationPermissionsHelper.Dialog locationOffDialog = new Dialog(
R.string.ask_to_turn_location_on,
R.string.upload_map_location_access
);
LocationPermissionsHelper locationPermissionsHelper = new LocationPermissionsHelper(
locationPermissionsHelper = new LocationPermissionsHelper(
this, locationManager, this);
locationPermissionsHelper.handleLocationPermissions(locationAccessDialog,
locationOffDialog);
locationPermissionsHelper.requestForLocationAccess(R.string.location_permission_title,
R.string.upload_map_location_access);
}
@Override
@ -505,7 +504,7 @@ public class LocationPickerActivity extends BaseActivity implements
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
onLocationPermissionGranted();
} else {
onLocationPermissionDenied("");
onLocationPermissionDenied(getString(R.string.upload_map_location_access));
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@ -524,21 +523,50 @@ public class LocationPickerActivity extends BaseActivity implements
@Override
public void onLocationPermissionDenied(String toastMessage) {
//do nothing
if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
permission.ACCESS_FINE_LOCATION)) {
if (!locationPermissionsHelper.checkLocationPermission(this)) {
if (store.getBoolean("isPermissionDenied", false)) {
// means user has denied location permission twice or checked the "Don't show again"
locationPermissionsHelper.showAppSettingsDialog(this,
R.string.upload_map_location_access);
} else {
Toast.makeText(getBaseContext(), toastMessage, Toast.LENGTH_LONG).show();
}
store.putBoolean("isPermissionDenied", true);
}
} else {
Toast.makeText(getBaseContext(), toastMessage, Toast.LENGTH_LONG).show();
}
}
@Override
public void onLocationPermissionGranted() {
if (moveToCurrentLocation || !(activity.equals("MediaActivity"))) {
if (locationPermissionsHelper.isLocationAccessToAppsTurnedOn()) {
locationManager.requestLocationUpdatesFromProvider(
LocationManager.NETWORK_PROVIDER);
locationManager.requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER);
getLocation();
} else {
getLocation();
locationPermissionsHelper.showLocationOffDialog(this,
R.string.ask_to_turn_location_on_text);
}
}
}
/**
* Gets new location if locations services are on, else gets last location
*/
private void getLocation() {
fr.free.nrw.commons.location.LatLng currLocation = locationManager.getLastLocation();
if (currLocation != null) {
GeoPoint currLocationGeopoint = new GeoPoint(currLocation.getLatitude(),
currLocation.getLongitude());
addLocationMarker(currLocationGeopoint);
if (moveToCurrentLocation) {
mapView.getController().setCenter(currLocationGeopoint);
mapView.getController().animateTo(currLocationGeopoint);
moveToCurrentLocation = false;
}
markerImage.setTranslationY(0);
}
}

View file

@ -45,7 +45,7 @@ public class BookmarkLocationsFragment extends DaggerFragment {
contributionController.locationPermissionCallback.onLocationPermissionGranted();
} else {
if (shouldShowRequestPermissionRationale(permission.ACCESS_FINE_LOCATION)) {
contributionController.handleShowRationaleFlowCameraLocation(getActivity());
contributionController.handleShowRationaleFlowCameraLocation(getActivity(), inAppCameraLocationPermissionLauncher);
} else {
contributionController.locationPermissionCallback.onLocationPermissionDenied(getActivity().getString(R.string.in_app_camera_location_permission_denied));
}

View file

@ -17,7 +17,6 @@ import fr.free.nrw.commons.filepicker.UploadableFile;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.location.LocationPermissionsHelper;
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.nearby.Place;
@ -84,15 +83,6 @@ public class ContributionController {
*/
private void createDialogsAndHandleLocationPermissions(Activity activity,
ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher) {
LocationPermissionsHelper.Dialog locationAccessDialog = new Dialog(
R.string.location_permission_title,
R.string.in_app_camera_location_permission_rationale
);
LocationPermissionsHelper.Dialog locationOffDialog = new Dialog(
R.string.ask_to_turn_location_on,
R.string.in_app_camera_needs_location
);
locationPermissionCallback = new LocationPermissionCallback() {
@Override
public void onLocationPermissionDenied(String toastMessage) {
@ -106,8 +96,13 @@ public class ContributionController {
@Override
public void onLocationPermissionGranted() {
if (!locationPermissionsHelper.isLocationAccessToAppsTurnedOn()) {
showLocationOffDialog(activity, R.string.in_app_camera_needs_location,
R.string.in_app_camera_location_unavailable);
} else {
initiateCameraUpload(activity);
}
}
};
locationPermissionsHelper = new LocationPermissionsHelper(
@ -115,22 +110,46 @@ public class ContributionController {
if (inAppCameraLocationPermissionLauncher != null) {
inAppCameraLocationPermissionLauncher.launch(
new String[]{permission.ACCESS_FINE_LOCATION});
} else {
locationPermissionsHelper.handleLocationPermissions(locationAccessDialog,
locationOffDialog);
}
}
public void handleShowRationaleFlowCameraLocation(Activity activity) {
/**
* Shows a dialog alerting the user about location services being off
* and asking them to turn it on
* TODO: Add a seperate callback in LocationPermissionsHelper for this.
* Ref: https://github.com/commons-app/apps-android-commons/pull/5494/files#r1510553114
*
* @param activity Activity reference
* @param dialogTextResource Resource id of text to be shown in dialog
* @param toastTextResource Resource id of text to be shown in toast
*/
private void showLocationOffDialog(Activity activity, int dialogTextResource,
int toastTextResource) {
DialogUtil
.showAlertDialog(activity,
activity.getString(R.string.ask_to_turn_location_on),
activity.getString(dialogTextResource),
activity.getString(R.string.title_app_shortcut_setting),
activity.getString(R.string.cancel),
() -> locationPermissionsHelper.openLocationSettings(activity),
() -> {
Toast.makeText(activity, activity.getString(toastTextResource),
Toast.LENGTH_LONG).show();
initiateCameraUpload(activity);
}
);
}
public void handleShowRationaleFlowCameraLocation(Activity activity,
ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher) {
DialogUtil.showAlertDialog(activity, activity.getString(R.string.location_permission_title),
activity.getString(R.string.in_app_camera_location_permission_rationale),
activity.getString(android.R.string.ok),
activity.getString(android.R.string.cancel),
() -> {
if (!locationPermissionsHelper.isLocationAccessToAppsTurnedOn()) {
locationPermissionsHelper.showLocationOffDialog(activity);
}
createDialogsAndHandleLocationPermissions(activity,
inAppCameraLocationPermissionLauncher);
},
() -> locationPermissionCallback.onLocationPermissionDenied(
activity.getString(R.string.in_app_camera_location_permission_denied)),
@ -162,6 +181,7 @@ public class ContributionController {
inAppCameraLocationPermissionLauncher);
},
() -> {
ViewUtil.showLongToast(activity, R.string.in_app_camera_location_permission_denied);
defaultKvStore.putBoolean("inAppCameraLocationPref", false);
initiateCameraUpload(activity);
},

View file

@ -155,7 +155,6 @@ public class ContributionsFragment
&& !store.getBoolean("doNotAskForLocationPermission", false)
&& (((MainActivity) getActivity()).activeFragment == ActiveFragment.CONTRIBUTIONS)) {
binding.cardViewNearby.permissionType = NearbyNotificationCardView.PermissionType.ENABLE_LOCATION_PERMISSION;
showNearbyCardPermissionRationale();
} else {
displayYouWontSeeNearbyMessage();
}
@ -537,6 +536,7 @@ public class ContributionsFragment
private void displayYouWontSeeNearbyMessage() {
ViewUtil.showLongToast(getActivity(),
getResources().getString(R.string.unable_to_display_nearest_place));
// Set to true as the user doesn't want the app to ask for location permission anymore
store.putBoolean("doNotAskForLocationPermission", true);
}

View file

@ -98,7 +98,9 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
private int contributionsSize;
private String userName;
private ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
private ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher = registerForActivityResult(
new ActivityResultContracts.RequestMultiplePermissions(),
new ActivityResultCallback<Map<String, Boolean>>() {
@Override
public void onActivityResult(Map<String, Boolean> result) {
boolean areAllGranted = true;
@ -110,10 +112,12 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
controller.locationPermissionCallback.onLocationPermissionGranted();
} else {
if (shouldShowRequestPermissionRationale(permission.ACCESS_FINE_LOCATION)) {
controller.handleShowRationaleFlowCameraLocation(getActivity());
controller.handleShowRationaleFlowCameraLocation(getActivity(),
inAppCameraLocationPermissionLauncher);
} else {
controller.locationPermissionCallback.onLocationPermissionDenied(
getActivity().getString(R.string.in_app_camera_location_permission_denied));
getActivity().getString(
R.string.in_app_camera_location_permission_denied));
}
}
}

View file

@ -11,11 +11,9 @@ public class ExploreMapContract {
interface View {
boolean isNetworkConnectionEstablished();
void populatePlaces(LatLng currentLatLng);
void checkPermissionsAndPerformAction();
void recenterMap(LatLng currentLatLng);
void showLocationOffDialog();
void openLocationSettings();
void populatePlaces(LatLng curlatLng);
void askForLocationPermission();
void recenterMap(LatLng curLatLng);
void hideBottomDetailsSheet();
LatLng getMapCenter();
LatLng getMapFocus();

View file

@ -48,8 +48,11 @@ import fr.free.nrw.commons.databinding.FragmentExploreMapBinding;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.explore.ExploreMapRootFragment;
import fr.free.nrw.commons.explore.paging.LiveDataConverter;
import fr.free.nrw.commons.filepicker.Constants;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.location.LocationPermissionsHelper;
import fr.free.nrw.commons.location.LocationPermissionsHelper.LocationPermissionCallback;
import fr.free.nrw.commons.location.LocationServiceManager;
import fr.free.nrw.commons.location.LocationUpdateListener;
import fr.free.nrw.commons.media.MediaClient;
@ -65,7 +68,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
import org.osmdroid.events.MapEventsReceiver;
@ -87,7 +89,7 @@ import org.osmdroid.views.overlay.TilesOverlay;
import timber.log.Timber;
public class ExploreMapFragment extends CommonsDaggerSupportFragment
implements ExploreMapContract.View, LocationUpdateListener {
implements ExploreMapContract.View, LocationUpdateListener, LocationPermissionCallback {
private BottomSheetBehavior bottomSheetDetailsBehavior;
private BroadcastReceiver broadcastReceiver;
@ -119,48 +121,40 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
BookmarkLocationsDao bookmarkLocationDao; // May be needed in future if we want to integrate bookmarking explore places
@Inject
SystemThemeUtils systemThemeUtils;
LocationPermissionsHelper locationPermissionsHelper;
private ExploreMapPresenter presenter;
public FragmentExploreMapBinding binding;
private ActivityResultLauncher<String[]> activityResultLauncher = registerForActivityResult(
new ActivityResultContracts.RequestMultiplePermissions(),
new ActivityResultCallback<Map<String, Boolean>>() {
@Override
public void onActivityResult(Map<String, Boolean> result) {
boolean areAllGranted = true;
for (final boolean b : result.values()) {
areAllGranted = areAllGranted && b;
}
if (areAllGranted) {
private ActivityResultLauncher<String> activityResultLauncher = registerForActivityResult(
new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) {
locationPermissionGranted();
} else {
if (shouldShowRequestPermissionRationale(permission.ACCESS_FINE_LOCATION)) {
DialogUtil.showAlertDialog(getActivity(),
getActivity().getString(R.string.location_permission_title),
getActivity().getString(R.string.location_permission_rationale_nearby),
getActivity().getString(R.string.location_permission_rationale_explore),
getActivity().getString(android.R.string.ok),
getActivity().getString(android.R.string.cancel),
() -> {
if (!(locationManager.isNetworkProviderEnabled()
|| locationManager.isGPSProviderEnabled())) {
showLocationOffDialog();
}
askForLocationPermission();
},
() -> isPermissionDenied = true,
null,
null,
false);
} else {
isPermissionDenied = true;
if (isPermissionDenied) {
locationPermissionsHelper.showAppSettingsDialog(getActivity(),
R.string.explore_map_needs_location);
}
Timber.d("The user checked 'Don't ask again' or denied the permission twice");
isPermissionDenied = true;
}
}
});
@NonNull
public static ExploreMapFragment newInstance() {
ExploreMapFragment fragment = new ExploreMapFragment();
@ -184,7 +178,7 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
setSearchThisAreaButtonVisibility(false);
binding.tvAttribution.setText(Html.fromHtml(getString(R.string.map_attribution)));
initNetworkBroadCastReceiver();
locationPermissionsHelper = new LocationPermissionsHelper(getActivity(),locationManager,this);
if (presenter == null) {
presenter = new ExploreMapPresenter(bookmarkLocationDao);
}
@ -278,7 +272,9 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
}
});
if (!locationPermissionsHelper.checkLocationPermission(getActivity())) {
askForLocationPermission();
}
}
@Override
@ -288,8 +284,7 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
presenter.attachView(this);
registerNetworkReceiver();
if (isResumed()) {
if (!isPermissionDenied && !applicationKvStore
.getBoolean("doNotAskForLocationPermission", false)) {
if (locationPermissionsHelper.checkLocationPermission(getActivity())) {
performMapReadyActions();
} else {
startMapWithoutPermission();
@ -297,8 +292,24 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
}
}
@Override
public void onPause() {
super.onPause();
// unregistering the broadcastReceiver, as it was causing an exception and a potential crash
unregisterNetworkReceiver();
}
/**
* Unregisters the networkReceiver
*/
private void unregisterNetworkReceiver() {
if (getActivity() != null) {
getActivity().unregisterReceiver(broadcastReceiver);
}
}
private void startMapWithoutPermission() {
applicationKvStore.putBoolean("doNotAskForLocationPermission", true);
lastKnownLocation = MapUtils.defaultLatLng;
moveCameraToPosition(
new GeoPoint(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude()));
@ -316,13 +327,14 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
binding.mapView.getOverlayManager().getTilesOverlay()
.setColorFilter(TilesOverlay.INVERT_COLORS);
}
if (!applicationKvStore.getBoolean("doNotAskForLocationPermission", false) ||
PermissionUtils.hasPermission(getActivity(),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION})) {
checkPermissionsAndPerformAction();
} else {
if (applicationKvStore.getBoolean("doNotAskForLocationPermission", false) &&
!locationPermissionsHelper.checkLocationPermission(getActivity())) {
isPermissionDenied = true;
}
lastKnownLocation = MapUtils.defaultLatLng;
moveCameraToPosition(
new GeoPoint(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude()));
presenter.onMapReady(exploreMapController);
}
private void initViews() {
@ -394,7 +406,6 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
public void populatePlaces(LatLng currentLatLng) {
final Observable<MapController.ExplorePlacesInfo> nearbyPlacesInfoObservable;
if (currentLatLng == null) {
checkPermissionsAndPerformAction();
return;
}
if (currentLatLng.equals(getLastMapFocus())) { // Means we are checking around current location
@ -417,8 +428,9 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
},
throwable -> {
Timber.d(throwable);
showErrorMessage(getString(R.string.error_fetching_nearby_places)
+ throwable.getLocalizedMessage());
// Not showing the user, throwable localizedErrorMessage
showErrorMessage(getString(R.string.error_fetching_nearby_places));
setProgressBarVisibility(false);
presenter.lockUnlockNearby(false);
}));
@ -445,9 +457,9 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
}
@Override
public void checkPermissionsAndPerformAction() {
Timber.d("Checking permission and perfoming action");
activityResultLauncher.launch(new String[]{permission.ACCESS_FINE_LOCATION});
public void askForLocationPermission() {
Timber.d("Asking for location permission");
activityResultLauncher.launch(permission.ACCESS_FINE_LOCATION);
}
private void locationPermissionGranted() {
@ -466,9 +478,9 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
locationManager.requestLocationUpdatesFromProvider(LocationManager.NETWORK_PROVIDER);
locationManager.requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER);
setProgressBarVisibility(true);
} else {
Toast.makeText(getContext(), getString(R.string.nearby_location_not_available),
Toast.LENGTH_LONG).show();
}
else {
locationPermissionsHelper.showLocationOffDialog(getActivity(), R.string.ask_to_turn_location_on_text);
}
presenter.onMapReady(exploreMapController);
registerUnregisterLocationListener(false);
@ -480,13 +492,24 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
@Override
public void recenterMap(LatLng currentLatLng) {
if (isPermissionDenied || currentLatLng == null) {
recenterToUserLocation = true;
checkPermissionsAndPerformAction();
if (!isPermissionDenied && !(locationManager.isNetworkProviderEnabled()
|| locationManager.isGPSProviderEnabled())) {
showLocationOffDialog();
// if user has denied permission twice, then show dialog
if (isPermissionDenied) {
if (locationPermissionsHelper.checkLocationPermission(getActivity())) {
// this will run when user has given permission by opening app's settings
isPermissionDenied = false;
recenterMap(currentLatLng);
} else {
askForLocationPermission();
}
} else {
if (!locationPermissionsHelper.checkLocationPermission(getActivity())) {
askForLocationPermission();
} else {
locationPermissionGranted();
}
}
if (currentLatLng == null) {
recenterToUserLocation = true;
return;
}
recenterMarkerToPosition(new GeoPoint(currentLatLng.getLatitude(), currentLatLng.getLongitude()));
@ -514,31 +537,6 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
}
}
@Override
public void showLocationOffDialog() {
// This creates a dialog box that prompts the user to enable location
DialogUtil
.showAlertDialog(getActivity(), getString(R.string.ask_to_turn_location_on),
getString(R.string.nearby_needs_location),
getString(R.string.yes), getString(R.string.no), this::openLocationSettings, null);
}
@Override
public void openLocationSettings() {
// This method opens the location settings of the device along with a followup toast.
final Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
final PackageManager packageManager = getActivity().getPackageManager();
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent);
Toast.makeText(getContext(), R.string.recommend_high_accuracy_mode, Toast.LENGTH_LONG)
.show();
} else {
Toast.makeText(getContext(), R.string.cannot_open_location_settings, Toast.LENGTH_LONG)
.show();
}
}
@Override
public void hideBottomDetailsSheet() {
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
@ -843,7 +841,20 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
if (mapCenter != null) {
latLnge = new fr.free.nrw.commons.location.LatLng(
mapCenter.getLatitude(), mapCenter.getLongitude(), 100);
} else {
if (applicationKvStore.getString("LastLocation") != null) {
final String[] locationLatLng
= applicationKvStore.getString("LastLocation").split(",");
lastKnownLocation
= new fr.free.nrw.commons.location.LatLng(Double.parseDouble(locationLatLng[0]),
Double.parseDouble(locationLatLng[1]), 1f);
latLnge = lastKnownLocation;
} else {
latLnge = new fr.free.nrw.commons.location.LatLng(51.506255446947776,
-0.07483536015053005, 1f);
}
}
moveCameraToPosition(new GeoPoint(latLnge.getLatitude(),latLnge.getLongitude()));
return latLnge;
}
@ -902,4 +913,10 @@ public class ExploreMapFragment extends CommonsDaggerSupportFragment
}
};
}
@Override
public void onLocationPermissionDenied(String toastMessage) {}
@Override
public void onLocationPermissionGranted() {}
}

View file

@ -131,7 +131,6 @@ public class ExploreMapPresenter
public void onMapReady(ExploreMapController exploreMapController) {
this.exploreMapController = exploreMapController;
exploreMapFragmentView.addSearchThisAreaButtonAction();
if (null != exploreMapFragmentView) {
exploreMapFragmentView.addSearchThisAreaButtonAction();
initializeMapOperations();
@ -141,7 +140,6 @@ public class ExploreMapPresenter
public void initializeMapOperations() {
lockUnlockNearby(false);
updateMap(LOCATION_SIGNIFICANTLY_CHANGED);
exploreMapFragmentView.addSearchThisAreaButtonAction();
}
public Observable<ExplorePlacesInfo> loadAttractionsFromLocation(LatLng currentLatLng,

View file

@ -1,10 +1,13 @@
package fr.free.nrw.commons.location;
import android.Manifest;
import android.Manifest.permission;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.Settings;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.filepicker.Constants.RequestCodes;
@ -12,120 +15,172 @@ import fr.free.nrw.commons.utils.DialogUtil;
import fr.free.nrw.commons.utils.PermissionUtils;
/**
* Helper class to handle location permissions
* Helper class to handle location permissions.
*
* Location flow for fragments containing a map is as follows:
* Case 1: When location permission has never been asked for or denied before
* Check if permission is already granted or not.
* If not already granted, ask for it (if it isn't denied twice before).
* If now user grants permission, go to Case 3/4, else go to Case 2.
*
* Case 2: When location permission is just asked but has been denied
* Shows a toast to tell the user why location permission is needed.
* Also shows a rationale to the user, on agreeing to which, we go back to Case 1.
* Show current location / nearby pins / nearby images according to the default location.
*
* Case 3: When location permission are already granted, but location services are off
* Asks the user to turn on the location service, using a dialog.
* If the user rejects, checks for the last known location and shows stuff using that location.
* Also displays a toast telling the user why location should be turned on.
*
* Case 4: When location permission has been granted and location services are also on
* Do whatever is required by that particular activity / fragment using current location.
*
*/
public class LocationPermissionsHelper {
Activity activity;
LocationServiceManager locationManager;
LocationPermissionCallback callback;
public LocationPermissionsHelper(Activity activity, LocationServiceManager locationManager,
LocationPermissionCallback callback) {
this.activity = activity;
this.locationManager = locationManager;
this.callback = callback;
}
public static class Dialog {
int dialogTitleResource;
int dialogTextResource;
public Dialog(int dialogTitle, int dialogText) {
dialogTitleResource = dialogTitle;
dialogTextResource = dialogText;
}
}
/**
* Handles the entire location permissions flow
* Ask for location permission if the user agrees on attaching location with pictures and the
* app does not have the access to location
*
* @param locationAccessDialog
* @param locationOffDialog
* @param dialogTitleResource Resource id of the title of the dialog
* @param dialogTextResource Resource id of the text of the dialog
*/
public void handleLocationPermissions(Dialog locationAccessDialog,
Dialog locationOffDialog) {
requestForLocationAccess(locationAccessDialog, locationOffDialog);
}
/**
* Ask for location permission if the user agrees on attaching location with pictures
* and the app does not have the access to location
*
* @param locationAccessDialog
* @param locationOffDialog
*/
private void requestForLocationAccess(
Dialog locationAccessDialog,
Dialog locationOffDialog
public void requestForLocationAccess(
int dialogTitleResource,
int dialogTextResource
) {
if (PermissionUtils.hasPermission(activity, new String[]{permission.ACCESS_FINE_LOCATION})) {
if (checkLocationPermission(activity)) {
callback.onLocationPermissionGranted();
} else {
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission.ACCESS_FINE_LOCATION)) {
if (locationAccessDialog != null && locationOffDialog != null) {
DialogUtil.showAlertDialog(activity, activity.getString(locationAccessDialog.dialogTitleResource),
activity.getString(locationAccessDialog.dialogTextResource),
if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
permission.ACCESS_FINE_LOCATION)) {
DialogUtil.showAlertDialog(activity, activity.getString(dialogTitleResource),
activity.getString(dialogTextResource),
activity.getString(android.R.string.ok),
activity.getString(android.R.string.cancel),
() -> {
if (!isLocationAccessToAppsTurnedOn()) {
showLocationOffDialog(activity);
} else {
ActivityCompat.requestPermissions(activity,
new String[]{permission.ACCESS_FINE_LOCATION}, 1);
}
},
() -> callback.onLocationPermissionDenied(activity.getString(R.string.in_app_camera_location_permission_denied)),
() -> callback.onLocationPermissionDenied(
activity.getString(R.string.upload_map_location_access)),
null,
false);
}
} else {
ActivityCompat.requestPermissions(activity, new String[]{permission.ACCESS_FINE_LOCATION},
ActivityCompat.requestPermissions(activity,
new String[]{permission.ACCESS_FINE_LOCATION},
RequestCodes.LOCATION);
}
}
}
public void showLocationOffDialog(Activity activity) {
/**
* Shows a dialog for user to open the settings page and turn on location services
*
* @param activity Activity object
* @param dialogTextResource int id of the required string resource
*/
public void showLocationOffDialog(Activity activity, int dialogTextResource) {
DialogUtil
.showAlertDialog(activity,
activity.getString(R.string.ask_to_turn_location_on),
activity.getString(R.string.in_app_camera_needs_location),
activity.getString(dialogTextResource),
activity.getString(R.string.title_app_shortcut_setting),
activity.getString(R.string.cancel),
() -> openLocationSettings(activity),
() -> callback.onLocationPermissionDenied(activity.getString(
R.string.in_app_camera_location_unavailable)));
() -> Toast.makeText(activity, activity.getString(dialogTextResource),
Toast.LENGTH_LONG).show()
);
}
/**
* Open location source settings so that apps with location access can access it
* Opens the location access page in settings, for user to turn on location services
*
* TODO: modify it to fix https://github.com/commons-app/apps-android-commons/issues/5255
* @param activity Activtiy object
*/
public void openLocationSettings(Activity activity) {
final Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
final PackageManager packageManager = activity.getPackageManager();
if (intent.resolveActivity(packageManager) != null) {
activity.startActivity(intent);
} else {
Toast.makeText(activity, R.string.cannot_open_location_settings, Toast.LENGTH_LONG)
.show();
}
}
/**
* Shows a dialog for user to open the app's settings page and give location permission
*
* @param activity Activity object
* @param dialogTextResource int id of the required string resource
*/
public void showAppSettingsDialog(Activity activity, int dialogTextResource) {
DialogUtil
.showAlertDialog(activity, activity.getString(R.string.location_permission_title),
activity.getString(dialogTextResource),
activity.getString(R.string.title_app_shortcut_setting),
activity.getString(R.string.cancel),
() -> openAppSettings(activity),
() -> Toast.makeText(activity, activity.getString(dialogTextResource),
Toast.LENGTH_LONG).show()
);
}
/**
* Opens detailed settings page of the app for the user to turn on location services
*
* @param activity Activity object
*/
public void openAppSettings(Activity activity) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
intent.setData(uri);
activity.startActivity(intent);
}
/**
* Check if apps have access to location even after having individual access
*
* @return
* @return Returns true if location services are on and false otherwise
*/
public boolean isLocationAccessToAppsTurnedOn() {
return (locationManager.isNetworkProviderEnabled() || locationManager.isGPSProviderEnabled());
return (locationManager.isNetworkProviderEnabled()
|| locationManager.isGPSProviderEnabled());
}
/**
* Checks if location permission is already granted or not
*
* @param activity Activity object
* @return Returns true if location permission is granted and false otherwise
*/
public boolean checkLocationPermission(Activity activity) {
return PermissionUtils.hasPermission(activity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION});
}
/**
* Handle onPermissionDenied within individual classes based on the requirements
*/
public interface LocationPermissionCallback {
void onLocationPermissionDenied(String toastMessage);
void onLocationPermissionGranted();
}
}

View file

@ -24,7 +24,7 @@ public interface NearbyParentFragmentContract {
boolean isListBottomSheetExpanded();
void checkPermissionsAndPerformAction();
void askForLocationPermission();
void displayLoginSkippedWarning();
@ -36,8 +36,6 @@ public interface NearbyParentFragmentContract {
void recenterMap(LatLng currentLatLng);
void showLocationOffDialog();
void openLocationSettings();
void hideBottomSheet();

View file

@ -6,7 +6,6 @@ import static fr.free.nrw.commons.location.LocationServiceManager.LocationChange
import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.MAP_UPDATED;
import static fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT;
import android.Manifest;
import android.Manifest.permission;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
@ -67,6 +66,8 @@ import fr.free.nrw.commons.contributions.MainActivity.ActiveFragment;
import fr.free.nrw.commons.databinding.FragmentNearbyParentBinding;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.location.LocationPermissionsHelper;
import fr.free.nrw.commons.location.LocationPermissionsHelper.LocationPermissionCallback;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.location.LocationServiceManager;
import fr.free.nrw.commons.location.LocationUpdateListener;
@ -84,9 +85,9 @@ import fr.free.nrw.commons.upload.FileUtils;
import fr.free.nrw.commons.utils.DialogUtil;
import fr.free.nrw.commons.utils.ExecutorUtils;
import fr.free.nrw.commons.utils.LayoutUtils;
import fr.free.nrw.commons.utils.MapUtils;
import fr.free.nrw.commons.utils.NearbyFABUtils;
import fr.free.nrw.commons.utils.NetworkUtils;
import fr.free.nrw.commons.utils.PermissionUtils;
import fr.free.nrw.commons.utils.SystemThemeUtils;
import fr.free.nrw.commons.utils.ViewUtil;
import fr.free.nrw.commons.wikidata.WikidataEditListener;
@ -130,7 +131,8 @@ import timber.log.Timber;
public class NearbyParentFragment extends CommonsDaggerSupportFragment
implements NearbyParentFragmentContract.View,
WikidataEditListener.WikidataP18EditListener, LocationUpdateListener {
WikidataEditListener.WikidataP18EditListener, LocationUpdateListener,
LocationPermissionCallback {
FragmentNearbyParentBinding binding;
@ -152,6 +154,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
SystemThemeUtils systemThemeUtils;
@Inject
CommonPlaceClickActions commonPlaceClickActions;
private LocationPermissionsHelper locationPermissionsHelper;
private NearbyFilterSearchRecyclerViewAdapter nearbyFilterSearchRecyclerViewAdapter;
private BottomSheetBehavior bottomSheetListBehavior;
private BottomSheetBehavior bottomSheetDetailsBehavior;
@ -201,7 +204,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
controller.locationPermissionCallback.onLocationPermissionGranted();
} else {
if (shouldShowRequestPermissionRationale(permission.ACCESS_FINE_LOCATION)) {
controller.handleShowRationaleFlowCameraLocation(getActivity());
controller.handleShowRationaleFlowCameraLocation(getActivity(), inAppCameraLocationPermissionLauncher);
} else {
controller.locationPermissionCallback.onLocationPermissionDenied(
getActivity().getString(
@ -223,15 +226,17 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
getActivity().getString(android.R.string.ok),
getActivity().getString(android.R.string.cancel),
() -> {
if (!(locationManager.isNetworkProviderEnabled()
|| locationManager.isGPSProviderEnabled())) {
showLocationOffDialog();
}
askForLocationPermission();
},
() -> isPermissionDenied = true,
null,
null,
false);
} else {
if (isPermissionDenied) {
locationPermissionsHelper.showAppSettingsDialog(getActivity(),
R.string.nearby_needs_location);
}
Timber.d("The user checked 'Don't ask again' or denied the permission twice");
isPermissionDenied = true;
}
}
@ -323,7 +328,8 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
} else {
binding.rlContainerWlmMonthMessage.setVisibility(View.GONE);
}
locationPermissionsHelper = new LocationPermissionsHelper(getActivity(), locationManager,
this);
presenter.attachView(this);
isPermissionDenied = false;
recenterToUserLocation = false;
@ -426,7 +432,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
}
initNearbyFilter();
addCheckBoxCallback();
performMapReadyActions();
moveCameraToPosition(lastMapFocus);
initRvNearbyList();
onResume();
@ -471,6 +476,10 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
binding.tvLearnMore.setOnClickListener(v ->onLearnMoreClicked());
binding.nearbyFilter.ivToggleChips.setOnClickListener(v -> onToggleChipsClicked());
if (!locationPermissionsHelper.checkLocationPermission(getActivity())) {
askForLocationPermission();
}
}
/**
@ -527,14 +536,18 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
private void performMapReadyActions() {
if (((MainActivity) getActivity()).activeFragment == ActiveFragment.NEARBY) {
if (!applicationKvStore.getBoolean("doNotAskForLocationPermission", false) ||
PermissionUtils.hasPermission(getActivity(),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION})) {
checkPermissionsAndPerformAction();
} else {
if (applicationKvStore.getBoolean("doNotAskForLocationPermission", false) &&
!locationPermissionsHelper.checkLocationPermission(getActivity())) {
isPermissionDenied = true;
}
}
presenter.onMapReady();
}
@Override
public void askForLocationPermission() {
Timber.d("Asking for location permission");
locationPermissionLauncher.launch(permission.ACCESS_FINE_LOCATION);
}
private void locationPermissionGranted() {
@ -554,8 +567,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
locationManager.requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER);
setProgressBarVisibility(true);
} else {
Toast.makeText(getContext(), getString(R.string.nearby_location_not_available),
Toast.LENGTH_LONG).show();
locationPermissionsHelper.showLocationOffDialog(getActivity(), R.string.ask_to_turn_location_on_text);
}
presenter.onMapReady();
registerUnregisterLocationListener(false);
@ -568,15 +580,10 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
presenter.attachView(this);
registerNetworkReceiver();
if (isResumed() && ((MainActivity) getActivity()).activeFragment == ActiveFragment.NEARBY) {
if (!isPermissionDenied && !applicationKvStore.getBoolean(
"doNotAskForLocationPermission", false)) {
if (!locationManager.isGPSProviderEnabled()) {
startMapWithCondition("Without GPS");
if (locationPermissionsHelper.checkLocationPermission(getActivity())) {
locationPermissionGranted();
} else {
startTheMap();
}
} else {
startMapWithCondition("Without Permission");
startMapWithoutPermission();
}
}
}
@ -586,12 +593,8 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
* coordinates, other than that it points to the last known location which can be get by the key
* "LastLocation" from applicationKvStore
*
* @param condition : for which condition the map should start
*/
private void startMapWithCondition(final String condition) {
if (condition.equals("Without Permission")) {
applicationKvStore.putBoolean("doNotAskForLocationPermission", true);
}
private void startMapWithoutPermission() {
if (applicationKvStore.getString("LastLocation") != null) {
final String[] locationLatLng
= applicationKvStore.getString("LastLocation").split(",");
@ -599,12 +602,13 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
= new fr.free.nrw.commons.location.LatLng(Double.parseDouble(locationLatLng[0]),
Double.parseDouble(locationLatLng[1]), 1f);
} else {
lastKnownLocation = new fr.free.nrw.commons.location.LatLng(51.50550,
-0.07520, 1f);
lastKnownLocation = MapUtils.defaultLatLng;
}
if (binding.map != null) {
recenterMap(lastKnownLocation);
moveCameraToPosition(
new GeoPoint(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude()));
}
presenter.onMapReady();
}
private void registerNetworkReceiver() {
@ -1426,12 +1430,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
// TODO
}
@Override
public void checkPermissionsAndPerformAction() {
Timber.d("Checking permission and perfoming action");
locationPermissionLauncher.launch(permission.ACCESS_FINE_LOCATION);
}
/**
* Starts animation of fab plus (turning on opening) and other FABs
*/
@ -1559,6 +1557,14 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
return presenter.backButtonClicked();
}
@Override
public void onLocationPermissionDenied(String toastMessage) {
}
@Override
public void onLocationPermissionGranted() {
}
/**
* onLogoutComplete is called after shared preferences and data stored in local database are
* cleared.
@ -1856,18 +1862,37 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
@Override
public void recenterMap(fr.free.nrw.commons.location.LatLng currentLatLng) {
if (isPermissionDenied || currentLatLng == null) {
recenterToUserLocation = true;
checkPermissionsAndPerformAction();
if (!isPermissionDenied && !(locationManager.isNetworkProviderEnabled()
|| locationManager.isGPSProviderEnabled())) {
showLocationOffDialog();
// if user has denied permission twice, then show dialog
if (isPermissionDenied) {
if (locationPermissionsHelper.checkLocationPermission(getActivity())) {
// this will run when user has given permission by opening app's settings
isPermissionDenied = false;
locationPermissionGranted();
return;
} else {
askForLocationPermission();
}
} else {
if (!locationPermissionsHelper.checkLocationPermission(getActivity())) {
askForLocationPermission();
} else {
locationPermissionGranted();
}
}
if (currentLatLng == null) {
recenterToUserLocation = true;
return;
}
addCurrentLocationMarker(currentLatLng);
binding.map.getController()
.animateTo(new GeoPoint(currentLatLng.getLatitude(), currentLatLng.getLongitude()));
/*
* FIXME: With the revamp of the location permission helper in the MR
* #5494[1], there is a doubt that the following code is redundant.
* If we could confirm the same, the following code can be removed. If it
* turns out to be necessary, we could replace this with a comment
* clarifying why it is necessary.
*
* Ref: https://github.com/commons-app/apps-android-commons/pull/5494#discussion_r1560404794
*/
if (lastMapFocus != null) {
Location mylocation = new Location("");
Location dest_location = new Location("");
@ -1890,15 +1915,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
}
}
@Override
public void showLocationOffDialog() {
// This creates a dialog box that prompts the user to enable location
DialogUtil
.showAlertDialog(getActivity(), getString(R.string.ask_to_turn_location_on),
getString(R.string.nearby_needs_location),
getString(R.string.yes), getString(R.string.no), this::openLocationSettings, null);
}
@Override
public void openLocationSettings() {
// This method opens the location settings of the device along with a followup toast.
@ -2103,7 +2119,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
super.setUserVisibleHint(isVisibleToUser);
this.isVisibleToUser = isVisibleToUser;
if (isResumed() && isVisibleToUser) {
startTheMap();
performMapReadyActions();
} else {
if (null != bottomSheetListBehavior) {
bottomSheetListBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
@ -2115,10 +2131,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
}
}
private void startTheMap() {
performMapReadyActions();
}
/**
* Clears all markers from the map and resets certain map overlays and gestures. After clearing
* markers, it re-adds a scale bar overlay and rotation gesture overlay to the map.

View file

@ -92,7 +92,6 @@ public class NearbyParentFragmentPresenter
public void initializeMapOperations() {
lockUnlockNearby(false);
updateMapAndList(LOCATION_SIGNIFICANTLY_CHANGED);
this.nearbyParentFragmentView.addSearchThisAreaButtonAction();
nearbyParentFragmentView.setCheckBoxAction();
}

View file

@ -93,7 +93,7 @@ public class SettingsFragment extends PreferenceFragmentCompat {
areAllGranted = areAllGranted && b;
}
if (!areAllGranted && shouldShowRequestPermissionRationale(permission.ACCESS_FINE_LOCATION)) {
contributionController.handleShowRationaleFlowCameraLocation(getActivity());
contributionController.handleShowRationaleFlowCameraLocation(getActivity(), inAppCameraLocationPermissionLauncher);
}
}
});

View file

@ -282,6 +282,8 @@
<string name="nearby_location_not_available">Nearby might not work properly, Location not available.</string>
<string name="upload_location_access_denied">Location access denied. Please set your location manually to use this feature.</string>
<string name="location_permission_rationale_nearby">Permission required to display a list of nearby places</string>
<string name="location_permission_rationale_explore">Permission required to display a list of nearby images</string>
<string name="nearby_directions">Directions</string>
<string name="nearby_wikidata">Wikidata</string>
@ -355,7 +357,7 @@
<string name="share_app_title">Share App</string>
<string name="rotate">Rotate</string>
<string name="error_fetching_nearby_places">Error fetching nearby places.</string>
<string name="error_fetching_nearby_places">Could not load nearby places</string>
<string name="no_pictures_in_this_area">No pictures in this area</string>
<string name="no_nearby_places_around">No nearby places around</string>
<string name="error_fetching_nearby_monuments">Error fetching nearby monuments.</string>
@ -586,7 +588,7 @@ Upload your first media by tapping on the add button.</string>
<string name="coordinates_edit_helper_edit_message_else">Could not add coordinates.</string>
<string name="description_edit_helper_edit_message_else">Could not add descriptions.</string>
<string name="caption_edit_helper_edit_message_else">Could not add caption.</string>
<string name="coordinates_picking_unsuccessful">Unable to get coordinates.</string>
<string name="coordinates_picking_unsuccessful">Image\'s coordinates not updated</string>
<string name="descriptions_picking_unsuccessful">Unable to get descriptions.</string>
<string name="description_activity_title">Edit descriptions and captions</string>
@ -623,8 +625,10 @@ Upload your first media by tapping on the add button.</string>
<string name="cannot_open_location_settings">Failed to open location settings. Please turn on location manually</string>
<string name="recommend_high_accuracy_mode">For best results, choose the High Accuracy mode.</string>
<string name="ask_to_turn_location_on">Turn on location?</string>
<string name="ask_to_turn_location_on_text">Kindly turn on location services for the app show your current location</string>
<string name="nearby_needs_location">Nearby needs location enabled to work properly</string>
<string name="upload_map_location_access">You need to give access to your current location to set location automatically.</string>
<string name="explore_map_needs_location">Explore map needs location permission to display nearby images</string>
<string name="upload_map_location_access">You need to give location permission to set location automatically.</string>
<string name="use_location_from_similar_image">Did you shoot these two pictures at the same place? Do you want to use the latitude/longitude of the picture on the right?</string>
<string name="load_more">Load More</string>
<string name="nearby_no_results">No places found, try changing your search criteria.</string>

View file

@ -71,7 +71,6 @@ class NearbyParentFragmentPresenterTest {
verify(nearbyParentFragmentView).`setProgressBarVisibility`(true)
assertTrue(null == nearbyParentFragmentView.mapCenter)
verify(nearbyParentFragmentView).populatePlaces(null)
verify(nearbyParentFragmentView).addSearchThisAreaButtonAction()
verify(nearbyParentFragmentView).setCheckBoxAction()
}
@ -121,7 +120,7 @@ class NearbyParentFragmentPresenterTest {
/**
* Test updateMapAndList method returns with zero interactions when last location is null
*/
@Test @Ignore
@Test
fun testUpdateMapAndListWhenLastLocationIsNull() {
whenever(nearbyParentFragmentView.isNetworkConnectionEstablished()).thenReturn(true)
whenever(nearbyParentFragmentView.getLastLocation()).thenReturn(null)

View file

@ -379,12 +379,4 @@ class NearbyParentFragmentUnitTest {
Assert.assertEquals(shadowActivity.nextStartedActivityForResult, null)
}
@Test @Ignore
@Throws(Exception::class)
fun testShowLocationOffDialog() {
fragment.showLocationOffDialog()
val dialog: AlertDialog = ShadowAlertDialog.getLatestDialog() as AlertDialog
Assert.assertEquals(dialog.isShowing, true)
}
}