mirror of
				https://github.com/commons-app/apps-android-commons.git
				synced 2025-10-31 14:53:59 +01:00 
			
		
		
		
	Migrated location and language module from Java to Kotlin
This commit is contained in:
		
							parent
							
								
									574b9e3c15
								
							
						
					
					
						commit
						4148049156
					
				
					 10 changed files with 467 additions and 521 deletions
				
			
		|  | @ -423,7 +423,7 @@ class LocationPickerActivity : BaseActivity(), LocationPermissionCallback { | ||||||
|      * Moves map to GPS location |      * Moves map to GPS location | ||||||
|      */ |      */ | ||||||
|     private fun moveMapToGPSLocation() { |     private fun moveMapToGPSLocation() { | ||||||
|         locationManager.lastLocation?.let { |         locationManager.lastLocationVar?.let { | ||||||
|             moveMapTo(GeoPoint(it.latitude, it.longitude)) |             moveMapTo(GeoPoint(it.latitude, it.longitude)) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -591,7 +591,7 @@ class LocationPickerActivity : BaseActivity(), LocationPermissionCallback { | ||||||
| 
 | 
 | ||||||
|     override fun onLocationPermissionGranted() { |     override fun onLocationPermissionGranted() { | ||||||
|         if (moveToCurrentLocation || activity != "MediaActivity") { |         if (moveToCurrentLocation || activity != "MediaActivity") { | ||||||
|             if (locationPermissionsHelper.isLocationAccessToAppsTurnedOn) { |             if (locationPermissionsHelper.isLocationAccessToAppsTurnedOn()) { | ||||||
|                 locationManager.requestLocationUpdatesFromProvider(LocationManager.NETWORK_PROVIDER) |                 locationManager.requestLocationUpdatesFromProvider(LocationManager.NETWORK_PROVIDER) | ||||||
|                 locationManager.requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER) |                 locationManager.requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER) | ||||||
|                 addMarkerAtGPSLocation() |                 addMarkerAtGPSLocation() | ||||||
|  | @ -606,7 +606,7 @@ class LocationPickerActivity : BaseActivity(), LocationPermissionCallback { | ||||||
|      * Adds a marker at the user's GPS location |      * Adds a marker at the user's GPS location | ||||||
|      */ |      */ | ||||||
|     private fun addMarkerAtGPSLocation() { |     private fun addMarkerAtGPSLocation() { | ||||||
|         locationManager.lastLocation?.let { |         locationManager.lastLocationVar?.let { | ||||||
|             addLocationMarker(GeoPoint(it.latitude, it.longitude)) |             addLocationMarker(GeoPoint(it.latitude, it.longitude)) | ||||||
|             markerImage.translationY = 0f |             markerImage.translationY = 0f | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -1,116 +1,111 @@ | ||||||
| package fr.free.nrw.commons.language; | package fr.free.nrw.commons.language | ||||||
| 
 | 
 | ||||||
| import android.content.Context; | import android.content.Context | ||||||
| import android.content.res.Resources; | import android.content.res.Resources | ||||||
| import android.text.TextUtils; | import android.text.TextUtils | ||||||
| 
 | 
 | ||||||
| import androidx.annotation.ArrayRes; | import androidx.annotation.ArrayRes | ||||||
| import androidx.annotation.NonNull; | import fr.free.nrw.commons.R | ||||||
| import androidx.annotation.Nullable; | import java.lang.ref.SoftReference | ||||||
|  | import java.util.Arrays | ||||||
|  | import java.util.Locale | ||||||
| 
 | 
 | ||||||
| import fr.free.nrw.commons.R; |  | ||||||
| import java.lang.ref.SoftReference; |  | ||||||
| import java.util.Arrays; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.Locale; |  | ||||||
| 
 | 
 | ||||||
| /** Immutable look up table for all app supported languages. All article languages may not be | /** Immutable look up table for all app supported languages. All article languages may not be | ||||||
|   * present in this table as it is statically bundled with the app. */ |  * present in this table as it is statically bundled with the app. */ | ||||||
| public class AppLanguageLookUpTable { | class AppLanguageLookUpTable(context: Context) { | ||||||
|     public static final String SIMPLIFIED_CHINESE_LANGUAGE_CODE = "zh-hans"; |  | ||||||
|     public static final String TRADITIONAL_CHINESE_LANGUAGE_CODE = "zh-hant"; |  | ||||||
|     public static final String CHINESE_CN_LANGUAGE_CODE = "zh-cn"; |  | ||||||
|     public static final String CHINESE_HK_LANGUAGE_CODE = "zh-hk"; |  | ||||||
|     public static final String CHINESE_MO_LANGUAGE_CODE = "zh-mo"; |  | ||||||
|     public static final String CHINESE_SG_LANGUAGE_CODE = "zh-sg"; |  | ||||||
|     public static final String CHINESE_TW_LANGUAGE_CODE = "zh-tw"; |  | ||||||
|     public static final String CHINESE_YUE_LANGUAGE_CODE = "zh-yue"; |  | ||||||
|     public static final String CHINESE_LANGUAGE_CODE = "zh"; |  | ||||||
|     public static final String NORWEGIAN_LEGACY_LANGUAGE_CODE = "no"; |  | ||||||
|     public static final String NORWEGIAN_BOKMAL_LANGUAGE_CODE = "nb"; |  | ||||||
|     public static final String TEST_LANGUAGE_CODE = "test"; |  | ||||||
|     public static final String FALLBACK_LANGUAGE_CODE = "en"; // Must exist in preference_language_keys. |  | ||||||
| 
 | 
 | ||||||
|     @NonNull private final Resources resources; |     companion object { | ||||||
|  |         const val SIMPLIFIED_CHINESE_LANGUAGE_CODE = "zh-hans" | ||||||
|  |         const val TRADITIONAL_CHINESE_LANGUAGE_CODE = "zh-hant" | ||||||
|  |         const val CHINESE_CN_LANGUAGE_CODE = "zh-cn" | ||||||
|  |         const val CHINESE_HK_LANGUAGE_CODE = "zh-hk" | ||||||
|  |         const val CHINESE_MO_LANGUAGE_CODE = "zh-mo" | ||||||
|  |         const val CHINESE_SG_LANGUAGE_CODE = "zh-sg" | ||||||
|  |         const val CHINESE_TW_LANGUAGE_CODE = "zh-tw" | ||||||
|  |         const val CHINESE_YUE_LANGUAGE_CODE = "zh-yue" | ||||||
|  |         const val CHINESE_LANGUAGE_CODE = "zh" | ||||||
|  |         const val NORWEGIAN_LEGACY_LANGUAGE_CODE = "no" | ||||||
|  |         const val NORWEGIAN_BOKMAL_LANGUAGE_CODE = "nb" | ||||||
|  |         const val TEST_LANGUAGE_CODE = "test" | ||||||
|  |         const val FALLBACK_LANGUAGE_CODE = "en" // Must exist in preference_language_keys. | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private val resources: Resources = context.resources | ||||||
| 
 | 
 | ||||||
|     // Language codes for all app supported languages in fixed order. The special code representing |     // Language codes for all app supported languages in fixed order. The special code representing | ||||||
|     // the dynamic system language is null. |     // the dynamic system language is null. | ||||||
|     @NonNull private SoftReference<List<String>> codesRef = new SoftReference<>(null); |     private var codesRef = SoftReference<List<String>>(null) | ||||||
| 
 | 
 | ||||||
|     // English names for all app supported languages in fixed order. |     // English names for all app supported languages in fixed order. | ||||||
|     @NonNull private SoftReference<List<String>> canonicalNamesRef = new SoftReference<>(null); |     private var canonicalNamesRef = SoftReference<List<String>>(null) | ||||||
| 
 | 
 | ||||||
|     // Native names for all app supported languages in fixed order. |     // Native names for all app supported languages in fixed order. | ||||||
|     @NonNull private SoftReference<List<String>> localizedNamesRef = new SoftReference<>(null); |     private var localizedNamesRef = SoftReference<List<String>>(null) | ||||||
| 
 |  | ||||||
|     public AppLanguageLookUpTable(@NonNull Context context) { |  | ||||||
|         resources = context.getResources(); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @return Nonnull immutable list. The special code representing the dynamic system language is |      * @return Nonnull immutable list. The special code representing the dynamic system language is | ||||||
|      *         null. |      *         null. | ||||||
|      */ |      */ | ||||||
|     @NonNull |     fun getCodes(): List<String> { | ||||||
|     public List<String> getCodes() { |         var codes = codesRef.get() | ||||||
|         List<String> codes = codesRef.get(); |  | ||||||
|         if (codes == null) { |         if (codes == null) { | ||||||
|             codes = getStringList(R.array.preference_language_keys); |             codes = getStringList(R.array.preference_language_keys) | ||||||
|             codesRef = new SoftReference<>(codes); |             codesRef = SoftReference(codes) | ||||||
|         } |         } | ||||||
|         return codes; |         return codes | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Nullable |     fun getCanonicalName(code: String?): String? { | ||||||
|     public String getCanonicalName(@Nullable String code) { |         var name = defaultIndex(getCanonicalNames(), indexOfCode(code), null) | ||||||
|         String name = defaultIndex(getCanonicalNames(), indexOfCode(code), null); |         if (name.isNullOrEmpty() && !code.isNullOrEmpty()) { | ||||||
|         if (TextUtils.isEmpty(name) && !TextUtils.isEmpty(code)) { |             name = when (code) { | ||||||
|             if (code.equals(Locale.CHINESE.getLanguage())) { |                 Locale.CHINESE.language -> Locale.CHINESE.getDisplayName(Locale.ENGLISH) | ||||||
|                 name = Locale.CHINESE.getDisplayName(Locale.ENGLISH); |                 NORWEGIAN_LEGACY_LANGUAGE_CODE -> | ||||||
|             } else if (code.equals(NORWEGIAN_LEGACY_LANGUAGE_CODE)) { |                     defaultIndex(getCanonicalNames(), indexOfCode(NORWEGIAN_BOKMAL_LANGUAGE_CODE), null) | ||||||
|                 name = defaultIndex(getCanonicalNames(), indexOfCode(NORWEGIAN_BOKMAL_LANGUAGE_CODE), null); |                 else -> null | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return name; |         return name | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Nullable |     fun getLocalizedName(code: String?): String? { | ||||||
|     public String getLocalizedName(@Nullable String code) { |         var name = defaultIndex(getLocalizedNames(), indexOfCode(code), null) | ||||||
|         String name = defaultIndex(getLocalizedNames(), indexOfCode(code), null); |         if (name.isNullOrEmpty() && !code.isNullOrEmpty()) { | ||||||
|         if (TextUtils.isEmpty(name) && !TextUtils.isEmpty(code)) { |             name = when (code) { | ||||||
|             if (code.equals(Locale.CHINESE.getLanguage())) { |                 Locale.CHINESE.language -> Locale.CHINESE.getDisplayName(Locale.CHINESE) | ||||||
|                 name = Locale.CHINESE.getDisplayName(Locale.CHINESE); |                 NORWEGIAN_LEGACY_LANGUAGE_CODE -> | ||||||
|             } else if (code.equals(NORWEGIAN_LEGACY_LANGUAGE_CODE)) { |                     defaultIndex(getLocalizedNames(), indexOfCode(NORWEGIAN_BOKMAL_LANGUAGE_CODE), null) | ||||||
|                 name = defaultIndex(getLocalizedNames(), indexOfCode(NORWEGIAN_BOKMAL_LANGUAGE_CODE), null); |                 else -> null | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return name; |         return name | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public List<String> getCanonicalNames() { |     fun getCanonicalNames(): List<String> { | ||||||
|         List<String> names = canonicalNamesRef.get(); |         var names = canonicalNamesRef.get() | ||||||
|         if (names == null) { |         if (names == null) { | ||||||
|             names = getStringList(R.array.preference_language_canonical_names); |             names = getStringList(R.array.preference_language_canonical_names) | ||||||
|             canonicalNamesRef = new SoftReference<>(names); |             canonicalNamesRef = SoftReference(names) | ||||||
|         } |         } | ||||||
|         return names; |         return names | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public List<String> getLocalizedNames() { |     fun getLocalizedNames(): List<String> { | ||||||
|         List<String> names = localizedNamesRef.get(); |         var names = localizedNamesRef.get() | ||||||
|         if (names == null) { |         if (names == null) { | ||||||
|             names = getStringList(R.array.preference_language_local_names); |             names = getStringList(R.array.preference_language_local_names) | ||||||
|             localizedNamesRef = new SoftReference<>(names); |             localizedNamesRef = SoftReference(names) | ||||||
|         } |         } | ||||||
|         return names; |         return names | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public boolean isSupportedCode(@Nullable String code) { |     fun isSupportedCode(code: String?): Boolean { | ||||||
|         return getCodes().contains(code); |         return getCodes().contains(code) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private <T> T defaultIndex(List<T> list, int index, T defaultValue) { |     private fun <T> defaultIndex(list: List<T>, index: Int, defaultValue: T?): T? { | ||||||
|         return inBounds(list, index) ? list.get(index) : defaultValue; |         return if (inBounds(list, index)) list[index] else defaultValue | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | @ -121,21 +116,20 @@ public class AppLanguageLookUpTable { | ||||||
|      *             language is null. |      *             language is null. | ||||||
|      * @return The index of the language code or -1 if the code is not supported. |      * @return The index of the language code or -1 if the code is not supported. | ||||||
|      */ |      */ | ||||||
|     private int indexOfCode(@Nullable String code) { |     private fun indexOfCode(code: String?): Int { | ||||||
|         return getCodes().indexOf(code); |         return getCodes().indexOf(code) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** @return Nonnull immutable list. */ |     /** @return Nonnull immutable list. */ | ||||||
|     @NonNull |     private fun getStringList(id: Int): List<String> { | ||||||
|     private List<String> getStringList(int id) { |         return getStringArray(id).toList() | ||||||
|         return Arrays.asList(getStringArray(id)); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private boolean inBounds(List<?> list, int index) { |     private fun inBounds(list: List<*>, index: Int): Boolean { | ||||||
|         return index >= 0 && index < list.size(); |         return index in list.indices | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public String[] getStringArray(@ArrayRes int id) { |     fun getStringArray(@ArrayRes id: Int): Array<String> { | ||||||
|         return resources.getStringArray(id); |         return resources.getStringArray(id) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,132 +1,106 @@ | ||||||
| package fr.free.nrw.commons.location; | package fr.free.nrw.commons.location | ||||||
| 
 | 
 | ||||||
| import android.location.Location; | import android.location.Location | ||||||
| import android.net.Uri; | import android.net.Uri | ||||||
| import android.os.Parcel; | import android.os.Parcel | ||||||
| import android.os.Parcelable; | import android.os.Parcelable | ||||||
|  | import kotlin.math.abs | ||||||
|  | import kotlin.math.max | ||||||
|  | import kotlin.math.min | ||||||
|  | import kotlin.math.round | ||||||
| 
 | 
 | ||||||
| import androidx.annotation.NonNull; |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * a latitude and longitude point with accuracy information, often of a picture |  * A latitude and longitude point with accuracy information, often of a picture. | ||||||
|  */ |  */ | ||||||
| public class LatLng implements Parcelable { | data class LatLng( | ||||||
| 
 |     var latitude: Double, | ||||||
|     private final double latitude; |     var longitude: Double, | ||||||
|     private final double longitude; |     val accuracy: Float | ||||||
|     private final float accuracy; | ) : Parcelable { | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Accepts latitude and longitude. |      * Accepts latitude and longitude. | ||||||
|      * North and South values are cut off at 90° |      * North and South values are cut off at 90° | ||||||
|      * |      * | ||||||
|      * @param latitude the latitude |  | ||||||
|      * @param longitude the longitude |  | ||||||
|      * @param accuracy the accuracy |  | ||||||
|      * |  | ||||||
|      * Examples: |      * Examples: | ||||||
|      * the Statue of Liberty is located at 40.69° N, 74.04° W |      * the Statue of Liberty is located at 40.69° N, 74.04° W | ||||||
|      * The Statue of Liberty could be constructed as LatLng(40.69, -74.04, 1.0) |      * The Statue of Liberty could be constructed as LatLng(40.69, -74.04, 1.0) | ||||||
|      * where positive signifies north, east and negative signifies south, west. |      * where positive signifies north, east and negative signifies south, west. | ||||||
|      */ |      */ | ||||||
|     public LatLng(double latitude, double longitude, float accuracy) { |     init { | ||||||
|         if (-180.0D <= longitude && longitude < 180.0D) { |         val adjustedLongitude = when { | ||||||
|             this.longitude = longitude; |             longitude in -180.0..180.0 -> longitude | ||||||
|         } else { |             else -> ((longitude - 180.0) % 360.0 + 360.0) % 360.0 - 180.0 | ||||||
|             this.longitude = ((longitude - 180.0D) % 360.0D + 360.0D) % 360.0D - 180.0D; |  | ||||||
|         } |         } | ||||||
|         this.latitude = Math.max(-90.0D, Math.min(90.0D, latitude)); |         latitude = max(-90.0, min(90.0, latitude)) | ||||||
|         this.accuracy = accuracy; |         longitude = adjustedLongitude | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Accepts a non-null [Location] and converts it to a [LatLng]. | ||||||
|  |      */ | ||||||
|  |     companion object { | ||||||
|  |         /** | ||||||
|  |          * gets the latitude and longitude of a given non-null location | ||||||
|  |          * @param location the non-null location of the user | ||||||
|  |          * @return LatLng the Latitude and Longitude of a given location | ||||||
|  |          */ | ||||||
|  |         @JvmStatic | ||||||
|  |         fun from(location: Location): LatLng { | ||||||
|  |             return LatLng(location.latitude, location.longitude, location.accuracy) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @JvmField | ||||||
|  |         val CREATOR: Parcelable.Creator<LatLng> = object : Parcelable.Creator<LatLng> { | ||||||
|  |             override fun createFromParcel(parcel: Parcel): LatLng { | ||||||
|  |                 return LatLng(parcel) | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             override fun newArray(size: Int): Array<LatLng?> { | ||||||
|  |                 return arrayOfNulls(size) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * An alternate constructor for this class. |      * An alternate constructor for this class. | ||||||
|      * @param in A parcelable which contains the latitude, longitude, and accuracy |      * @param parcel A parcelable which contains the latitude, longitude, and accuracy | ||||||
|      */ |      */ | ||||||
|     public LatLng(Parcel in) { |     private constructor(parcel: Parcel) : this( | ||||||
|         latitude = in.readDouble(); |         latitude = parcel.readDouble(), | ||||||
|         longitude = in.readDouble(); |         longitude = parcel.readDouble(), | ||||||
|         accuracy = in.readFloat(); |         accuracy = parcel.readFloat() | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Creates a hash code for the latitude and longitude. | ||||||
|  |      */ | ||||||
|  |     override fun hashCode(): Int { | ||||||
|  |         var result = 1 | ||||||
|  |         val latitudeBits = latitude.toBits() | ||||||
|  |         result = 31 * result + (latitudeBits xor (latitudeBits ushr 32)).toInt() | ||||||
|  |         val longitudeBits = longitude.toBits() | ||||||
|  |         result = 31 * result + (longitudeBits xor (longitudeBits ushr 32)).toInt() | ||||||
|  |         return result | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * gets the latitude and longitude of a given non-null location |      * Checks for equality of two LatLng objects. | ||||||
|      * @param location the non-null location of the user |      * @param other the second LatLng object | ||||||
|      * @return LatLng the Latitude and Longitude of a given location |  | ||||||
|      */ |      */ | ||||||
|     public static LatLng from(@NonNull Location location) { |     override fun equals(other: Any?): Boolean { | ||||||
|         return new LatLng(location.getLatitude(), location.getLongitude(), location.getAccuracy()); |         if (this === other) return true | ||||||
|  |         if (other !is LatLng) return false | ||||||
|  |         return latitude.toBits() == other.latitude.toBits() && | ||||||
|  |                 longitude.toBits() == other.longitude.toBits() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * creates a hash code for the longitude and longitude |      * Returns a string representation of the latitude and longitude. | ||||||
|      */ |      */ | ||||||
|     public int hashCode() { |     override fun toString(): String { | ||||||
|         byte var1 = 1; |         return "lat/lng: ($latitude,$longitude)" | ||||||
|         long var2 = Double.doubleToLongBits(this.latitude); |  | ||||||
|         int var3 = 31 * var1 + (int)(var2 ^ var2 >>> 32); |  | ||||||
|         var2 = Double.doubleToLongBits(this.longitude); |  | ||||||
|         var3 = 31 * var3 + (int)(var2 ^ var2 >>> 32); |  | ||||||
|         return var3; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * checks for equality of two LatLng objects |  | ||||||
|      * @param o the second LatLng object |  | ||||||
|      */ |  | ||||||
|     public boolean equals(Object o) { |  | ||||||
|         if (this == o) { |  | ||||||
|             return true; |  | ||||||
|         } else if (!(o instanceof LatLng)) { |  | ||||||
|             return false; |  | ||||||
|         } else { |  | ||||||
|             LatLng var2 = (LatLng)o; |  | ||||||
|             return Double.doubleToLongBits(this.latitude) == Double.doubleToLongBits(var2.latitude) && Double.doubleToLongBits(this.longitude) == Double.doubleToLongBits(var2.longitude); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * returns a string representation of the latitude and longitude |  | ||||||
|      */ |  | ||||||
|     public String toString() { |  | ||||||
|         return "lat/lng: (" + this.latitude + "," + this.longitude + ")"; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Rounds the float to 4 digits and returns absolute value. |  | ||||||
|      * |  | ||||||
|      * @param coordinate A coordinate value as string. |  | ||||||
|      * @return String of the rounded number. |  | ||||||
|      */ |  | ||||||
|     private String formatCoordinate(double coordinate) { |  | ||||||
|         double roundedNumber = Math.round(coordinate * 10000d) / 10000d; |  | ||||||
|         double absoluteNumber = Math.abs(roundedNumber); |  | ||||||
|         return String.valueOf(absoluteNumber); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Returns "N" or "S" depending on the latitude. |  | ||||||
|      * |  | ||||||
|      * @return "N" or "S". |  | ||||||
|      */ |  | ||||||
|     private String getNorthSouth() { |  | ||||||
|         if (this.latitude < 0) { |  | ||||||
|             return "S"; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return "N"; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Returns "E" or "W" depending on the longitude. |  | ||||||
|      * |  | ||||||
|      * @return "E" or "W". |  | ||||||
|      */ |  | ||||||
|     private String getEastWest() { |  | ||||||
|         if (this.longitude >= 0 && this.longitude < 180) { |  | ||||||
|             return "E"; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return "W"; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | @ -135,64 +109,42 @@ public class LatLng implements Parcelable { | ||||||
|      * |      * | ||||||
|      * @return The formatted string. |      * @return The formatted string. | ||||||
|      */ |      */ | ||||||
|     public String getPrettyCoordinateString() { |     fun getPrettyCoordinateString(): String { | ||||||
|         return formatCoordinate(this.latitude) + " " + this.getNorthSouth() + ", " |         return "${formatCoordinate(latitude)} ${getNorthSouth()}, " + | ||||||
|                + formatCoordinate(this.longitude) + " " + this.getEastWest(); |                 "${formatCoordinate(longitude)} ${getEastWest()}" | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Return the location accuracy in meter. |      * Gets a URI for a Google Maps intent at the location. | ||||||
|      * |  | ||||||
|      * @return float |  | ||||||
|      */ |      */ | ||||||
|     public float getAccuracy() { |     fun getGmmIntentUri(): Uri { | ||||||
|         return accuracy; |         return Uri.parse("geo:$latitude,$longitude?z=16") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun writeToParcel(parcel: Parcel, flags: Int) { | ||||||
|  |         parcel.writeDouble(latitude) | ||||||
|  |         parcel.writeDouble(longitude) | ||||||
|  |         parcel.writeFloat(accuracy) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun describeContents(): Int = 0 | ||||||
|  | 
 | ||||||
|  |     private fun formatCoordinate(coordinate: Double): String { | ||||||
|  |         val roundedNumber = round(coordinate * 10000) / 10000 | ||||||
|  |         return abs(roundedNumber).toString() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Return the longitude in degrees. |      * Returns "N" or "S" depending on the latitude. | ||||||
|      * |      * | ||||||
|      * @return double |      * @return "N" or "S". | ||||||
|      */ |      */ | ||||||
|     public double getLongitude() { |     private fun getNorthSouth(): String = if (latitude < 0) "S" else "N" | ||||||
|         return longitude; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Return the latitude in degrees. |      * Returns "E" or "W" depending on the longitude. | ||||||
|      * |      * | ||||||
|      * @return double |      * @return "E" or "W". | ||||||
|      */ |      */ | ||||||
|     public double getLatitude() { |     private fun getEastWest(): String = if (longitude in 0.0..179.999) "E" else "W" | ||||||
|         return latitude; | } | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Uri getGmmIntentUri() { |  | ||||||
|         return Uri.parse("geo:" + latitude + "," + longitude + "?z=16"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int describeContents() { |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void writeToParcel(Parcel dest, int flags) { |  | ||||||
|         dest.writeDouble(latitude); |  | ||||||
|         dest.writeDouble(longitude); |  | ||||||
|         dest.writeFloat(accuracy); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public static final Creator<LatLng> CREATOR = new Creator<LatLng>() { |  | ||||||
|         @Override |  | ||||||
|         public LatLng createFromParcel(Parcel in) { |  | ||||||
|             return new LatLng(in); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         @Override |  | ||||||
|         public LatLng[] newArray(int size) { |  | ||||||
|             return new LatLng[size]; |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
|  | @ -1,18 +1,16 @@ | ||||||
| package fr.free.nrw.commons.location; | package fr.free.nrw.commons.location | ||||||
| 
 | 
 | ||||||
| import android.Manifest; | import android.Manifest.permission | ||||||
| import android.Manifest.permission; | import android.app.Activity | ||||||
| import android.app.Activity; | import android.content.Intent | ||||||
| import android.content.Intent; | import android.net.Uri | ||||||
| import android.content.pm.PackageManager; | import android.provider.Settings | ||||||
| import android.net.Uri; | import android.widget.Toast | ||||||
| import android.provider.Settings; | import androidx.core.app.ActivityCompat | ||||||
| import android.widget.Toast; | import fr.free.nrw.commons.R | ||||||
| import androidx.core.app.ActivityCompat; | import fr.free.nrw.commons.filepicker.Constants.RequestCodes | ||||||
| import fr.free.nrw.commons.R; | import fr.free.nrw.commons.utils.DialogUtil | ||||||
| import fr.free.nrw.commons.filepicker.Constants.RequestCodes; | import fr.free.nrw.commons.utils.PermissionUtils | ||||||
| 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. | ||||||
|  | @ -37,51 +35,58 @@ import fr.free.nrw.commons.utils.PermissionUtils; | ||||||
|  * Do whatever is required by that particular activity / fragment using current location. |  * Do whatever is required by that particular activity / fragment using current location. | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| public class LocationPermissionsHelper { | class LocationPermissionsHelper( | ||||||
| 
 |     private val activity: Activity, | ||||||
|     Activity activity; |     private val locationManager: LocationServiceManager, | ||||||
|     LocationServiceManager locationManager; |     private val callback: LocationPermissionCallback? | ||||||
|     LocationPermissionCallback callback; | ) { | ||||||
| 
 |  | ||||||
|     public LocationPermissionsHelper(Activity activity, LocationServiceManager locationManager, |  | ||||||
|         LocationPermissionCallback callback) { |  | ||||||
|         this.activity = activity; |  | ||||||
|         this.locationManager = locationManager; |  | ||||||
|         this.callback = callback; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Ask for location permission if the user agrees on attaching location with pictures and the |      * Ask for location permission if the user agrees on attaching location with pictures and the | ||||||
|      * app does not have the access to location |      * app does not have the access to location | ||||||
|      * |      * | ||||||
|      * @param dialogTitleResource Resource id of the title of the dialog  |      * @param dialogTitleResource Resource id of the title of the dialog | ||||||
|      * @param dialogTextResource Resource id of the text of the dialog  |      * @param dialogTextResource Resource id of the text of the dialog | ||||||
|      */ |      */ | ||||||
|     public void requestForLocationAccess( |     fun requestForLocationAccess( | ||||||
|         int dialogTitleResource, |         dialogTitleResource: Int, | ||||||
|         int dialogTextResource |         dialogTextResource: Int | ||||||
|     ) { |     ) { | ||||||
|         if (checkLocationPermission(activity)) { |         if (checkLocationPermission(activity)) { | ||||||
|             callback.onLocationPermissionGranted(); |             callback?.onLocationPermissionGranted() | ||||||
|         } else { |         } else { | ||||||
|             if (ActivityCompat.shouldShowRequestPermissionRationale(activity, |             if (ActivityCompat.shouldShowRequestPermissionRationale( | ||||||
|                 permission.ACCESS_FINE_LOCATION)) { |                     activity, | ||||||
|                 DialogUtil.showAlertDialog(activity, activity.getString(dialogTitleResource), |                     permission.ACCESS_FINE_LOCATION | ||||||
|  |                 ) | ||||||
|  |             ) { | ||||||
|  |                 DialogUtil.showAlertDialog( | ||||||
|  |                     activity, | ||||||
|  |                     activity.getString(dialogTitleResource), | ||||||
|                     activity.getString(dialogTextResource), |                     activity.getString(dialogTextResource), | ||||||
|                     activity.getString(android.R.string.ok), |                     activity.getString(android.R.string.ok), | ||||||
|                     activity.getString(android.R.string.cancel), |                     activity.getString(android.R.string.cancel), | ||||||
|                     () -> { |                     { | ||||||
|                         ActivityCompat.requestPermissions(activity, |                         ActivityCompat.requestPermissions( | ||||||
|                             new String[]{permission.ACCESS_FINE_LOCATION}, 1); |                             activity, | ||||||
|  |                             arrayOf(permission.ACCESS_FINE_LOCATION), | ||||||
|  |                             1 | ||||||
|  |                         ) | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         callback?.onLocationPermissionDenied( | ||||||
|  |                             activity.getString(R.string.upload_map_location_access) | ||||||
|  |                         ) | ||||||
|                     }, |                     }, | ||||||
|                     () -> callback.onLocationPermissionDenied( |  | ||||||
|                         activity.getString(R.string.upload_map_location_access)), |  | ||||||
|                     null, |                     null, | ||||||
|                     false); |                     false | ||||||
|  |                 ) | ||||||
|             } else { |             } else { | ||||||
|                 ActivityCompat.requestPermissions(activity, |                 ActivityCompat.requestPermissions( | ||||||
|                     new String[]{permission.ACCESS_FINE_LOCATION}, |                     activity, | ||||||
|                     RequestCodes.LOCATION); |                     arrayOf(permission.ACCESS_FINE_LOCATION), | ||||||
|  |                     RequestCodes.LOCATION | ||||||
|  |                 ) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -92,33 +97,38 @@ public class LocationPermissionsHelper { | ||||||
|      * @param activity Activity object |      * @param activity Activity object | ||||||
|      * @param dialogTextResource int id of the required string resource |      * @param dialogTextResource int id of the required string resource | ||||||
|      */ |      */ | ||||||
|     public void showLocationOffDialog(Activity activity, int dialogTextResource) { |     fun showLocationOffDialog(activity: Activity, dialogTextResource: Int) { | ||||||
|         DialogUtil |         DialogUtil.showAlertDialog( | ||||||
|             .showAlertDialog(activity, |             activity, | ||||||
|                 activity.getString(R.string.ask_to_turn_location_on), |             activity.getString(R.string.ask_to_turn_location_on), | ||||||
|                 activity.getString(dialogTextResource), |             activity.getString(dialogTextResource), | ||||||
|                 activity.getString(R.string.title_app_shortcut_setting), |             activity.getString(R.string.title_app_shortcut_setting), | ||||||
|                 activity.getString(R.string.cancel), |             activity.getString(R.string.cancel), | ||||||
|                 () -> openLocationSettings(activity), |             { openLocationSettings(activity) }, | ||||||
|                 () -> Toast.makeText(activity, activity.getString(dialogTextResource), |             { | ||||||
|                     Toast.LENGTH_LONG).show() |                 Toast.makeText( | ||||||
|             ); |                     activity, | ||||||
|  |                     activity.getString(dialogTextResource), | ||||||
|  |                     Toast.LENGTH_LONG | ||||||
|  |                 ).show() | ||||||
|  |             } | ||||||
|  |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Opens the location access page in settings, for user to turn on location services |      * Opens the location access page in settings, for user to turn on location services | ||||||
|      * |      * | ||||||
|      * @param activity Activtiy object |      * @param activity Activity object | ||||||
|      */ |      */ | ||||||
|     public void openLocationSettings(Activity activity) { |     fun openLocationSettings(activity: Activity) { | ||||||
|         final Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); |         val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS) | ||||||
|         final PackageManager packageManager = activity.getPackageManager(); |         val packageManager = activity.packageManager | ||||||
| 
 | 
 | ||||||
|         if (intent.resolveActivity(packageManager) != null) { |         if (intent.resolveActivity(packageManager) != null) { | ||||||
|             activity.startActivity(intent); |             activity.startActivity(intent) | ||||||
|         } else { |         } else { | ||||||
|             Toast.makeText(activity, R.string.cannot_open_location_settings, Toast.LENGTH_LONG) |             Toast.makeText(activity, R.string.cannot_open_location_settings, Toast.LENGTH_LONG) | ||||||
|                 .show(); |                 .show() | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -128,16 +138,22 @@ public class LocationPermissionsHelper { | ||||||
|      * @param activity Activity object |      * @param activity Activity object | ||||||
|      * @param dialogTextResource int id of the required string resource |      * @param dialogTextResource int id of the required string resource | ||||||
|      */ |      */ | ||||||
|     public void showAppSettingsDialog(Activity activity, int dialogTextResource) { |     fun showAppSettingsDialog(activity: Activity, dialogTextResource: Int) { | ||||||
|         DialogUtil |         DialogUtil.showAlertDialog( | ||||||
|             .showAlertDialog(activity, activity.getString(R.string.location_permission_title), |             activity, | ||||||
|                 activity.getString(dialogTextResource), |             activity.getString(R.string.location_permission_title), | ||||||
|                 activity.getString(R.string.title_app_shortcut_setting), |             activity.getString(dialogTextResource), | ||||||
|                 activity.getString(R.string.cancel), |             activity.getString(R.string.title_app_shortcut_setting), | ||||||
|                 () -> openAppSettings(activity), |             activity.getString(R.string.cancel), | ||||||
|                 () -> Toast.makeText(activity, activity.getString(dialogTextResource), |             { openAppSettings(activity) }, | ||||||
|                     Toast.LENGTH_LONG).show() |             { | ||||||
|             ); |                 Toast.makeText( | ||||||
|  |                     activity, | ||||||
|  |                     activity.getString(dialogTextResource), | ||||||
|  |                     Toast.LENGTH_LONG | ||||||
|  |                 ).show() | ||||||
|  |             } | ||||||
|  |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | @ -145,22 +161,20 @@ public class LocationPermissionsHelper { | ||||||
|      * |      * | ||||||
|      * @param activity Activity object |      * @param activity Activity object | ||||||
|      */ |      */ | ||||||
|     public void openAppSettings(Activity activity) { |     private fun openAppSettings(activity: Activity) { | ||||||
|         Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); |         val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) | ||||||
|         Uri uri = Uri.fromParts("package", activity.getPackageName(), null); |         val uri = Uri.fromParts("package", activity.packageName, null) | ||||||
|         intent.setData(uri); |         intent.data = uri | ||||||
|         activity.startActivity(intent); |         activity.startActivity(intent) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * Check if apps have access to location even after having individual access |      * Check if apps have access to location even after having individual access | ||||||
|      * |      * | ||||||
|      * @return Returns true if location services are on and false otherwise |      * @return Returns true if location services are on and false otherwise | ||||||
|      */ |      */ | ||||||
|     public boolean isLocationAccessToAppsTurnedOn() { |     fun isLocationAccessToAppsTurnedOn(): Boolean { | ||||||
|         return (locationManager.isNetworkProviderEnabled() |         return locationManager.isNetworkProviderEnabled() || locationManager.isGPSProviderEnabled() | ||||||
|             || locationManager.isGPSProviderEnabled()); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | @ -169,18 +183,18 @@ public class LocationPermissionsHelper { | ||||||
|      * @param activity Activity object |      * @param activity Activity object | ||||||
|      * @return Returns true if location permission is granted and false otherwise |      * @return Returns true if location permission is granted and false otherwise | ||||||
|      */ |      */ | ||||||
|     public boolean checkLocationPermission(Activity activity) { |     fun checkLocationPermission(activity: Activity): Boolean { | ||||||
|         return PermissionUtils.hasPermission(activity, |         return PermissionUtils.hasPermission( | ||||||
|             new String[]{Manifest.permission.ACCESS_FINE_LOCATION}); |             activity, | ||||||
|  |             arrayOf(permission.ACCESS_FINE_LOCATION) | ||||||
|  |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Handle onPermissionDenied within individual classes based on the requirements |      * Handle onPermissionDenied within individual classes based on the requirements | ||||||
|      */ |      */ | ||||||
|     public interface LocationPermissionCallback { |     interface LocationPermissionCallback { | ||||||
| 
 |         fun onLocationPermissionDenied(toastMessage: String) | ||||||
|         void onLocationPermissionDenied(String toastMessage); |         fun onLocationPermissionGranted() | ||||||
| 
 |  | ||||||
|         void onLocationPermissionGranted(); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,90 +1,85 @@ | ||||||
| package fr.free.nrw.commons.location; | package fr.free.nrw.commons.location | ||||||
| 
 | 
 | ||||||
| import android.Manifest.permission; | import android.Manifest | ||||||
| import android.app.Activity; | import android.app.Activity | ||||||
| import android.content.Context; | import android.content.Context | ||||||
| import android.content.pm.PackageManager; | import android.content.pm.PackageManager | ||||||
| import android.location.Location; | import android.location.Location | ||||||
| import android.location.LocationListener; | import android.location.LocationListener | ||||||
| import android.location.LocationManager; | import android.location.LocationManager | ||||||
| import android.os.Bundle; | import android.os.Bundle | ||||||
| import androidx.core.app.ActivityCompat; | import androidx.core.app.ActivityCompat | ||||||
| import java.util.HashSet; | import timber.log.Timber | ||||||
| import java.util.List; | import java.util.concurrent.CopyOnWriteArrayList | ||||||
| import java.util.Set; |  | ||||||
| import java.util.concurrent.CopyOnWriteArrayList; |  | ||||||
| 
 | 
 | ||||||
| import timber.log.Timber; |  | ||||||
| 
 | 
 | ||||||
| public class LocationServiceManager implements LocationListener { | class LocationServiceManager(private val context: Context) : LocationListener { | ||||||
| 
 | 
 | ||||||
|     // Maybe these values can be improved for efficiency |     companion object { | ||||||
|     private static final long MIN_LOCATION_UPDATE_REQUEST_TIME_IN_MILLIS = 10 * 100; |         // Maybe these values can be improved for efficiency | ||||||
|     private static final long MIN_LOCATION_UPDATE_REQUEST_DISTANCE_IN_METERS = 1; |         private const val MIN_LOCATION_UPDATE_REQUEST_TIME_IN_MILLIS = 10 * 100L | ||||||
|  |         private const val MIN_LOCATION_UPDATE_REQUEST_DISTANCE_IN_METERS = 1f | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     private LocationManager locationManager; |     private val locationManager: LocationManager = | ||||||
|     private Location lastLocation; |         context.getSystemService(Context.LOCATION_SERVICE) as LocationManager | ||||||
|     //private Location lastLocationDuplicate; // Will be used for nearby card view on contributions activity |     var lastLocationVar: Location? = null | ||||||
|     private final List<LocationUpdateListener> locationListeners = new CopyOnWriteArrayList<>(); |     private val locationListeners = CopyOnWriteArrayList<LocationUpdateListener>() | ||||||
|     private boolean isLocationManagerRegistered = false; |     private var isLocationManagerRegistered = false | ||||||
|     private Set<Activity> locationExplanationDisplayed = new HashSet<>(); |     private val locationExplanationDisplayed = mutableSetOf<Activity>() | ||||||
|     private Context context; |  | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Constructs a new instance of LocationServiceManager. |      * Constructs a new instance of LocationServiceManager. | ||||||
|      * |      * | ||||||
|      * @param context the context |  | ||||||
|      */ |      */ | ||||||
|     public LocationServiceManager(Context context) { |     fun getLastLocation(): LatLng? { | ||||||
|         this.context = context; |         if (lastLocationVar == null) { | ||||||
|         this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); |             lastLocationVar = getLastKnownLocation() | ||||||
|  |             return lastLocationVar?.let { LatLng.from(it) } | ||||||
|  |         } | ||||||
|  |         return LatLng.from(lastLocationVar!!) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public LatLng getLastLocation() { |     private fun getLastKnownLocation(): Location? { | ||||||
|         if (lastLocation == null) { |         val providers = locationManager.getProviders(true) | ||||||
|                 lastLocation = getLastKnownLocation(); |         var bestLocation: Location? = null | ||||||
|                 if(lastLocation != null) { |         for (provider in providers) { | ||||||
|                     return LatLng.from(lastLocation); |             val location: Location? = if ( | ||||||
|                 } |                 ActivityCompat.checkSelfPermission( | ||||||
|                 else { |                     context, | ||||||
|                     return null; |                     Manifest.permission.ACCESS_FINE_LOCATION) | ||||||
|                 } |                 == | ||||||
|         } |                 PackageManager.PERMISSION_GRANTED && | ||||||
|         return LatLng.from(lastLocation); |                 ActivityCompat.checkSelfPermission( | ||||||
|     } |                     context, | ||||||
|  |                     Manifest.permission.ACCESS_COARSE_LOCATION) | ||||||
|  |                 == | ||||||
|  |                 PackageManager.PERMISSION_GRANTED | ||||||
|  |             ) { | ||||||
|  |                 locationManager.getLastKnownLocation(provider) | ||||||
|  |             } else { | ||||||
|  |                 null | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|     private Location getLastKnownLocation() { |             if ( | ||||||
|         List<String> providers = locationManager.getProviders(true); |                 location != null | ||||||
|         Location bestLocation = null; |                 && | ||||||
|         for (String provider : providers) { |                 (bestLocation == null || location.accuracy < bestLocation.accuracy) | ||||||
|             Location l=null; |             ) { | ||||||
|             if (ActivityCompat.checkSelfPermission(context, permission.ACCESS_FINE_LOCATION) |                 bestLocation = location | ||||||
|                 == PackageManager.PERMISSION_GRANTED |  | ||||||
|                 && ActivityCompat.checkSelfPermission(context, permission.ACCESS_COARSE_LOCATION) |  | ||||||
|                 == PackageManager.PERMISSION_GRANTED) { |  | ||||||
|                 l = locationManager.getLastKnownLocation(provider); |  | ||||||
|             } |  | ||||||
|             if (l == null) { |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|             if (bestLocation == null |  | ||||||
|                 || l.getAccuracy() < bestLocation.getAccuracy()) { |  | ||||||
|                 bestLocation = l; |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         if (bestLocation == null) { |         return bestLocation | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|         return bestLocation; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Registers a LocationManager to listen for current location. |      * Registers a LocationManager to listen for current location. | ||||||
|      */ |      */ | ||||||
|     public void registerLocationManager() { |     fun registerLocationManager() { | ||||||
|         if (!isLocationManagerRegistered) { |         if (!isLocationManagerRegistered) { | ||||||
|             isLocationManagerRegistered = requestLocationUpdatesFromProvider(LocationManager.NETWORK_PROVIDER) |             isLocationManagerRegistered = | ||||||
|                     && requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER); |                 requestLocationUpdatesFromProvider(LocationManager.NETWORK_PROVIDER) && | ||||||
|  |                     requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -94,100 +89,86 @@ public class LocationServiceManager implements LocationListener { | ||||||
|      * @param locationProvider the location provider |      * @param locationProvider the location provider | ||||||
|      * @return true if successful |      * @return true if successful | ||||||
|      */ |      */ | ||||||
|     public boolean requestLocationUpdatesFromProvider(String locationProvider) { |     fun requestLocationUpdatesFromProvider(locationProvider: String): Boolean { | ||||||
|         try { |         return try { | ||||||
|             // If both providers are not available |             if (locationManager.allProviders.contains(locationProvider)) { | ||||||
|             if (locationManager == null || !(locationManager.getAllProviders().contains(locationProvider))) { |                 locationManager.requestLocationUpdates( | ||||||
|                 return false; |                     locationProvider, | ||||||
|             } |  | ||||||
|             locationManager.requestLocationUpdates(locationProvider, |  | ||||||
|                     MIN_LOCATION_UPDATE_REQUEST_TIME_IN_MILLIS, |                     MIN_LOCATION_UPDATE_REQUEST_TIME_IN_MILLIS, | ||||||
|                     MIN_LOCATION_UPDATE_REQUEST_DISTANCE_IN_METERS, |                     MIN_LOCATION_UPDATE_REQUEST_DISTANCE_IN_METERS, | ||||||
|                     this); |                     this | ||||||
|             return true; |                 ) | ||||||
|         } catch (IllegalArgumentException e) { |                 true | ||||||
|             Timber.e(e, "Illegal argument exception"); |             } else { | ||||||
|             return false; |                 false | ||||||
|         } catch (SecurityException e) { |             } | ||||||
|             Timber.e(e, "Security exception"); |         } catch (e: IllegalArgumentException) { | ||||||
|             return false; |             Timber.e(e, "Illegal argument exception") | ||||||
|  |             false | ||||||
|  |         } catch (e: SecurityException) { | ||||||
|  |             Timber.e(e, "Security exception") | ||||||
|  |             false | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Returns whether a given location is better than the current best location. |      * Returns whether a given location is better than the current best location. | ||||||
|      * |      * | ||||||
|      * @param location            the location to be tested |      * @param location the location to be tested | ||||||
|      * @param currentBestLocation the current best location |      * @param currentBestLocation the current best location | ||||||
|      * @return LOCATION_SIGNIFICANTLY_CHANGED if location changed significantly |      * @return LOCATION_SIGNIFICANTLY_CHANGED if location changed significantly | ||||||
|      * LOCATION_SLIGHTLY_CHANGED if location changed slightly |      * LOCATION_SLIGHTLY_CHANGED if location changed slightly | ||||||
|      */ |      */ | ||||||
|     private LocationChangeType isBetterLocation(Location location, Location currentBestLocation) { |     private fun isBetterLocation(location: Location, currentBestLocation: Location?): LocationChangeType { | ||||||
| 
 |  | ||||||
|         if (currentBestLocation == null) { |         if (currentBestLocation == null) { | ||||||
|             // A new location is always better than no location |             return LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED | ||||||
|             return LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Check whether the new location fix is newer or older |         val timeDelta = location.time - currentBestLocation.time | ||||||
|         long timeDelta = location.getTime() - currentBestLocation.getTime(); |         val isSignificantlyNewer = timeDelta > MIN_LOCATION_UPDATE_REQUEST_TIME_IN_MILLIS | ||||||
|         boolean isSignificantlyNewer = timeDelta > MIN_LOCATION_UPDATE_REQUEST_TIME_IN_MILLIS; |         val isNewer = timeDelta > 0 | ||||||
|         boolean isNewer = timeDelta > 0; |         val accuracyDelta = (location.accuracy - currentBestLocation.accuracy).toInt() | ||||||
|  |         val isMoreAccurate = accuracyDelta < 0 | ||||||
|  |         val isSignificantlyLessAccurate = accuracyDelta > 200 | ||||||
|  |         val isFromSameProvider = isSameProvider(location.provider, currentBestLocation.provider) | ||||||
| 
 | 
 | ||||||
|         // Check whether the new location fix is more or less accurate |         val results = FloatArray(5) | ||||||
|         int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); |  | ||||||
|         boolean isLessAccurate = accuracyDelta > 0; |  | ||||||
|         boolean isMoreAccurate = accuracyDelta < 0; |  | ||||||
|         boolean isSignificantlyLessAccurate = accuracyDelta > 200; |  | ||||||
| 
 |  | ||||||
|         // Check if the old and new location are from the same provider |  | ||||||
|         boolean isFromSameProvider = isSameProvider(location.getProvider(), |  | ||||||
|                 currentBestLocation.getProvider()); |  | ||||||
| 
 |  | ||||||
|         float[] results = new float[5]; |  | ||||||
|         Location.distanceBetween( |         Location.distanceBetween( | ||||||
|                         currentBestLocation.getLatitude(), |             currentBestLocation.latitude, currentBestLocation.longitude, | ||||||
|                         currentBestLocation.getLongitude(), |             location.latitude, location.longitude, | ||||||
|                         location.getLatitude(), |             results | ||||||
|                         location.getLongitude(), |         ) | ||||||
|                         results); |  | ||||||
| 
 | 
 | ||||||
|         // If it's been more than two minutes since the current location, use the new location |         return when { | ||||||
|         // because the user has likely moved |             isSignificantlyNewer | ||||||
|         if (isSignificantlyNewer |                     || | ||||||
|                 || isMoreAccurate |                     isMoreAccurate | ||||||
|                 || (isNewer && !isLessAccurate) |                     || | ||||||
|                 || (isNewer && !isSignificantlyLessAccurate && isFromSameProvider)) { |                     (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) -> { | ||||||
|             if (results[0] < 1000) { // Means change is smaller than 1000 meter |                 if (results[0] < 1000) LocationChangeType.LOCATION_SLIGHTLY_CHANGED | ||||||
|                 return LocationChangeType.LOCATION_SLIGHTLY_CHANGED; |                 else LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED | ||||||
|             } else { |  | ||||||
|                 return LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED; |  | ||||||
|             } |             } | ||||||
|         } else{ |             else -> LocationChangeType.LOCATION_NOT_CHANGED | ||||||
|             return LocationChangeType.LOCATION_NOT_CHANGED; |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Checks whether two providers are the same |      * Checks whether two providers are the same | ||||||
|      */ |      */ | ||||||
|     private boolean isSameProvider(String provider1, String provider2) { |     private fun isSameProvider(provider1: String?, provider2: String?): Boolean { | ||||||
|         if (provider1 == null) { |         return provider1 == provider2 | ||||||
|             return provider2 == null; |  | ||||||
|         } |  | ||||||
|         return provider1.equals(provider2); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Unregisters location manager. |      * Unregisters location manager. | ||||||
|      */ |      */ | ||||||
|     public void unregisterLocationManager() { |     fun unregisterLocationManager() { | ||||||
|         isLocationManagerRegistered = false; |         isLocationManagerRegistered = false | ||||||
|         locationExplanationDisplayed.clear(); |         locationExplanationDisplayed.clear() | ||||||
|         try { |         try { | ||||||
|             locationManager.removeUpdates(this); |             locationManager.removeUpdates(this) | ||||||
|         } catch (SecurityException e) { |         } catch (e: SecurityException) { | ||||||
|             Timber.e(e, "Security exception"); |             Timber.e(e, "Security exception") | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -196,9 +177,9 @@ public class LocationServiceManager implements LocationListener { | ||||||
|      * |      * | ||||||
|      * @param listener the new listener |      * @param listener the new listener | ||||||
|      */ |      */ | ||||||
|     public void addLocationListener(LocationUpdateListener listener) { |     fun addLocationListener(listener: LocationUpdateListener) { | ||||||
|         if (!locationListeners.contains(listener)) { |         if (!locationListeners.contains(listener)) { | ||||||
|             locationListeners.add(listener); |             locationListeners.add(listener) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -207,64 +188,55 @@ public class LocationServiceManager implements LocationListener { | ||||||
|      * |      * | ||||||
|      * @param listener the listener to be removed |      * @param listener the listener to be removed | ||||||
|      */ |      */ | ||||||
|     public void removeLocationListener(LocationUpdateListener listener) { |     fun removeLocationListener(listener: LocationUpdateListener) { | ||||||
|         locationListeners.remove(listener); |         locationListeners.remove(listener) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     override fun onLocationChanged(location: Location) { | ||||||
|     public void onLocationChanged(Location location) { |         Timber.d("on location changed") | ||||||
|         Timber.d("on location changed"); |         val changeType = isBetterLocation(location, lastLocationVar) | ||||||
|             if (isBetterLocation(location, lastLocation) |         if (changeType == LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED) { | ||||||
|                     .equals(LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED)) { |             lastLocationVar = location | ||||||
|                 lastLocation = location; |             locationListeners.forEach { it.onLocationChangedSignificantly(LatLng.from(location)) } | ||||||
|                 //lastLocationDuplicate = location; |         } else if (lastLocationVar?.let { location.distanceTo(it) }!! >= 500) { | ||||||
|                 for (LocationUpdateListener listener : locationListeners) { |             locationListeners.forEach { it.onLocationChangedMedium(LatLng.from(location)) } | ||||||
|                     listener.onLocationChangedSignificantly(LatLng.from(lastLocation)); |         } else if (changeType == LocationChangeType.LOCATION_SLIGHTLY_CHANGED) { | ||||||
|                 } |             lastLocationVar = location | ||||||
|             } else if (location.distanceTo(lastLocation) >= 500) { |             locationListeners.forEach { it.onLocationChangedSlightly(LatLng.from(location)) } | ||||||
|                 // Update nearby notification card at every 500 meters. |         } | ||||||
|                 for (LocationUpdateListener listener : locationListeners) { |  | ||||||
|                     listener.onLocationChangedMedium(LatLng.from(lastLocation)); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             else if (isBetterLocation(location, lastLocation) |  | ||||||
|                     .equals(LocationChangeType.LOCATION_SLIGHTLY_CHANGED)) { |  | ||||||
|                 lastLocation = location; |  | ||||||
|                 //lastLocationDuplicate = location; |  | ||||||
|                 for (LocationUpdateListener listener : locationListeners) { |  | ||||||
|                     listener.onLocationChangedSlightly(LatLng.from(lastLocation)); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Deprecated("Deprecated in Java", ReplaceWith( | ||||||
|     public void onStatusChanged(String provider, int status, Bundle extras) { |         "Timber.d(\"%s's status changed to %d\", provider, status)", | ||||||
|         Timber.d("%s's status changed to %d", provider, status); |         "timber.log.Timber" | ||||||
|  |     ) | ||||||
|  |     ) | ||||||
|  |     override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) { | ||||||
|  |         Timber.d("%s's status changed to %d", provider, status) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override | 
 | ||||||
|     public void onProviderEnabled(String provider) { | 
 | ||||||
|         Timber.d("Provider %s enabled", provider); |     override fun onProviderEnabled(provider: String) { | ||||||
|  |         Timber.d("Provider %s enabled", provider) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     override fun onProviderDisabled(provider: String) { | ||||||
|     public void onProviderDisabled(String provider) { |         Timber.d("Provider %s disabled", provider) | ||||||
|         Timber.d("Provider %s disabled", provider); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public boolean isNetworkProviderEnabled() { |     fun isNetworkProviderEnabled(): Boolean { | ||||||
|         return locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); |         return locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public boolean isGPSProviderEnabled() { |     fun isGPSProviderEnabled(): Boolean { | ||||||
|         return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); |         return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public enum LocationChangeType{ |     enum class LocationChangeType { | ||||||
|         LOCATION_SIGNIFICANTLY_CHANGED, //Went out of borders of nearby markers |         LOCATION_SIGNIFICANTLY_CHANGED, | ||||||
|         LOCATION_SLIGHTLY_CHANGED,      //User might be walking or driving |         LOCATION_SLIGHTLY_CHANGED, | ||||||
|         LOCATION_MEDIUM_CHANGED,      //Between slight and significant changes, will be used for nearby card view updates. |         LOCATION_MEDIUM_CHANGED, | ||||||
|         LOCATION_NOT_CHANGED, |         LOCATION_NOT_CHANGED, | ||||||
|         PERMISSION_JUST_GRANTED, |         PERMISSION_JUST_GRANTED, | ||||||
|         MAP_UPDATED, |         MAP_UPDATED, | ||||||
|  | @ -272,3 +244,12 @@ public class LocationServiceManager implements LocationListener { | ||||||
|         CUSTOM_QUERY |         CUSTOM_QUERY | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,12 @@ | ||||||
| package fr.free.nrw.commons.location; | package fr.free.nrw.commons.location | ||||||
| 
 | 
 | ||||||
| public interface LocationUpdateListener { | interface LocationUpdateListener { | ||||||
|     void onLocationChangedSignificantly(LatLng latLng); // Will be used to update all nearby markers on the map |     // Will be used to update all nearby markers on the map | ||||||
|     void onLocationChangedSlightly(LatLng latLng); // Will be used to track users motion |     fun onLocationChangedSignificantly(latLng: LatLng) | ||||||
|     void onLocationChangedMedium(LatLng latLng); // Will be used updating nearby card view notification | 
 | ||||||
| } |     // Will be used to track users motion | ||||||
|  |     fun onLocationChangedSlightly(latLng: LatLng) | ||||||
|  | 
 | ||||||
|  |     // Will be used updating nearby card view notification | ||||||
|  |     fun onLocationChangedMedium(latLng: LatLng) | ||||||
|  | } | ||||||
|  | @ -42,8 +42,8 @@ class LanguagesAdapter constructor( | ||||||
|         AppLanguageLookUpTable(context) |         AppLanguageLookUpTable(context) | ||||||
| 
 | 
 | ||||||
|     init { |     init { | ||||||
|         languageNamesList = language.localizedNames |         languageNamesList = language.getLocalizedNames() | ||||||
|         languageCodesList = language.codes |         languageCodesList = language.getCodes() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private val filter = LanguageFilter() |     private val filter = LanguageFilter() | ||||||
|  | @ -117,7 +117,7 @@ class LanguagesAdapter constructor( | ||||||
|      */ |      */ | ||||||
|     fun getIndexOfUserDefaultLocale(context: Context): Int { |     fun getIndexOfUserDefaultLocale(context: Context): Int { | ||||||
|         val userLanguageCode = context.locale?.language ?: return DEFAULT_INDEX |         val userLanguageCode = context.locale?.language ?: return DEFAULT_INDEX | ||||||
|         return language.codes.indexOf(userLanguageCode).takeIf { it >= 0 } ?: DEFAULT_INDEX |         return language.getCodes().indexOf(userLanguageCode).takeIf { it >= 0 } ?: DEFAULT_INDEX | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun getIndexOfLanguageCode(languageCode: String): Int = languageCodesList.indexOf(languageCode) |     fun getIndexOfLanguageCode(languageCode: String): Int = languageCodesList.indexOf(languageCode) | ||||||
|  | @ -128,17 +128,17 @@ class LanguagesAdapter constructor( | ||||||
|         override fun performFiltering(constraint: CharSequence?): FilterResults { |         override fun performFiltering(constraint: CharSequence?): FilterResults { | ||||||
|             val filterResults = FilterResults() |             val filterResults = FilterResults() | ||||||
|             val temp: LinkedHashMap<String, String> = LinkedHashMap() |             val temp: LinkedHashMap<String, String> = LinkedHashMap() | ||||||
|             if (constraint != null && language.localizedNames != null) { |             if (constraint != null) { | ||||||
|                 val length: Int = language.localizedNames.size |                 val length: Int = language.getLocalizedNames().size | ||||||
|                 var i = 0 |                 var i = 0 | ||||||
|                 while (i < length) { |                 while (i < length) { | ||||||
|                     val key: String = language.codes[i] |                     val key: String = language.getCodes()[i] | ||||||
|                     val value: String = language.localizedNames[i] |                     val value: String = language.getLocalizedNames()[i] | ||||||
|                     val defaultlanguagecode = getIndexOfUserDefaultLocale(context) |                     val defaultlanguagecode = getIndexOfUserDefaultLocale(context) | ||||||
|                     if (value.contains(constraint, true) || |                     if (value.contains(constraint, true) || | ||||||
|                         Locale(key) |                         Locale(key) | ||||||
|                             .getDisplayName( |                             .getDisplayName( | ||||||
|                                 Locale(language.codes[defaultlanguagecode]), |                                 Locale(language.getCodes()[defaultlanguagecode]), | ||||||
|                             ).contains(constraint, true) |                             ).contains(constraint, true) | ||||||
|                     ) { |                     ) { | ||||||
|                         temp[key] = value |                         temp[key] = value | ||||||
|  |  | ||||||
|  | @ -62,5 +62,5 @@ class LatLngTests { | ||||||
|     private fun assertPrettyCoordinateString( |     private fun assertPrettyCoordinateString( | ||||||
|         expected: String, |         expected: String, | ||||||
|         place: LatLng, |         place: LatLng, | ||||||
|     ) = assertEquals(expected, place.prettyCoordinateString) |     ) = assertEquals(expected, place.getPrettyCoordinateString()) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -248,11 +248,11 @@ class MediaDetailFragmentUnitTests { | ||||||
|     @Throws(Exception::class) |     @Throws(Exception::class) | ||||||
|     fun testOnUpdateCoordinatesClickedCurrentLocationNull() { |     fun testOnUpdateCoordinatesClickedCurrentLocationNull() { | ||||||
|         `when`(media.coordinates).thenReturn(null) |         `when`(media.coordinates).thenReturn(null) | ||||||
|         `when`(locationManager.lastLocation).thenReturn(null) |         `when`(locationManager.getLastLocation()).thenReturn(null) | ||||||
|         `when`(applicationKvStore.getString(lastLocation)).thenReturn("37.773972,-122.431297") |         `when`(applicationKvStore.getString(lastLocation)).thenReturn("37.773972,-122.431297") | ||||||
|         fragment.onUpdateCoordinatesClicked() |         fragment.onUpdateCoordinatesClicked() | ||||||
|         Mockito.verify(media, Mockito.times(1)).coordinates |         Mockito.verify(media, Mockito.times(1)).coordinates | ||||||
|         Mockito.verify(locationManager, Mockito.times(1)).lastLocation |         Mockito.verify(locationManager, Mockito.times(1)).getLastLocation() | ||||||
|         val shadowActivity: ShadowActivity = shadowOf(activity) |         val shadowActivity: ShadowActivity = shadowOf(activity) | ||||||
|         val startedIntent = shadowActivity.nextStartedActivity |         val startedIntent = shadowActivity.nextStartedActivity | ||||||
|         val shadowIntent: ShadowIntent = shadowOf(startedIntent) |         val shadowIntent: ShadowIntent = shadowOf(startedIntent) | ||||||
|  | @ -276,11 +276,11 @@ class MediaDetailFragmentUnitTests { | ||||||
|     @Throws(Exception::class) |     @Throws(Exception::class) | ||||||
|     fun testOnUpdateCoordinatesClickedCurrentLocationNotNull() { |     fun testOnUpdateCoordinatesClickedCurrentLocationNotNull() { | ||||||
|         `when`(media.coordinates).thenReturn(null) |         `when`(media.coordinates).thenReturn(null) | ||||||
|         `when`(locationManager.lastLocation).thenReturn(LatLng(-0.000001, -0.999999, 0f)) |         `when`(locationManager.getLastLocation()).thenReturn(LatLng(-0.000001, -0.999999, 0f)) | ||||||
|         `when`(applicationKvStore.getString(lastLocation)).thenReturn("37.773972,-122.431297") |         `when`(applicationKvStore.getString(lastLocation)).thenReturn("37.773972,-122.431297") | ||||||
| 
 | 
 | ||||||
|         fragment.onUpdateCoordinatesClicked() |         fragment.onUpdateCoordinatesClicked() | ||||||
|         Mockito.verify(locationManager, Mockito.times(3)).lastLocation |         Mockito.verify(locationManager, Mockito.times(3)).getLastLocation() | ||||||
|         val shadowActivity: ShadowActivity = shadowOf(activity) |         val shadowActivity: ShadowActivity = shadowOf(activity) | ||||||
|         val startedIntent = shadowActivity.nextStartedActivity |         val startedIntent = shadowActivity.nextStartedActivity | ||||||
|         val shadowIntent: ShadowIntent = shadowOf(startedIntent) |         val shadowIntent: ShadowIntent = shadowOf(startedIntent) | ||||||
|  |  | ||||||
|  | @ -54,8 +54,8 @@ class LanguagesAdapterTest { | ||||||
|                 .from(context) |                 .from(context) | ||||||
|                 .inflate(R.layout.row_item_languages_spinner, null) as View |                 .inflate(R.layout.row_item_languages_spinner, null) as View | ||||||
| 
 | 
 | ||||||
|         languageNamesList = language.localizedNames |         languageNamesList = language.getLocalizedNames() | ||||||
|         languageCodesList = language.codes |         languageCodesList = language.getCodes() | ||||||
| 
 | 
 | ||||||
|         languagesAdapter = LanguagesAdapter(context, selectedLanguages) |         languagesAdapter = LanguagesAdapter(context, selectedLanguages) | ||||||
|     } |     } | ||||||
|  | @ -124,12 +124,12 @@ class LanguagesAdapterTest { | ||||||
|         var i = 0 |         var i = 0 | ||||||
|         var s = 0 |         var s = 0 | ||||||
|         while (i < length) { |         while (i < length) { | ||||||
|             val key: String = language.codes[i] |             val key: String = language.getCodes()[i] | ||||||
|             val value: String = language.localizedNames[i] |             val value: String = language.getLocalizedNames()[i] | ||||||
|             if (value.contains(constraint, true) || |             if (value.contains(constraint, true) || | ||||||
|                 Locale(key) |                 Locale(key) | ||||||
|                     .getDisplayName( |                     .getDisplayName( | ||||||
|                         Locale(language.codes[defaultlanguagecode!!]), |                         Locale(language.getCodes()[defaultlanguagecode!!]), | ||||||
|                     ).contains(constraint, true) |                     ).contains(constraint, true) | ||||||
|             ) { |             ) { | ||||||
|                 s++ |                 s++ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Saifuddin
						Saifuddin