Fixes geolocation issue + remove image cropping dependency

bs
Laurent 5 years ago
parent ff24fca659
commit f01386347a
  1. 2
      app/build.gradle
  2. 29
      app/src/main/java/net/pokeranalytics/android/ui/activity/components/BaseActivity.kt
  3. 46
      app/src/main/java/net/pokeranalytics/android/ui/modules/data/LocationDataFragment.kt
  4. 19
      app/src/main/java/net/pokeranalytics/android/ui/view/PlayerImageView.kt
  5. 130
      app/src/main/java/net/pokeranalytics/android/util/LocationManager.kt

@ -104,7 +104,7 @@ dependencies {
implementation 'com.google.android.play:core-ktx:1.8.1' // In-app Reviews implementation 'com.google.android.play:core-ktx:1.8.1' // In-app Reviews
// Places // Places
implementation 'com.google.android.libraries.places:places:1.1.0' implementation 'com.google.android.libraries.places:places:2.3.0'
// Billing / Subscriptions // Billing / Subscriptions
// WARNING FOR 2.0: https://developer.android.com/google/play/billing/billing_library_releases_notes // WARNING FOR 2.0: https://developer.android.com/google/play/billing/billing_library_releases_notes

@ -11,7 +11,6 @@ import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
import com.google.android.libraries.places.api.model.PlaceLikelihood
import io.realm.Realm import io.realm.Realm
import net.pokeranalytics.android.model.realm.Location import net.pokeranalytics.android.model.realm.Location
import net.pokeranalytics.android.util.LocationManager import net.pokeranalytics.android.util.LocationManager
@ -139,20 +138,20 @@ abstract class BaseActivity : AppCompatActivity() {
/** /**
* Ask for places request * Ask for places request
*/ */
fun askForPlacesRequest(callback: ((success: Boolean, places: ArrayList<PlaceLikelihood>) -> Unit)?) { // fun askForPlacesRequest(callback: ((success: Boolean, places: ArrayList<PlaceLikelihood>) -> Unit)?) {
// Call findCurrentPlace and handle the response (first check that the user has granted permission). // // Call findCurrentPlace and handle the response (first check that the user has granted permission).
if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { // if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationManager(this).askForPlacesRequest(callback) // LocationManager(this).askForPlacesRequest(callback)
} else { // } else {
askForLocationPermission { granted -> // askForLocationPermission { granted ->
if (granted) { // if (granted) {
LocationManager(this).askForPlacesRequest(callback) // LocationManager(this).askForPlacesRequest(callback)
} else { // } else {
callback?.invoke(false, ArrayList()) // callback?.invoke(false, ArrayList())
} // }
} // }
} // }
} // }
/** /**
* Find the nearest location from the user * Find the nearest location from the user

@ -14,7 +14,9 @@ import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.LocationRow import net.pokeranalytics.android.ui.view.rowrepresentable.LocationRow
import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow
import net.pokeranalytics.android.util.LocationManager
import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.NULL_TEXT
import timber.log.Timber
/** /**
* Custom EditableDataFragment to manage the LOCATE_ME case * Custom EditableDataFragment to manage the LOCATE_ME case
@ -50,7 +52,7 @@ class LocationDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
// If we create a new location, we try to locate the user by default // If we create a new location, we try to locate the user by default
isLookingForPlaces = true isLookingForPlaces = true
getSuggestionsPlaces() getLocation()
} }
@ -109,7 +111,7 @@ class LocationDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
isLookingForPlaces = value isLookingForPlaces = value
if (value) { if (value) {
updateAdapterUI() updateAdapterUI()
getSuggestionsPlaces() getLocation()
} else { } else {
clearCurrentLocation() clearCurrentLocation()
updateAdapterUI() updateAdapterUI()
@ -169,43 +171,25 @@ class LocationDataFragment : EditableDataFragment(), StaticRowRepresentableDataS
/** /**
* Return the places around the user * Return the places around the user
*/ */
private fun getSuggestionsPlaces() { private fun getLocation() {
val maxResults = 5 LocationManager(requireContext()).getSingleLocation { loc ->
parentActivity?.askForPlacesRequest { success, places -> Timber.d("Location received = $loc")
if (success) { loc?.let {
// Try to get the location of the user location.latitude = it.latitude
parentActivity?.findCurrentLocation {currentLocation -> location.longitude = it.longitude
currentLocation?.let { locationActivated = true
location.latitude = currentLocation.latitude } ?: run {
location.longitude = currentLocation.longitude locationActivated = false
}
}
}
if (success && places.size > 0) {
rowPlaces.clear()
placesForRows.clear()
for ((index, place) in places.withIndex()) {
if (index < maxResults) {
val row = CustomizableRowRepresentable(customViewType = RowViewType.LOCATION_TITLE, title = place.place.name, isSelectable = true)
rowPlaces.add(row)
placesForRows[row] = place
}
} }
locationActivated = true
isLookingForPlaces = false
updateAdapterUI()
} else {
isLookingForPlaces = false isLookingForPlaces = false
locationActivated = false
updateAdapterUI() updateAdapterUI()
} }
}
} }
} }

