mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 21:03:54 +01:00
Merge branch 'master' of https://github.com/siva-subramaniam-v/apps-android-commons into gradle-version-upgrade
This commit is contained in:
commit
c4d4cbeae2
73 changed files with 801 additions and 186 deletions
|
|
@ -147,7 +147,11 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
|||
loginCredentials.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the keyboard if the user's focus is not on the password (hasFocus is false).
|
||||
* @param view The keyboard
|
||||
* @param hasFocus Set to true if the keyboard has focus
|
||||
*/
|
||||
@OnFocusChange(R.id.login_password)
|
||||
void onPasswordFocusChanged(View view, boolean hasFocus) {
|
||||
if (!hasFocus) {
|
||||
|
|
|
|||
|
|
@ -3,12 +3,9 @@ package fr.free.nrw.commons.contributions;
|
|||
import static fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT;
|
||||
|
||||
import android.Manifest;
|
||||
import android.Manifest.permission;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import androidx.annotation.NonNull;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.filepicker.DefaultCallback;
|
||||
|
|
@ -70,15 +67,6 @@ public class ContributionController {
|
|||
PermissionUtils.checkPermissionsAndPerformAction(activity,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
() -> {
|
||||
if (VERSION.SDK_INT >= VERSION_CODES.Q) {
|
||||
PermissionUtils.checkPermissionsAndPerformAction(
|
||||
activity,
|
||||
permission.ACCESS_MEDIA_LOCATION,
|
||||
() -> {},
|
||||
R.string.media_location_permission_denied,
|
||||
R.string.add_location_manually
|
||||
);
|
||||
}
|
||||
FilePicker.openCustomSelector(activity, 0);
|
||||
},
|
||||
R.string.storage_permission_title,
|
||||
|
|
@ -91,7 +79,8 @@ public class ContributionController {
|
|||
*/
|
||||
private void initiateGalleryUpload(final Activity activity, final boolean allowMultipleUploads) {
|
||||
setPickerConfiguration(activity, allowMultipleUploads);
|
||||
FilePicker.openGallery(activity, 0);
|
||||
boolean isGetContentPickerPreferred = defaultKvStore.getBoolean("getContentPhotoPickerPref");
|
||||
FilePicker.openGallery(activity, 0, isGetContentPickerPreferred);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import android.app.Activity;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Bundle;
|
||||
|
|
@ -152,6 +151,20 @@ public class MainActivity extends BaseActivity
|
|||
}
|
||||
}
|
||||
setUpPager();
|
||||
/**
|
||||
* Ask the user for media location access just after login
|
||||
* so that location in the EXIF metadata of the images shared by the user
|
||||
* is retained on devices running Android 10 or above
|
||||
*/
|
||||
if (VERSION.SDK_INT >= VERSION_CODES.Q) {
|
||||
PermissionUtils.checkPermissionsAndPerformAction(
|
||||
this,
|
||||
permission.ACCESS_MEDIA_LOCATION,
|
||||
() -> {},
|
||||
R.string.media_location_permission_denied,
|
||||
R.string.add_location_manually
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,10 +44,11 @@ public class FilePicker implements Constants {
|
|||
return uri;
|
||||
}
|
||||
|
||||
private static Intent createGalleryIntent(@NonNull Context context, int type) {
|
||||
private static Intent createGalleryIntent(@NonNull Context context, int type,
|
||||
boolean isGetContentPickerPreferred) {
|
||||
// storing picked image type to shared preferences
|
||||
storeType(context, type);
|
||||
return plainGalleryPickerIntent()
|
||||
return plainGalleryPickerIntent(isGetContentPickerPreferred)
|
||||
.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, configuration(context).allowsMultiplePickingInGallery());
|
||||
}
|
||||
|
||||
|
|
@ -103,8 +104,8 @@ public class FilePicker implements Constants {
|
|||
*
|
||||
* @param type Custom type of your choice, which will be returned with the images
|
||||
*/
|
||||
public static void openGallery(Activity activity, int type) {
|
||||
Intent intent = createGalleryIntent(activity, type);
|
||||
public static void openGallery(Activity activity, int type, boolean isGetContentPickerPreferred) {
|
||||
Intent intent = createGalleryIntent(activity, type, isGetContentPickerPreferred);
|
||||
activity.startActivityForResult(intent, RequestCodes.PICK_PICTURE_FROM_GALLERY);
|
||||
}
|
||||
|
||||
|
|
@ -198,8 +199,40 @@ public class FilePicker implements Constants {
|
|||
return data == null || (data.getData() == null && data.getClipData() == null);
|
||||
}
|
||||
|
||||
private static Intent plainGalleryPickerIntent() {
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
private static Intent plainGalleryPickerIntent(boolean isGetContentPickerPreferred) {
|
||||
/**
|
||||
* Asking for ACCESS_MEDIA_LOCATION at runtime solved the location-loss issue
|
||||
* in the custom selector in Contributions fragment.
|
||||
* Detailed discussion: https://github.com/commons-app/apps-android-commons/issues/5015
|
||||
*
|
||||
* This permission check, however, was insufficient to fix location-loss in
|
||||
* the regular selector in Contributions fragment and Nearby fragment,
|
||||
* especially on some devices running Android 13 that use the new Photo Picker by default.
|
||||
*
|
||||
* New Photo Picker: https://developer.android.com/training/data-storage/shared/photopicker
|
||||
*
|
||||
* The new Photo Picker introduced by Android redacts location tags from EXIF metadata.
|
||||
* Reported on the Google Issue Tracker: https://issuetracker.google.com/issues/243294058
|
||||
* Status: Won't fix (Intended behaviour)
|
||||
*
|
||||
* Switched intent from ACTION_GET_CONTENT to ACTION_OPEN_DOCUMENT
|
||||
* (based on user's preference) as:
|
||||
*
|
||||
* ACTION_GET_CONTENT opens the 'best application' for choosing that kind of data
|
||||
* The best application is the new Photo Picker that redacts the location tags
|
||||
*
|
||||
* ACTION_OPEN_DOCUMENT, however, displays the various DocumentsProvider instances
|
||||
* installed on the device, letting the user interactively navigate through them.
|
||||
*
|
||||
* So, this allows us to use the traditional file picker that does not redact location tags from EXIF.
|
||||
*
|
||||
*/
|
||||
Intent intent;
|
||||
if (isGetContentPickerPreferred) {
|
||||
intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
} else {
|
||||
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
}
|
||||
intent.setType("image/*");
|
||||
return intent;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,10 @@ public class LatLng implements Parcelable {
|
|||
this.latitude = Math.max(-90.0D, Math.min(90.0D, latitude));
|
||||
this.accuracy = accuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* An alternate constructor for this class.
|
||||
* @param in A parcelable which contains the latitude, longitude, and accuracy
|
||||
*/
|
||||
public LatLng(Parcel in) {
|
||||
latitude = in.readDouble();
|
||||
longitude = in.readDouble();
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ import com.facebook.imagepipeline.image.ImageInfo;
|
|||
import com.facebook.imagepipeline.request.ImageRequest;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.LocationPicker.LocationPicker;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.MediaDataExtractor;
|
||||
|
|
@ -1232,6 +1233,12 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
|||
if (media == null || media.getUser() == null) {
|
||||
return;
|
||||
}
|
||||
if (sessionManager.getUserName() == null) {
|
||||
String userProfileLink = BuildConfig.COMMONS_URL + "/wiki/User:" + media.getUser();
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(userProfileLink));
|
||||
startActivity(browserIntent);
|
||||
return;
|
||||
}
|
||||
ProfileActivity.startYourself(getActivity(), media.getUser(), !Objects
|
||||
.equals(sessionManager.getUserName(), media.getUser()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
/**
|
||||
* Saves response of list of places for the first time
|
||||
*/
|
||||
private List<Place> places;
|
||||
private List<Place> places = new ArrayList<>();
|
||||
|
||||
@NonNull
|
||||
public static NearbyParentFragment newInstance() {
|
||||
|
|
|
|||
|
|
@ -129,6 +129,10 @@ public class ReviewImageFragment extends CommonsDaggerSupportFragment {
|
|||
|
||||
if (getReviewActivity().reviewController.firstRevision != null) {
|
||||
user = getReviewActivity().reviewController.firstRevision.getUser();
|
||||
} else {
|
||||
if(savedInstanceState != null) {
|
||||
user = savedInstanceState.getString(SAVED_USER);
|
||||
}
|
||||
}
|
||||
|
||||
//if the user is null because of whatsoever reason, review will not be sent anyways
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import fr.free.nrw.commons.recentlanguages.Language;
|
|||
import fr.free.nrw.commons.recentlanguages.RecentLanguagesAdapter;
|
||||
import fr.free.nrw.commons.recentlanguages.RecentLanguagesDao;
|
||||
import fr.free.nrw.commons.upload.LanguagesAdapter;
|
||||
import fr.free.nrw.commons.utils.DialogUtil;
|
||||
import fr.free.nrw.commons.utils.PermissionUtils;
|
||||
import fr.free.nrw.commons.utils.ViewUtil;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -71,6 +72,7 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
|||
private TextView recentLanguagesTextView;
|
||||
private View separator;
|
||||
private ListView languageHistoryListView;
|
||||
private static final String GET_CONTENT_PICKER_HELP_URL = "https://commons-app.github.io/docs.html#get-content";
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
|
|
@ -150,6 +152,17 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
|||
checkPermissionsAndSendLogs();
|
||||
return true;
|
||||
});
|
||||
|
||||
Preference getContentPickerPreference = findPreference("getContentPhotoPickerPref");
|
||||
getContentPickerPreference.setOnPreferenceChangeListener(
|
||||
(preference, newValue) -> {
|
||||
boolean isGetContentPickerTurnedOn = (boolean) newValue;
|
||||
if (isGetContentPickerTurnedOn) {
|
||||
showLocationLossWarning();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
// Disable some settings when not logged in.
|
||||
if (defaultKvStore.getBoolean("login_skipped", false)) {
|
||||
findPreference("useExternalStorage").setEnabled(false);
|
||||
|
|
@ -162,6 +175,26 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On some devices, the new Photo Picker with GET_CONTENT takeover
|
||||
* redacts location tags from EXIF metadata
|
||||
*
|
||||
* Show warning to the user when ACTION_GET_CONTENT intent is enabled
|
||||
*/
|
||||
private void showLocationLossWarning() {
|
||||
DialogUtil.showAlertDialog(
|
||||
getActivity(),
|
||||
null,
|
||||
getString(R.string.location_loss_warning),
|
||||
getString(R.string.ok),
|
||||
getString(R.string.read_help_link),
|
||||
() -> {},
|
||||
() -> Utils.handleWebUrl(requireContext(), Uri.parse(GET_CONTENT_PICKER_HELP_URL)),
|
||||
null,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Adapter onCreateAdapter(final PreferenceScreen preferenceScreen) {
|
||||
return new PreferenceGroupAdapter(preferenceScreen) {
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@ package fr.free.nrw.commons.upload.mediaDetails;
|
|||
import static fr.free.nrw.commons.di.CommonsApplicationModule.IO_THREAD;
|
||||
import static fr.free.nrw.commons.di.CommonsApplicationModule.MAIN_THREAD;
|
||||
import static fr.free.nrw.commons.utils.ImageUtils.EMPTY_CAPTION;
|
||||
import static fr.free.nrw.commons.utils.ImageUtils.FILE_FBMD;
|
||||
import static fr.free.nrw.commons.utils.ImageUtils.FILE_NAME_EXISTS;
|
||||
import static fr.free.nrw.commons.utils.ImageUtils.FILE_NO_EXIF;
|
||||
import static fr.free.nrw.commons.utils.ImageUtils.IMAGE_BLURRY;
|
||||
import static fr.free.nrw.commons.utils.ImageUtils.IMAGE_DARK;
|
||||
import static fr.free.nrw.commons.utils.ImageUtils.IMAGE_GEOLOCATION_DIFFERENT;
|
||||
import static fr.free.nrw.commons.utils.ImageUtils.IMAGE_KEEP;
|
||||
import static fr.free.nrw.commons.utils.ImageUtils.IMAGE_OK;
|
||||
|
||||
|
|
@ -331,11 +326,8 @@ public class UploadMediaPresenter implements UserActionListener, SimilarImageInt
|
|||
view.showDuplicatePicturePopup(uploadItem);
|
||||
}
|
||||
|
||||
// If image has some problems check if the bits are set in errorCode and
|
||||
// show popup accordingly
|
||||
if (((errorCode & FILE_NO_EXIF) != 0) || ((errorCode & IMAGE_DARK) != 0) ||
|
||||
((errorCode & FILE_FBMD) != 0) || ((errorCode & IMAGE_GEOLOCATION_DIFFERENT) != 0) ||
|
||||
((errorCode & IMAGE_BLURRY) != 0)) {
|
||||
// If image has some other problems, show popup accordingly
|
||||
if (errorCode != EMPTY_CAPTION && errorCode != FILE_NAME_EXISTS) {
|
||||
view.showBadImagePopup(errorCode, uploadItem);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue