mirror of
				https://github.com/commons-app/apps-android-commons.git
				synced 2025-10-31 06:43:56 +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
	
	 Siva Subramaniam
						Siva Subramaniam