Added map, JSON requests and clusters
This commit is contained in:
parent
41d331da02
commit
f0136fb2d3
@ -31,4 +31,6 @@ dependencies {
|
|||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
implementation 'com.google.android.gms:play-services-maps:10.2.1'
|
implementation 'com.google.android.gms:play-services-maps:10.2.1'
|
||||||
implementation 'com.google.android.gms:play-services-location:10.2.1'
|
implementation 'com.google.android.gms:play-services-location:10.2.1'
|
||||||
|
compile 'com.google.maps.android:android-maps-utils:0.4+'
|
||||||
|
compile 'com.koushikdutta.ion:ion:2.+'
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
android:value="@string/google_maps_key" />
|
android:value="@string/google_maps_key" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MapsActivity"
|
android:name=".YelpMapActivity"
|
||||||
android:label="@string/title_activity_maps">
|
android:label="@string/title_activity_maps">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
50
app/src/main/java/fishrungames/yelpmapapp/DataProvider.kt
Executable file
50
app/src/main/java/fishrungames/yelpmapapp/DataProvider.kt
Executable file
@ -0,0 +1,50 @@
|
|||||||
|
package fishrungames.yelpmapapp
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.google.gson.JsonArray
|
||||||
|
import com.koushikdutta.ion.Ion
|
||||||
|
import java.io.BufferedInputStream
|
||||||
|
import java.net.HttpURLConnection
|
||||||
|
import java.net.URL
|
||||||
|
import java.security.AccessController.getContext
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import com.koushikdutta.async.future.FutureCallback
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import org.json.JSONObject
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mephi on 09.06.2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DataProvider(val context: Context, val onUpdateMapMarkers : ((Map<String, MapMarkerRecord>) -> Unit)) {
|
||||||
|
|
||||||
|
val yelpApiKey = "TFhv6H25FV25ETpIC64TmN1sZ98yLIK3-4IZ7-CFSaRIyO6Xo97n1uI5207vo3JA-gLgu1f_7dw4LLWrpAcVAELSVFwHxYDL2FEfwaheJ9WvjbgEbjd3ADWAkt46WXYx"
|
||||||
|
|
||||||
|
fun requestData(lat : Double, lon : Double, radius : Int)
|
||||||
|
{
|
||||||
|
|
||||||
|
Ion.with(context)
|
||||||
|
.load("https://api.yelp.com/v3/businesses/search?latitude=${lat}&longitude=${lon}&radius=${radius}")
|
||||||
|
.addHeader("Authorization", "Bearer " + yelpApiKey)
|
||||||
|
.asJsonObject()
|
||||||
|
.setCallback { e, result ->
|
||||||
|
|
||||||
|
if (e != null)
|
||||||
|
{
|
||||||
|
return@setCallback
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
return@setCallback
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleResponseAsyncTask(onUpdateMapMarkers).execute(result)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
52
app/src/main/java/fishrungames/yelpmapapp/HandleResponseAsyncTask.kt
Executable file
52
app/src/main/java/fishrungames/yelpmapapp/HandleResponseAsyncTask.kt
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
package fishrungames.yelpmapapp
|
||||||
|
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mephi on 10.06.2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
class HandleResponseAsyncTask(val onUpdateMapMarkers : ((Map<String, MapMarkerRecord>) -> Unit)) : AsyncTask<JsonObject, Int, Map<String, MapMarkerRecord>>()
|
||||||
|
{
|
||||||
|
|
||||||
|
override fun doInBackground(vararg response : JsonObject): Map<String, MapMarkerRecord> {
|
||||||
|
|
||||||
|
val newMapMarkers = mutableMapOf<String, MapMarkerRecord>()
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
for (businessElement in response[0].getAsJsonArray("businesses")) {
|
||||||
|
val businessJson = businessElement.asJsonObject
|
||||||
|
|
||||||
|
val id = businessJson.get("id").asString
|
||||||
|
val name = businessJson.get("name").asString
|
||||||
|
val image_url = businessJson.get("image_url").asString
|
||||||
|
val latitude = businessJson.get("coordinates").asJsonObject.get("latitude").asDouble
|
||||||
|
val longitude = businessJson.get("coordinates").asJsonObject.get("longitude").asDouble
|
||||||
|
|
||||||
|
var mapMarker = MapMarkerRecord(id, name, image_url, latitude, longitude)
|
||||||
|
|
||||||
|
newMapMarkers[name] = mapMarker
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (e : Exception)
|
||||||
|
{
|
||||||
|
e.printStackTrace()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return newMapMarkers
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPostExecute(result: Map<String, MapMarkerRecord>) {
|
||||||
|
super.onPostExecute(result)
|
||||||
|
|
||||||
|
onUpdateMapMarkers(result)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
21
app/src/main/java/fishrungames/yelpmapapp/MapMarkerClusterItem.kt
Executable file
21
app/src/main/java/fishrungames/yelpmapapp/MapMarkerClusterItem.kt
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
package fishrungames.yelpmapapp
|
||||||
|
|
||||||
|
import com.google.maps.android.clustering.ClusterItem
|
||||||
|
import com.google.android.gms.maps.model.LatLng
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mephi on 10.06.2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MapMarkerClusterItem(inMapMarkerRecord : MapMarkerRecord) : ClusterItem
|
||||||
|
{
|
||||||
|
private val mPosition = LatLng(inMapMarkerRecord.lat, inMapMarkerRecord.lon)
|
||||||
|
|
||||||
|
val mapMarkerRecord = inMapMarkerRecord
|
||||||
|
|
||||||
|
override fun getPosition(): LatLng {
|
||||||
|
return mPosition
|
||||||
|
}
|
||||||
|
}
|
14
app/src/main/java/fishrungames/yelpmapapp/MapMarkerRecord.kt
Executable file
14
app/src/main/java/fishrungames/yelpmapapp/MapMarkerRecord.kt
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
package fishrungames.yelpmapapp
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mephi on 09.06.2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
data class MapMarkerRecord (
|
||||||
|
val id: String,
|
||||||
|
val name: String,
|
||||||
|
val imageUrl: String,
|
||||||
|
val lat: Double,
|
||||||
|
val lon: Double
|
||||||
|
)
|
@ -27,11 +27,11 @@ import android.content.DialogInterface
|
|||||||
import android.support.v7.app.AlertDialog
|
import android.support.v7.app.AlertDialog
|
||||||
|
|
||||||
|
|
||||||
class MapsActivity : FragmentActivity(), OnMapReadyCallback, LocationListener,
|
open class MapsActivity : FragmentActivity(), OnMapReadyCallback, LocationListener,
|
||||||
GoogleApiClient.ConnectionCallbacks,
|
GoogleApiClient.ConnectionCallbacks,
|
||||||
GoogleApiClient.OnConnectionFailedListener {
|
GoogleApiClient.OnConnectionFailedListener {
|
||||||
|
|
||||||
private var mMap: GoogleMap? = null
|
internal var mMap: GoogleMap? = null
|
||||||
|
|
||||||
private var mLastLocation: Location? = null
|
private var mLastLocation: Location? = null
|
||||||
|
|
||||||
@ -61,22 +61,20 @@ class MapsActivity : FragmentActivity(), OnMapReadyCallback, LocationListener,
|
|||||||
override fun onMapReady(googleMap: GoogleMap) {
|
override fun onMapReady(googleMap: GoogleMap) {
|
||||||
|
|
||||||
// Add a marker in Sydney and move the camera
|
// Add a marker in Sydney and move the camera
|
||||||
val sydney = LatLng(-34.0, 151.0)
|
//val sydney = LatLng(-34.0, 151.0)
|
||||||
googleMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
|
//googleMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
|
||||||
googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
|
//googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (ContextCompat.checkSelfPermission(this,
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION)
|
//Location Permission already granted
|
||||||
== PackageManager.PERMISSION_GRANTED) {
|
buildGoogleApiClient()
|
||||||
//Location Permission already granted
|
googleMap.isMyLocationEnabled = true
|
||||||
buildGoogleApiClient()
|
} else {
|
||||||
googleMap.setMyLocationEnabled(true)
|
//Request Location Permission
|
||||||
} else {
|
checkLocationPermission()
|
||||||
//Request Location Permission
|
}
|
||||||
checkLocationPermission()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mMap = googleMap
|
mMap = googleMap
|
||||||
@ -85,11 +83,13 @@ class MapsActivity : FragmentActivity(), OnMapReadyCallback, LocationListener,
|
|||||||
|
|
||||||
override fun onConnected(bundle: Bundle?) {
|
override fun onConnected(bundle: Bundle?) {
|
||||||
val locationRequest = LocationRequest()
|
val locationRequest = LocationRequest()
|
||||||
locationRequest.setInterval(1000)
|
|
||||||
locationRequest.setFastestInterval(1000)
|
locationRequest.interval = 1000
|
||||||
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
|
locationRequest.fastestInterval = 1000
|
||||||
if (ContextCompat.checkSelfPermission(this,
|
locationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
|
|
||||||
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
|
||||||
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, this)
|
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,18 +101,14 @@ class MapsActivity : FragmentActivity(), OnMapReadyCallback, LocationListener,
|
|||||||
override fun onConnectionFailed(connectionResult: ConnectionResult) {}
|
override fun onConnectionFailed(connectionResult: ConnectionResult) {}
|
||||||
|
|
||||||
override fun onLocationChanged(location: Location) {
|
override fun onLocationChanged(location: Location) {
|
||||||
mLastLocation = location
|
|
||||||
|
|
||||||
//Place current location marker
|
if (mLastLocation == null) {
|
||||||
val latLng = LatLng(location.latitude, location.longitude)
|
val latLng = LatLng(location.latitude, location.longitude)
|
||||||
/*
|
|
||||||
val markerOptions = MarkerOptions()
|
|
||||||
markerOptions.position(latLng)
|
|
||||||
markerOptions.title("Current Position")
|
|
||||||
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA))
|
|
||||||
mCurrLocationMarker = mGoogleMap.addMarker(markerOptions)*/
|
|
||||||
|
|
||||||
mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 11f))
|
mLastLocation = location
|
||||||
|
|
||||||
|
mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 11f))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +183,3 @@ class MapsActivity : FragmentActivity(), OnMapReadyCallback, LocationListener,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LocationRequest {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
32
app/src/main/java/fishrungames/yelpmapapp/YelpInfoWindowProvider.kt
Executable file
32
app/src/main/java/fishrungames/yelpmapapp/YelpInfoWindowProvider.kt
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
package fishrungames.yelpmapapp
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.View
|
||||||
|
import com.google.android.gms.maps.model.Marker
|
||||||
|
import android.widget.TextView
|
||||||
|
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mephi on 10.06.2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
internal class MyInfoWindowAdapter(val activity: Activity) : InfoWindowAdapter {
|
||||||
|
|
||||||
|
private val myContentsView: View = activity.layoutInflater.inflate(R.layout.yelp_info_contents, null)
|
||||||
|
|
||||||
|
override fun getInfoContents(marker: Marker): View {
|
||||||
|
|
||||||
|
//myContentsView.findViewById(R.id.title) = marker.title
|
||||||
|
//myContentsView.findViewById(R.id.snippet).text = marker.snippet
|
||||||
|
|
||||||
|
return myContentsView
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInfoWindow(marker: Marker): View? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
141
app/src/main/java/fishrungames/yelpmapapp/YelpMapActivity.kt
Executable file
141
app/src/main/java/fishrungames/yelpmapapp/YelpMapActivity.kt
Executable file
@ -0,0 +1,141 @@
|
|||||||
|
package fishrungames.yelpmapapp
|
||||||
|
|
||||||
|
import android.location.Location
|
||||||
|
import android.os.Handler
|
||||||
|
import com.google.android.gms.maps.GoogleMap
|
||||||
|
import com.google.android.gms.maps.model.Marker
|
||||||
|
import com.google.android.gms.maps.model.BitmapDescriptorFactory
|
||||||
|
import com.google.android.gms.maps.model.MarkerOptions
|
||||||
|
import com.google.android.gms.maps.model.LatLng
|
||||||
|
import java.util.*
|
||||||
|
import com.google.maps.android.clustering.ClusterManager
|
||||||
|
import com.google.android.gms.maps.CameraUpdateFactory
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mephi on 09.06.2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
class YelpMapActivity : MapsActivity()
|
||||||
|
{
|
||||||
|
|
||||||
|
val handler = Handler()
|
||||||
|
|
||||||
|
val dataProvider = DataProvider(this, this::handleMarkersUpdated)
|
||||||
|
|
||||||
|
private var mClusterManager: ClusterManager<MapMarkerClusterItem>? = null
|
||||||
|
|
||||||
|
val markerMap = mutableMapOf<String, MapMarkerClusterItem>()
|
||||||
|
|
||||||
|
var latestRequestDate : Date? = null
|
||||||
|
|
||||||
|
var requestScheduled : Boolean = false
|
||||||
|
|
||||||
|
override fun onMapReady(googleMap: GoogleMap) {
|
||||||
|
super.onMapReady(googleMap)
|
||||||
|
|
||||||
|
googleMap.setOnCameraMoveListener {
|
||||||
|
|
||||||
|
tryRequestData(googleMap.cameraPosition.target.latitude, googleMap.cameraPosition.target.longitude)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setUpClusterer(googleMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onLocationChanged(location: Location) {
|
||||||
|
super.onLocationChanged(location)
|
||||||
|
tryRequestData(location.latitude, location.longitude)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleMarkersUpdated(newMarkerMap: Map<String, MapMarkerRecord>)
|
||||||
|
{
|
||||||
|
if (mClusterManager == null)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val clusterManager = mClusterManager!!
|
||||||
|
|
||||||
|
for (key in newMarkerMap.keys)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (!markerMap.containsKey(key))
|
||||||
|
{
|
||||||
|
val mapMarkerRecord = newMarkerMap[key] as MapMarkerRecord
|
||||||
|
|
||||||
|
val mapMarkerClusterItem = MapMarkerClusterItem(mapMarkerRecord)
|
||||||
|
|
||||||
|
clusterManager.addItem(mapMarkerClusterItem)
|
||||||
|
|
||||||
|
markerMap[key] = mapMarkerClusterItem
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun tryRequestData(lat : Double, lon : Double) {
|
||||||
|
|
||||||
|
val requestLimitInMs = 2000L
|
||||||
|
|
||||||
|
val newDate = Date()
|
||||||
|
|
||||||
|
if (latestRequestDate == null)
|
||||||
|
{
|
||||||
|
innerRequestData(lat, lon)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!requestScheduled) {
|
||||||
|
|
||||||
|
requestScheduled = true
|
||||||
|
|
||||||
|
val timeDiffMs = newDate.time - latestRequestDate!!.time
|
||||||
|
|
||||||
|
if (timeDiffMs > requestLimitInMs) {
|
||||||
|
innerRequestData(lat, lon)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
handler.postDelayed({ innerRequestData(lat, lon) }, requestLimitInMs - timeDiffMs)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun innerRequestData(lat : Double, lon : Double)
|
||||||
|
{
|
||||||
|
val radius = 2000
|
||||||
|
|
||||||
|
latestRequestDate = Date()
|
||||||
|
|
||||||
|
dataProvider.requestData(lat, lon, radius)
|
||||||
|
|
||||||
|
requestScheduled = false
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun setUpClusterer(googleMap: GoogleMap) {
|
||||||
|
|
||||||
|
// Initialize the manager with the context and the map.
|
||||||
|
// (Activity extends context, so we can pass 'this' in the constructor.)
|
||||||
|
mClusterManager = ClusterManager<MapMarkerClusterItem>(this, googleMap)
|
||||||
|
|
||||||
|
// Point the map's listeners at the listeners implemented by the cluster
|
||||||
|
// manager.
|
||||||
|
googleMap.setOnCameraIdleListener(mClusterManager)
|
||||||
|
googleMap.setOnMarkerClickListener(mClusterManager)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -5,4 +5,4 @@
|
|||||||
android:name="com.google.android.gms.maps.SupportMapFragment"
|
android:name="com.google.android.gms.maps.SupportMapFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="fishrungames.yelpmapapp.MapsActivity" />
|
tools:context="fishrungames.yelpmapapp.YelpMapActivity" />
|
||||||
|
6
app/src/main/res/layout/yelp_info_contents.xml
Executable file
6
app/src/main/res/layout/yelp_info_contents.xml
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical" android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -1,4 +1,4 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">YelpMapApp</string>
|
<string name="app_name">YelpMapApp</string>
|
||||||
<string name="title_activity_maps">Map</string>
|
<string name="title_activity_maps">Yelp Map App</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user