@ -10,9 +10,7 @@ import android.widget.FrameLayout
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat.getColor import androidx.core.content.ContextCompat.getColor
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import com.bumptech.glide.Glide import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade
import com.bumptech.glide.request.RequestOptions
import kotlinx.android.synthetic.main.view_player_image.view.* import kotlinx.android.synthetic.main.view_player_image.view.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Player import net.pokeranalytics.android.model.realm.Player
@ -78,21 +76,18 @@ class PlayerImageView : FrameLayout {
fun setPlayer(player: Player, size: Size = Size.NORMAL, isHero: Boolean = false) { fun setPlayer(player: Player, size: Size = Size.NORMAL, isHero: Boolean = false) {
// Picture // Picture
if (player.hasPicture()) { player.picture?.let { picture ->
val rDrawable = RoundedBitmapDrawableFactory.create(resources, picture)
rDrawable.isCircular = true
playerImageView.player_image.setImageDrawable(rDrawable)
playerImageView.playerInitial.text = "" } ?: run {
Glide.with(this)
.load(player.picture)
.apply(RequestOptions().circleCrop())
.transition(withCrossFade())
.into(playerImageView.player_image)
} else {
playerImageView.playerStroke.background = ResourcesCompat.getDrawable(resources, R.drawable.circle_stroke_kaki, null) playerImageView.playerStroke.background = ResourcesCompat.getDrawable(resources, R.drawable.circle_stroke_kaki, null)
playerImageView.player_image.setImageDrawable(null) playerImageView.player_image.setImageDrawable(null)
playerImageView.playerInitial.text = player.initials playerImageView.playerInitial.text = player.initials
playerImageView.playerInitial.setTextSize(TypedValue.COMPLEX_UNIT_SP, size.getFontSize()) playerImageView.playerInitial.setTextSize(TypedValue.COMPLEX_UNIT_SP, size.getFontSize())
} }
// Player color // Player color

@ -3,20 +3,12 @@ package net.pokeranalytics.android.util
import android.Manifest.permission.ACCESS_FINE_LOCATION import android.Manifest.permission.ACCESS_FINE_LOCATION
import android.content.Context import android.content.Context
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Looper
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.google.android.gms.common.api.ApiException import com.google.android.gms.location.*
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.android.libraries.places.api.Places
import com.google.android.libraries.places.api.model.Place
import com.google.android.libraries.places.api.model.PlaceLikelihood
import com.google.android.libraries.places.api.net.FindCurrentPlaceRequest
import io.realm.Realm import io.realm.Realm
import io.realm.kotlin.where import io.realm.kotlin.where
import net.pokeranalytics.android.model.realm.Location import net.pokeranalytics.android.model.realm.Location
import timber.log.Timber
import java.util.*
import kotlin.collections.ArrayList
class LocationManager(private var context: Context) { class LocationManager(private var context: Context) {
@ -27,46 +19,46 @@ class LocationManager(private var context: Context) {
/** /**
* Return the [places] around the user * Return the [places] around the user
*/ */
fun askForPlacesRequest(callback: ((success: Boolean, places: ArrayList<PlaceLikelihood>) -> Unit)?) { // fun askForPlacesRequest(callback: ((success: Boolean, places: ArrayList<PlaceLikelihood>) -> Unit)?) {
//
// Initialize Places. // // Initialize Places.
Places.initialize(context, context.getString(net.pokeranalytics.android.R.string.google_places_api)) // Places.initialize(context, context.getString(net.pokeranalytics.android.R.string.google_places_api))
//
// Create a new Places client instance. // // Create a new Places client instance.
val placesClient = Places.createClient(context) // val placesClient = Places.createClient(context)
//
// Use fields to define the data types to return. // // Use fields to define the data types to return.
val placeFields = Arrays.asList(Place.Field.NAME, Place.Field.ADDRESS, Place.Field.LAT_LNG) // val placeFields = Arrays.asList(Place.Field.NAME, Place.Field.ADDRESS, Place.Field.LAT_LNG)
//
// Use the builder to create a FindCurrentPlaceRequest. // // Use the builder to create a FindCurrentPlaceRequest.
val request = FindCurrentPlaceRequest.builder(placeFields).build() // val request = FindCurrentPlaceRequest.builder(placeFields).build()
//
// Call findCurrentPlace and handle the response (first check that the user has granted permission). // // Call findCurrentPlace and handle the response (first check that the user has granted permission).
if (ContextCompat.checkSelfPermission(context, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { // if (ContextCompat.checkSelfPermission(context, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
val placeResponse = placesClient.findCurrentPlace(request) // val placeResponse = placesClient.findCurrentPlace(request)
//
//
placeResponse.addOnCompleteListener { task -> // placeResponse.addOnCompleteListener { task ->
val places = ArrayList<PlaceLikelihood>() // val places = ArrayList<PlaceLikelihood>()
if (task.isSuccessful) { // if (task.isSuccessful) {
val response = task.result // val response = task.result
response?.placeLikelihoods?.let { // response?.placeLikelihoods?.let {
places.addAll(it) // places.addAll(it)
} // }
} else { // } else {
val exception = task.exception // val exception = task.exception
if (exception is ApiException) { // if (exception is ApiException) {
Timber.d("Error: ${"Place not found: " + exception.statusCode}") // Timber.d("Error: ${"Place not found: " + exception.statusCode}")
} // }
} // }
//
callback?.invoke(task.isSuccessful, places) // callback?.invoke(task.isSuccessful, places)
} // }
} else { // } else {
// If we don't have the permission, return // // If we don't have the permission, return
callback?.invoke(false, ArrayList()) // callback?.invoke(false, ArrayList())
} // }
} // }
/** /**
* Return if the database contains one or many locations with coordinates * Return if the database contains one or many locations with coordinates
@ -171,4 +163,42 @@ class LocationManager(private var context: Context) {
} }
} }
private val fusedLocationClient: FusedLocationProviderClient =
LocationServices.getFusedLocationProviderClient(context)
/***
* Finds and returns the current user location
* Gets one update then stops
*/
fun getSingleLocation(callback: ((location: android.location.Location?) -> Unit)) {
var locationResultReceived = false
val locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
super.onLocationResult(locationResult)
locationResult?.locations?.let {
if (!locationResultReceived && it.isNotEmpty()) {
locationResultReceived = true
callback(it.first())
fusedLocationClient.removeLocationUpdates(this)
}
}
}
}
if (ContextCompat.checkSelfPermission(context, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
val locationRequest = LocationRequest()
locationRequest.interval = 200L
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper())
} else {
// If we don't have the permission, return null
callback.invoke(null)
}
}
} }
Loading…
Cancel
Save