@@ -21,8 +21,14 @@ import android.content.*
2121import android.location.Geocoder
2222import android.net.Uri
2323import androidx.core.content.getSystemService
24+ import com.google.android.gms.common.api.ApiException
2425import com.google.android.gms.location.FusedLocationProviderClient
2526import com.google.android.gms.location.LocationServices
27+ import com.google.android.gms.maps.model.LatLng
28+ import com.google.android.libraries.places.api.Places
29+ import com.google.android.libraries.places.api.model.RectangularBounds
30+ import com.google.android.libraries.places.api.net.PlacesClient
31+ import com.google.android.libraries.places.ktx.api.net.awaitFindAutocompletePredictions
2632import com.mapcode.Mapcode
2733import com.mapcode.MapcodeCodec
2834import com.mapcode.UnknownMapcodeException
@@ -31,10 +37,7 @@ import com.mapcode.util.Location
3137import com.mapcode.util.NoAddressException
3238import com.mapcode.util.UnknownAddressException
3339import dagger.hilt.android.qualifiers.ApplicationContext
34- import kotlinx.coroutines.CoroutineScope
35- import kotlinx.coroutines.Dispatchers
36- import kotlinx.coroutines.launch
37- import kotlinx.coroutines.withContext
40+ import kotlinx.coroutines.*
3841import okhttp3.HttpUrl
3942import okhttp3.OkHttpClient
4043import okhttp3.Request
@@ -62,6 +65,8 @@ class ShowMapcodeUseCaseImpl @Inject constructor(
6265 */
6366 private var cachedLastLocation: Location ? = null
6467
68+ private val placesClient: PlacesClient by lazy { Places .createClient(ctx) }
69+
6570 override fun getMapcodes (lat : Double , long : Double ): List <Mapcode > {
6671 coroutineScope.launch(Dispatchers .IO ) {
6772 try {
@@ -103,7 +108,7 @@ class ShowMapcodeUseCaseImpl @Inject constructor(
103108 }
104109
105110 val matchingAddress = withContext(Dispatchers .Default ) {
106- geocoder.getFromLocationName(address, 10 ).firstOrNull()
111+ geocoder.getFromLocationName(address, 10 )? .firstOrNull()
107112 }
108113
109114 if (matchingAddress == null ) {
@@ -119,7 +124,7 @@ class ShowMapcodeUseCaseImpl @Inject constructor(
119124 override suspend fun reverseGeocode (lat : Double , long : Double ): Result <String > {
120125 try {
121126 val addressList = withContext(Dispatchers .Default ) {
122- geocoder.getFromLocation(lat, long, 1 )
127+ geocoder.getFromLocation(lat, long, 1 ) ? : emptyList()
123128 }
124129
125130 if (addressList.isEmpty()) {
@@ -193,23 +198,36 @@ class ShowMapcodeUseCaseImpl @Inject constructor(
193198 ctx.startActivity(shareIntent)
194199 }
195200
196- override suspend fun getMatchingAddresses (query : String ): Result <List <String >> {
197- try {
198- val addressList = withContext(Dispatchers .Default ) {
199- geocoder.getFromLocationName(query, 3 )
200- }
201-
202- val addressStringList = addressList.map { address ->
203- buildString {
204- for (i in 0 .. address.maxAddressLineIndex) {
205- append(address.getAddressLine(i))
206- }
201+ @OptIn(ExperimentalCoroutinesApi ::class )
202+ override suspend fun getMatchingAddresses (
203+ query : String ,
204+ maxResults : Int ,
205+ southwest : Location ,
206+ northeast : Location
207+ ): Result <List <String >> {
208+ val locationBias = RectangularBounds .newInstance(
209+ LatLng (southwest.latitude, southwest.longitude),
210+ LatLng (northeast.latitude, northeast.longitude)
211+ )
212+
213+ val responseResult = withContext(Dispatchers .Default ) {
214+ try {
215+ val response = placesClient.awaitFindAutocompletePredictions {
216+ this .query = query
217+ this .locationBias = locationBias
207218 }
219+
220+ success(response)
221+ } catch (e: ApiException ) {
222+ Timber .e(e.status.toString())
223+ failure(e)
208224 }
225+ }
209226
210- return success(addressStringList)
211- } catch (e: IOException ) {
212- return failure(e)
227+ return responseResult.map { response ->
228+ response.autocompletePredictions
229+ .map { it.getFullText(null ) }
230+ .map { it.toString() }
213231 }
214232 }
215233}
@@ -267,7 +285,12 @@ interface ShowMapcodeUseCase {
267285 fun shareText (text : String , description : String )
268286
269287 /* *
270- * Get a list of addresses that might correspond to the [query].
288+ * Get a list of addresses within the [northeast] and [southwest] bounds that might correspond to the [query].
271289 */
272- suspend fun getMatchingAddresses (query : String ): Result <List <String >>
290+ suspend fun getMatchingAddresses (
291+ query : String ,
292+ maxResults : Int ,
293+ southwest : Location ,
294+ northeast : Location
295+ ): Result <List <String >>
273296}
0 commit comments