From 66bd9ea3422fdd6d272ea0e12bf10e44dab44c7e Mon Sep 17 00:00:00 2001 From: andperks6 Date: Tue, 3 Mar 2020 13:36:57 -0700 Subject: [PATCH] searchRoom, passing data, navigation view --- app/build.gradle | 14 +- app/src/main/AndroidManifest.xml | 10 +- .../java/com/example/yfind/MainActivity.kt | 202 +++++++++++++----- .../java/com/example/yfind/SearchBuilding.kt | 32 ++- .../main/java/com/example/yfind/SearchRoom.kt | 139 ++++++++++++ .../java/com/example/yfind/locationUtil.kt | 109 ++++++++++ app/src/main/res/drawable/ic_destination.png | Bin 0 -> 1421 bytes app/src/main/res/drawable/ic_source.png | Bin 0 -> 1832 bytes app/src/main/res/layout/activity_main.xml | 12 +- app/src/main/res/layout/search_room.xml | 15 ++ 10 files changed, 449 insertions(+), 84 deletions(-) create mode 100644 app/src/main/java/com/example/yfind/SearchRoom.kt create mode 100644 app/src/main/java/com/example/yfind/locationUtil.kt create mode 100644 app/src/main/res/drawable/ic_destination.png create mode 100644 app/src/main/res/drawable/ic_source.png create mode 100644 app/src/main/res/layout/search_room.xml diff --git a/app/build.gradle b/app/build.gradle index 5c9ed83..ff0032b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,14 +6,15 @@ apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 29 - buildToolsVersion "29.0.2" + buildToolsVersion "29.0.3" defaultConfig { applicationId "com.example.yfind" - minSdkVersion 19 + minSdkVersion 21 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" +// multiDexEnabled true } buildTypes { release { @@ -26,17 +27,22 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8.toString() + } } dependencies { implementation 'com.esri.arcgisruntime:arcgis-android:100.7.0' implementation fileTree(dir: 'libs', include: ['*.jar']) implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.appcompat:appcompat:1.0.2' - implementation 'androidx.core:core-ktx:1.0.2' + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.core:core-ktx:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' implementation 'androidx.recyclerview:recyclerview:1.1.0' + implementation 'com.google.android.gms:play-services-location:17.0.0' +// implementation 'androidx.multidex:multidex:2.0.1' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 327a6b7..2950f48 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,7 +3,8 @@ package="com.example.yfind"> - + + @@ -37,6 +38,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/yfind/MainActivity.kt b/app/src/main/java/com/example/yfind/MainActivity.kt index 72dddef..55ffa1e 100644 --- a/app/src/main/java/com/example/yfind/MainActivity.kt +++ b/app/src/main/java/com/example/yfind/MainActivity.kt @@ -1,26 +1,41 @@ package com.example.yfind -import android.app.SearchManager -import android.app.Service -import android.content.Intent -import androidx.appcompat.app.AppCompatActivity + +import android.graphics.Color +import android.graphics.drawable.BitmapDrawable +import android.location.Location import android.os.Bundle -import android.util.Log -import android.widget.Toast -import com.esri.arcgisruntime.concurrent.ListenableFuture -import com.esri.arcgisruntime.data.FeatureQueryResult -import com.esri.arcgisruntime.data.QueryParameters +import android.widget.ProgressBar +import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat +import androidx.core.view.isInvisible +import androidx.core.view.isVisible import com.esri.arcgisruntime.data.ServiceFeatureTable +import com.esri.arcgisruntime.geometry.Geometry +import com.esri.arcgisruntime.geometry.Point +import com.esri.arcgisruntime.geometry.SpatialReferences import com.esri.arcgisruntime.layers.FeatureLayer +import com.esri.arcgisruntime.loadable.LoadStatus import com.esri.arcgisruntime.mapping.ArcGISMap import com.esri.arcgisruntime.mapping.Basemap -import kotlinx.android.synthetic.main.activity_main.mapView -import java.util.* +import com.esri.arcgisruntime.mapping.view.Graphic +import com.esri.arcgisruntime.mapping.view.GraphicsOverlay +import com.esri.arcgisruntime.mapping.view.MapView +import com.esri.arcgisruntime.symbology.PictureMarkerSymbol +import com.esri.arcgisruntime.symbology.SimpleLineSymbol +import com.esri.arcgisruntime.tasks.networkanalysis.Route +import com.esri.arcgisruntime.tasks.networkanalysis.RouteParameters +import com.esri.arcgisruntime.tasks.networkanalysis.RouteTask +import com.esri.arcgisruntime.tasks.networkanalysis.Stop +import kotlinx.android.synthetic.main.activity_main.* +import java.util.concurrent.ExecutionException + class MainActivity : AppCompatActivity() { companion object { private val TAG: String = MainActivity::class.java.simpleName } + private val buildingsFeatureTable: ServiceFeatureTable by lazy { ServiceFeatureTable(getString(R.string.buildings_url)) } @@ -34,11 +49,28 @@ class MainActivity : AppCompatActivity() { FeatureLayer(roomsFeatureTable) } + private var MapView: MapView? = null + private var mRoute: Route? = null + private val mRouteTask: RouteTask? = null + private val mRouteParams: RouteParameters? = null + private var mSourcePoint: Point? = null + private var mDestinationPoint: Point? = null + private var mRouteSymbol: SimpleLineSymbol? = null + private var mGraphicsOverlay: GraphicsOverlay? = null + private var roomGeometry : Geometry? = null + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - val map = ArcGISMap(Basemap.Type.TOPOGRAPHIC, 40.249727, -111.649265, 16) - mapView.map = map +// MapView = findViewById(R.id.mapView) + val progressBar: ProgressBar = findViewById(R.id.progressBar) + val bundle: Bundle? = intent.extras + this.roomGeometry = Geometry.fromJson(bundle?.getString("geometry")) + val lo = LocationUtil() + var currentLocation: Location? = lo.currentLocation + + val map = ArcGISMap(Basemap.Type.LIGHT_GRAY_CANVAS_VECTOR, 40.249727, -111.649265, 16) +// mapView.map = map // create feature layer with its service feature table // create the service feature table @@ -55,65 +87,113 @@ class MainActivity : AppCompatActivity() { // // // add the layer to the map // map.operationalLayers.add(buildingLayer) -// map.operationalLayers.add(roomsLayer) + map.operationalLayers.add(roomsLayer) // set the map to be displayed in the mapview mapView.map = map - } - override fun onNewIntent(intent: Intent) { - this.intent = intent - if (Intent.ACTION_SEARCH == intent.action) { - intent.getStringExtra(SearchManager.QUERY)?.let { - if (it.isNotEmpty()) { - searchBuildings(it) + setupSymbols() + + progressBar.isInvisible = true + + + val routeTaskUrl = + "https://utility.arcgis.com/usrsvcs/servers/a8ee36150d1b4178b33affcb5d7027cb/rest/services/World/Route/NAServer/Route_World" + // create route task from San Diego service + val routeTask = RouteTask(applicationContext, routeTaskUrl) +// var listenableFuture: ListenableFuture = routeTask.createDefaultParametersAsync() + +// routeTask.loadAsync() + val routeParameters = routeTask.createDefaultParametersAsync().get() + + routeTask.addDoneLoadingListener { + if (routeTask.loadError == null && routeTask.loadStatus == LoadStatus.LOADED) { // route task has loaded successfully + try { // get default route parameters +// val ESPG_3857 = SpatialReference.create(102100); + val roomCenter = this.roomGeometry?.extent?.center + if (lo == null){ + + } + val stop1Loc = Stop(Point(lo.currentLocation!!.latitude, lo.currentLocation!!.longitude)) + val stop2Loc = Stop(roomCenter) + // add route stops + routeParameters.setStops(listOf(stop1Loc, stop2Loc)) + + val result = routeTask.solveRouteAsync(routeParameters).get() + val routes = result.routes + mRoute = routes[0] + val routeGraphic: Graphic = Graphic(mRoute?.routeGeometry, mRouteSymbol) + mGraphicsOverlay?.graphics?.add(routeGraphic); + + + val directions = mRoute?.directionManeuvers +// val directionsArray = List(directions.size!!) + + // add mRouteSymbol graphic to the map + val selectedRouteSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.GREEN, 5F) + val selectedRouteGraphic = Graphic( + directions?.get(0)?.getGeometry(), + selectedRouteSymbol) + mGraphicsOverlay?.graphics?.add(selectedRouteGraphic) + } catch (e: Exception) { + e.printStackTrace() } } } + progressBar.isVisible = false + } - private fun searchBuildings(searchString: String) { - // clear any previous selections - buildingLayer.clearSelection() - // create a query for the state that was entered - val query = QueryParameters() - // make search case insensitive - query.whereClause = - "(upper(Name) LIKE '% ${searchString.toUpperCase(Locale.US)}%' OR Upper(Acronym) LIKE '%${searchString.toUpperCase(Locale.US)}%') AND Acronym != ''" - // call select features - val future: ListenableFuture = buildingsFeatureTable.queryFeaturesAsync(query) - // add done loading listener to fire when the selection returns - future.addDoneListener { - try { - // call get on the future to get the result - val result = future.get() - // check there are some results - val resultIterator = result.iterator() - if (resultIterator.hasNext()) { - resultIterator.next().run { - // get the extent of the first feature in the result to zoom to -// val envelope = geometry.extent -// mapView.setViewpointGeometryAsync(envelope, 10.0) -// // select the feature -// buildingLayer.selectFeature(this) - Log.d(TAG, attributes.toString()) - } - } else { - "No buildings found with name: $searchString".also { - Toast.makeText(this, it, Toast.LENGTH_LONG).show() - Log.d(TAG, it) - } - } - } catch (e: Exception) { - "Feature search failed for: $searchString. Error: ${e.message}".also { - Toast.makeText(this, it, Toast.LENGTH_LONG).show() - Log.e(TAG, it) - } + private fun setupSymbols() { + mGraphicsOverlay = GraphicsOverlay() + //add the overlay to the map view + mapView?.graphicsOverlays?.add(mGraphicsOverlay) + //[DocRef: Name=Picture Marker Symbol Drawable-android, Category=Fundamentals, Topic=Symbols and Renderers] + //Create a picture marker symbol from an app resource + val startDrawable = + ContextCompat.getDrawable(this, R.drawable.ic_source) as BitmapDrawable? + val pinSourceSymbol: PictureMarkerSymbol + try { + pinSourceSymbol = PictureMarkerSymbol.createAsync(startDrawable).get() + pinSourceSymbol.loadAsync() + pinSourceSymbol.addDoneLoadingListener { + //add a new graphic as start point + mSourcePoint = + Point(-117.15083257944445, 32.741123367963446, SpatialReferences.getWgs84()) + val pinSourceGraphic = Graphic(mSourcePoint, pinSourceSymbol) + mGraphicsOverlay!!.getGraphics().add(pinSourceGraphic) + } + pinSourceSymbol.offsetY = 20f + } catch (e: InterruptedException) { + e.printStackTrace() + } catch (e: ExecutionException) { + e.printStackTrace() + } + //[DocRef: END] + val endDrawable = + ContextCompat.getDrawable(this, R.drawable.ic_destination) as BitmapDrawable? + val pinDestinationSymbol: PictureMarkerSymbol + try { + pinDestinationSymbol = PictureMarkerSymbol.createAsync(endDrawable).get() + pinDestinationSymbol.loadAsync() + pinDestinationSymbol.addDoneLoadingListener { + //add a new graphic as end point + mDestinationPoint = + Point(-117.15557279683529, 32.703360305883045, SpatialReferences.getWgs84()) + val destinationGraphic = + Graphic(mDestinationPoint, pinDestinationSymbol) + mGraphicsOverlay!!.getGraphics().add(destinationGraphic) } + pinDestinationSymbol.offsetY = 20f + } catch (e: InterruptedException) { + e.printStackTrace() + } catch (e: ExecutionException) { + e.printStackTrace() } + //[DocRef: END] + mRouteSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLUE, 5F) } - override fun onPause() { super.onPause() mapView.pause() @@ -128,4 +208,8 @@ class MainActivity : AppCompatActivity() { super.onDestroy() mapView.dispose() } + + + } + diff --git a/app/src/main/java/com/example/yfind/SearchBuilding.kt b/app/src/main/java/com/example/yfind/SearchBuilding.kt index 19bcc85..a4341a1 100644 --- a/app/src/main/java/com/example/yfind/SearchBuilding.kt +++ b/app/src/main/java/com/example/yfind/SearchBuilding.kt @@ -13,16 +13,11 @@ import com.esri.arcgisruntime.data.FeatureQueryResult import com.esri.arcgisruntime.data.QueryParameters import com.esri.arcgisruntime.data.ServiceFeatureTable import java.util.* -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView import android.widget.* import com.esri.arcgisruntime.data.Feature import com.esri.arcgisruntime.data.QueryParameters.* - - - class SearchBuilding : AppCompatActivity() { companion object { private val TAG: String = SearchBuilding::class.java.simpleName @@ -32,10 +27,6 @@ class SearchBuilding : AppCompatActivity() { ServiceFeatureTable(getString(R.string.buildings_url)) } - private lateinit var recyclerView: RecyclerView - private lateinit var viewAdapter: RecyclerView.Adapter<*> - private lateinit var viewManager: RecyclerView.LayoutManager - private lateinit var results: MutableList override fun onCreate(savedInstanceState: Bundle?) { @@ -74,7 +65,7 @@ class SearchBuilding : AppCompatActivity() { future.addDoneListener { try { // call get on the future to get the result - val result = future.get() + val result = future.get().toList() // check there are some results val resultIterator = result.iterator() print(result.toString()) @@ -87,16 +78,16 @@ class SearchBuilding : AppCompatActivity() { val lv = findViewById(R.id.list) var arrayAdapter = ArrayAdapter(this, R.layout.list_row, R.id.label, results) lv.adapter = arrayAdapter + + lv.setOnItemClickListener{ parent, view, position, id -> + val building = result[position].attributes["Acronym"].toString() + Log.d("building clicked : ", building + "position: " + position + "id: " + id) +// val building = arrayAdapter.getPosition(position.toString()) as String // The item that was clicked + val intent = Intent(this, SearchRoom::class.java) + intent.putExtra("acronym", building) + startActivity(intent) + } } -// if (resultIterator.hasNext()) { -// resultIterator.next().run { -// // get the extent of the first feature in the result to zoom to -//// val envelope = geometry.extent -//// mapView.setViewpointGeometryAsync(envelope, 10.0) -//// // select the feature -// Log.d(TAG, attributes.toString()) -// } -// } else { "No buildings found with name: $searchString".also { Toast.makeText(this, it, Toast.LENGTH_LONG).show() @@ -144,3 +135,6 @@ class SearchBuilding : AppCompatActivity() { } } + + + diff --git a/app/src/main/java/com/example/yfind/SearchRoom.kt b/app/src/main/java/com/example/yfind/SearchRoom.kt new file mode 100644 index 0000000..9b1101c --- /dev/null +++ b/app/src/main/java/com/example/yfind/SearchRoom.kt @@ -0,0 +1,139 @@ +package com.example.yfind + +import android.app.SearchManager +import android.content.Context +import android.content.Intent +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.os.Parcelable +import android.util.Log +import android.view.Menu +import com.esri.arcgisruntime.concurrent.ListenableFuture +import com.esri.arcgisruntime.data.FeatureQueryResult +import com.esri.arcgisruntime.data.QueryParameters +import com.esri.arcgisruntime.data.ServiceFeatureTable +import java.util.* +import androidx.recyclerview.widget.RecyclerView +import android.widget.* +import com.esri.arcgisruntime.data.Feature +import com.esri.arcgisruntime.data.QueryParameters.* +import com.esri.arcgisruntime.geometry.Geometry +import kotlinx.android.parcel.Parcelize + +class SearchRoom : AppCompatActivity() { + companion object { + private val TAG: String = SearchRoom::class.java.simpleName + } + + private val roomsFeatureTable: ServiceFeatureTable by lazy { + ServiceFeatureTable(getString(R.string.rooms_url)) + } + + private var building :String = "" + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.search_room) + val bundle: Bundle? = intent.extras + this.building = bundle?.getString("acronym").toString() + SearchRooms("") + } + + private fun SearchRooms(searchString: String) { + + // create a query for the state that was entered + val query = QueryParameters() +// query.orderByFields.add(OrderBy("Acronym", SortOrder.ASCENDING)) + // make search case insensitive + Log.d("creating SearchRoom: ", building) + + query.whereClause = + "upper(RoomNumber) LIKE '%${searchString.toUpperCase(Locale.US)}%' AND upper(BLDG_SHORT)='${building}' " + query.maxFeatures = 10 + // call select features + val future: ListenableFuture = roomsFeatureTable.queryFeaturesAsync(query) + // add done loading listener to fire when the selection returns + future.addDoneListener { + + try { + Log.d("TAG" , "in doneListener") + // call get on the future to get the result + val result = future.get().toList() + // check there are some results + val resultIterator = result.iterator() + if(result.any()){ + var results: List = result.map { it.attributes["RoomNumber"].toString() } +// while (resultIterator.hasNext()){ +// results.add(resultIterator.next().attributes["Acronym"].toString()) +// } + Log.d("result: " , results[0]) + val lv = findViewById(R.id.list) + var arrayAdapter = ArrayAdapter(this, R.layout.list_row, R.id.label, results) + lv.adapter = arrayAdapter + + lv.setOnItemClickListener{ parent, view, position, id -> + val geo = result[position].geometry.toJson() // The item that was clicked + val intent = Intent(this, MainActivity::class.java) + intent.putExtra("geometry", geo) + startActivity(intent) + } + } +// if (resultIterator.hasNext()) { +// resultIterator.next().run { +// // get the extent of the first feature in the result to zoom to +//// val envelope = geometry.extent +//// mapView.setViewpointGeometryAsync(envelope, 10.0) +//// // select the feature +// Log.d(TAG, attributes.toString()) +// } +// } + else { + "No rooms found with name: $searchString for building: $building".also { + Toast.makeText(this, it, Toast.LENGTH_LONG).show() + Log.d(TAG, it) + } + } + } catch (e: Exception) { + "Feature search failed for: $searchString. Error: ${e.message}".also { + Toast.makeText(this, it, Toast.LENGTH_LONG).show() + Log.e(TAG, it) + } + + } + } + } + override + fun onCreateOptionsMenu(menu: Menu): Boolean { + val inflater = menuInflater + // Inflate menu to add items to action bar if it is present. + inflater.inflate(R.menu.menu_main, menu) + // Associate searchable configuration with the SearchView + val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager + val searchView = menu.findItem(R.id.action_search).getActionView() as SearchView + searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { + + override fun onQueryTextChange(it: String): Boolean { + if (it.isNotEmpty()) { + SearchRooms(it) + } + return false + } + + override fun onQueryTextSubmit(it: String): Boolean { + SearchRooms(it) + return false + } + + }) + searchView.setIconifiedByDefault(false) + searchView.setSearchableInfo( + searchManager.getSearchableInfo(componentName) + ) + + return true + } +} + + +//@Parcelize +//class Geometry(val name: Geometry, val age: Int) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/example/yfind/locationUtil.kt b/app/src/main/java/com/example/yfind/locationUtil.kt new file mode 100644 index 0000000..f3a7c00 --- /dev/null +++ b/app/src/main/java/com/example/yfind/locationUtil.kt @@ -0,0 +1,109 @@ +package com.example.yfind + +import android.Manifest +import android.annotation.SuppressLint +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.location.Location +import android.location.LocationManager +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.os.Looper +import android.provider.Settings +import android.widget.Toast +import androidx.core.app.ActivityCompat +import com.google.android.gms.location.* + +//import com.google.android.gms.location.* + +public class LocationUtil : AppCompatActivity() { + val PERMISSION_ID = 42 + lateinit var mFusedLocationClient: FusedLocationProviderClient + var currentLocation: Location? = null + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this) + + getLastLocation() + } + + @SuppressLint("MissingPermission") + private fun getLastLocation() { + if (checkPermissions()) { + if (isLocationEnabled()) { + + mFusedLocationClient.lastLocation.addOnCompleteListener(this) { task -> + var location: Location? = task.result + if (location == null) { + requestNewLocationData() + } else { + currentLocation = location +// findViewById(R.id.latTextView).text = location.latitude.toString() +// findViewById(R.id.lonTextView).text = location.longitude.toString() + } + } + } else { + Toast.makeText(this, "Turn on location", Toast.LENGTH_LONG).show() + val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS) + startActivity(intent) + } + } else { + requestPermissions() + } + } + private fun requestPermissions() { + ActivityCompat.requestPermissions( + this, + arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION), + PERMISSION_ID + ) + } + @SuppressLint("MissingPermission") + private fun requestNewLocationData() { + var mLocationRequest = LocationRequest() + mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY + mLocationRequest.interval = 0 + mLocationRequest.fastestInterval = 0 + mLocationRequest.numUpdates = 1 + + var mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this) + mFusedLocationClient!!.requestLocationUpdates( + mLocationRequest, mLocationCallback, + Looper.myLooper() + ) + } + + + private fun isLocationEnabled(): Boolean { + var locationManager: LocationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager + return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled( + LocationManager.NETWORK_PROVIDER + ) + } + + private fun checkPermissions(): Boolean { + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){ + return true + } + return false + } + + private val mLocationCallback = object : LocationCallback() { + override fun onLocationResult(locationResult: LocationResult) { + var mLastLocation: Location = locationResult.lastLocation + currentLocation = mLastLocation +// findViewById(R.id.latTextView).text = mLastLocation.latitude.toString() +// findViewById(R.id.lonTextView).text = mLastLocation.longitude.toString() + } + } + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + if (requestCode == PERMISSION_ID) { + if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { + getLastLocation() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_destination.png b/app/src/main/res/drawable/ic_destination.png new file mode 100644 index 0000000000000000000000000000000000000000..ef5a9aa0ee31bb851ea2b6549f1c69321cf7842c GIT binary patch literal 1421 zcmV;81#C00057P)t-s0001R zC>U@o7;r2aa4Q>dD;aPr8E`Bba4Q;cD;jVxAaE-ia4Q>dD;jVs8gMHbcrP1{JRYn~ zA+%8<%3USsZYY*O9=lZ|*=8ogStOlAABQ*{(qSduQ!3$FD&k)$3BHnf=A+ON#bcn-&!;Dx}5+2|NZv#`sm~I z$i3^CgW+aE|Nj2;$GqZdNdEfy?4gbAqmSr`Z}{KX=!tOn*2U;>E8kWw;9fc6X-DOF zTkD;O_|?Pfn1cTM`|-Q1{q^(dl6&75g{!;M(xFsPxIc=#6yfi*epmEa7B9 z=Z9?m{QLLW(f<7U{q*nr^6&ie@c#Y${`>mndtT;(XZhpa=!$Xo*wEl%J^0<$;9NHT z`}zIx>-_HP_R+}WZcXf;i~H&2=6zw|Vm|lU(%)Dy`|Rld{r&U8wc~P9=!kCWmVfJ- zg!tar=!gM>{)bz{1 z@w=_=tC{D9Yu{HdCRkdd0000FbW%=J03bkskH2uQ-_H;*VDF#v+;|5700VtVL_t(| z+U?r+Thl-o2XN@1v_N-Spd2CsR;!3Xw73-)3OGO%_rQt8iF@GQ`Y+o{F6l_p*j)0y zkB@nOywH9>&E37ZhbIjU7OK(X_4)mgvhw?VUQeTy@2Wq%DbO4-sOCVE!-&SFV8o@={9*dTig#Cn&PYF+@+XaJaPp1@wFJy0i3tM=p z4#A{4QfxuC*qPrde`#mCS-f-~I_1A^wL3r4r58t}>h50Avr--F%GfKA^W*xzmy}iS zsy;Rvw^QJe)}GPilgjEJSS>FFX*Jri8A5F|zf1T#03q2Pc^aso&5pewbsyu!Pqfv$ zM!E-5PqJwO;zB(DlI>I10skb>{+AKz126&I3x3}G7Wy-i^#Vwi&O(xYmbV{;i{B9w z>IRT*dM#G`aF`Q7w?NtgfY7#-rW=8O2BLx$fOHF@+;iZi4$sVWySj+Z7kPARJQqCHnzj!f6KhF&itN{qU`p*MG|2+VG3S58-Z~
~~`fTu`+ zXA0ms5RA8FV`8u7cz~Ovzfz$b>0>|^s1kUH12mtbH z3n21q3PAE}31IST2!Qg91yK2h0C0006yP)t-s|Ns90 z001IoG9qO*BxW`xW;P>bH6vv;BxW`wW;G;cH7RB}C1y4yW;P^dH6&&=BxW@xZ8|G} zM=_gPGooHNwrfApek_MfHK}7e!*n;WXD*IVDSAUWy>CCrXF$ttKg@AI&2&G{ct6T( zKh1MK&v`$|YCp|&KhS(X$!R~(dq2x=JG_*Ny%E{{R2~`~Cb; z&2*gRyOrRo-}mX)^WJ6Jmj3_#s_Mj{?W&(t+~( z_UrlYK*(r;;Hc;M?)&}wbk>l>@Yba0zs&H~xa!7C)Q0)}`()XalHaHD`}IZ2Y>wlx zBMW)iNx^L@B8$5*p#s6zf04F`2G6j`R%Rh#<1wW zLCI*1vZ??96QPJTqlwq8bofOtxNUVgeYD2}<+);4VT zh`wX3X}>@o;N>?2UoZ33$OlHj(FUJD8eq9?FYM;C+!{URL9Z#et-^j!E(WOK|@~0IYpfUpug*0et*R+x-K8fcJ%% zEFi%zBh_C3Yv*?%#owEd1SB(`QE&Gfz}on^`plb?k^tTXnu`E1J}fo!jvxo%cc9KL z2H<`LyelT802TZJR1|>mR=^)j6;c2`2s9Q4;Nwvv9}1)ZHAEi}0LDQ-sF4Ejj?_^c zV07kW2YKm>>YV!-%^GBqJn50?h;$V3Nf(xW8-Om_O} zv629$WC2r40hpG}cRDAO05IJLa2_`g=$hdN%rp;}<>b_C}A+| z#Ux-QJ_uLY>{Zx&?RA5IH?R+6evqujp18&!;7!PUi~k~83p?w~0oLP1zs&&~U}xhy z#sKd^3ngVRbOa90MbmRWVh5%b2Z)=wa_yhqP%m8}v zLHMcd0p@Lk1KZ62KEn&11pxLr9@$|8uoKdDbs^vj1bk@%@YUCl_RVfy-I>~hfNgsX z0QNb8+HU}GKm<6bA8=@*2ypm_cEC|bSjV&jz7+$$(+xN-&Ua3n)C^dGN#FnA)sJ3H z#p9Yg0V9FIcA8_>=p8HcH;5vrfC;+gVca`T%z^Xt``W%d^PI}!Ubf$ zq7@dQ0y1CK8j~;qnXhb-ONfBXSGUY3SU~10TxS$0AoEqOv*h0Qv1en6CwpD-h@F z0r&+(z9v9cK;`QKpn%NR1^@w>uMgk}$b5|e6o~V60z3hcuNA-rRK8xofFzku0R9DW WgEUt@0Y>5g0000 + - \ No newline at end of file + diff --git a/app/src/main/res/layout/search_room.xml b/app/src/main/res/layout/search_room.xml new file mode 100644 index 0000000..a45be82 --- /dev/null +++ b/app/src/main/res/layout/search_room.xml @@ -0,0 +1,15 @@ + + + + + + + +