diff options
author | Ognjen Cirkovic <ciraboxkg@gmail.com> | 2022-11-18 20:17:37 +0100 |
---|---|---|
committer | Ognjen Cirkovic <ciraboxkg@gmail.com> | 2022-11-18 20:17:37 +0100 |
commit | 9862992f8601f6f8bc4150a04e72af2e781aea64 (patch) | |
tree | 1b6e7c9554d555c0ed1217d31a8c0f352623d748 | |
parent | 0f9c12d1a15e03d85d06091f19f48dfca7aa5df1 (diff) |
Omogucenom klikom na dugme dodaj novu lokaciju da se otvara mapa. Omogucenja pretraga , gps lociranje, klikom bilo gde na mapi se postavlja marker.
4 files changed, 431 insertions, 60 deletions
diff --git a/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml b/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml index 56bdb58..1f19b5c 100644 --- a/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml +++ b/Client/BrzoDoLokacije/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools"> - + xmlns:tools="http://schemas.android.com/tools" > <!-- DOZVOLE --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> @@ -15,9 +14,7 @@ android:name="android.permission.CAMERA" android:required="true" android:requiredFeature="true" /> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - - <!-- SVOJSTVA --> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- SVOJSTVA --> <uses-feature android:name="android.hardware.camera" android:required="true" /> @@ -38,16 +35,31 @@ android:supportsRtl="true" android:theme="@style/Theme.BrzoDoLokacije" android:usesCleartextTraffic="true" - tools:targetApi="31"> + tools:targetApi="31" > + <activity + android:name=".MapsActivity" + android:exported="false" > + <meta-data + android:name="android.app.lib_name" + android:value="" /> + </activity> <meta-data android:name="com.google.android.geo.API_KEY" android:value="YOUR_API_KEY" /> - <activity android:name=".Activities.MapsActivity" android:screenOrientation="portrait" /> - <activity android:name=".Activities.ActivityCapturePost" android:screenOrientation="portrait" /> - <activity android:name=".Activities.ActivitySinglePost" android:screenOrientation="portrait" /> - <activity android:name=".Activities.ActivityAddPost" android:screenOrientation="portrait" /> + <activity + android:name=".Activities.MapsActivity" + android:screenOrientation="portrait" /> + <activity + android:name=".Activities.ActivityCapturePost" + android:screenOrientation="portrait" /> + <activity + android:name=".Activities.ActivitySinglePost" + android:screenOrientation="portrait" /> + <activity + android:name=".Activities.ActivityAddPost" + android:screenOrientation="portrait" /> <activity android:name=".Activities.SplashPage" android:exported="true" @@ -62,18 +74,27 @@ android:name="android.app.lib_name" android:value="" /> </activity> - <activity android:name=".Activities.ActivityForgottenPasswordVerify" android:screenOrientation="portrait" /> - <activity android:name=".Activities.ActivityForgottenPassword" android:screenOrientation="portrait" /> - <activity android:name=".Activities.ActivityLoginRegister" android:screenOrientation="portrait" /> - <activity android:name=".Activities.NavigationActivity" android:screenOrientation="portrait" /> - <activity android:name=".MainActivity" android:screenOrientation="portrait" /> - + <activity + android:name=".Activities.ActivityForgottenPasswordVerify" + android:screenOrientation="portrait" /> + <activity + android:name=".Activities.ActivityForgottenPassword" + android:screenOrientation="portrait" /> + <activity + android:name=".Activities.ActivityLoginRegister" + android:screenOrientation="portrait" /> + <activity + android:name=".Activities.NavigationActivity" + android:screenOrientation="portrait" /> + <activity + android:name=".MainActivity" + android:screenOrientation="portrait" /> <provider android:name="androidx.core.content.FileProvider" android:authorities="com.example.android.fileprovider" android:exported="false" - android:grantUriPermissions="true"> + android:grantUriPermissions="true" > <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/MapsActivity.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/MapsActivity.kt index b9205f6..8762d4e 100644 --- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/MapsActivity.kt +++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Activities/MapsActivity.kt @@ -1,49 +1,331 @@ package com.example.brzodolokacije.Activities -import androidx.appcompat.app.AppCompatActivity +import android.Manifest +import android.content.Context +import android.content.pm.PackageManager +import android.graphics.Canvas +import android.location.Location +import android.location.LocationManager +import android.os.Build import android.os.Bundle - -import com.google.android.gms.maps.CameraUpdateFactory -import com.google.android.gms.maps.GoogleMap -import com.google.android.gms.maps.OnMapReadyCallback -import com.google.android.gms.maps.SupportMapFragment -import com.google.android.gms.maps.model.LatLng -import com.google.android.gms.maps.model.MarkerOptions +import android.os.Looper +import android.os.StrictMode +import android.preference.PreferenceManager +import android.util.DisplayMetrics +import android.view.KeyEvent +import android.view.MotionEvent +import android.view.View +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat import com.example.brzodolokacije.R -import com.example.brzodolokacije.databinding.ActivityMapsBinding +import com.example.brzodolokacije.Services.GeocoderHelper +import com.google.android.gms.location.* +import com.google.android.material.button.MaterialButton +import com.google.android.material.floatingactionbutton.FloatingActionButton +import com.google.android.material.textfield.TextInputEditText +import org.osmdroid.config.Configuration +import org.osmdroid.tileprovider.tilesource.TileSourceFactory +import org.osmdroid.util.GeoPoint +import org.osmdroid.views.MapView +import org.osmdroid.views.Projection +import org.osmdroid.views.overlay.* +import org.osmdroid.views.overlay.compass.CompassOverlay +import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider +import org.osmdroid.views.overlay.gestures.RotationGestureOverlay +import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider +import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay -class MapsActivity : AppCompatActivity(), OnMapReadyCallback { - - private lateinit var mMap: GoogleMap - private lateinit var binding: ActivityMapsBinding +class MapsActivity : AppCompatActivity() { + var map: MapView? = null + var mLocationOverlay: MyLocationNewOverlay?=null + var mRotationGestureOverlay: RotationGestureOverlay?=null + var mScaleBarOverlay: ScaleBarOverlay?=null + var mCompassOverlay: CompassOverlay?=null + private lateinit var locationManager: LocationManager + private lateinit var searchButton: MaterialButton + private lateinit var gpsButton: FloatingActionButton + private lateinit var searchBar: TextInputEditText + var client: FusedLocationProviderClient? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + setContentView(R.layout.activity_maps) + + val ctx: Context = this + Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx)); + map= findViewById<MapView>(R.id.ActivityMapsMapView) + map!!.setTileSource(TileSourceFactory.MAPNIK); + setUpMap() + searchButton=findViewById<View>(R.id.ActivityMapsSearchButton) as MaterialButton + gpsButton=findViewById<View>(R.id.ActivityMapsMyLocation) as FloatingActionButton + searchBar=findViewById<View>(R.id.ActivityMapsSearchBar) as TextInputEditText + client= LocationServices.getFusedLocationProviderClient(this) + searchButton.setOnClickListener{ + searchMap() + + } + gpsButton.setOnClickListener{ + getLocation() + } + searchBar.setOnKeyListener(View.OnKeyListener { v1, keyCode, event -> // If the event is a key-down event on the "enter" button + if (event.action === KeyEvent.ACTION_DOWN && + keyCode == KeyEvent.KEYCODE_ENTER + ) { + // Perform action on key press + searchMap() + return@OnKeyListener true + } + false + }) + + + + } + + + override fun onResume() { + super.onResume() + map!!.onResume() + } + override fun onPause() { + super.onPause() + map!!.onPause() + } + fun setUpMap(){ + //Set up controlls and startPoint + map!!.setBuiltInZoomControls(true); + map!!.setMultiTouchControls(true); + val mapController = map!!.controller + mapController.setZoom(15) + fixNetworkPolicy() + + //my location + //checkLocPerm() + mLocationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), map) + mLocationOverlay!!.enableMyLocation() + map!!.getOverlays().add(this.mLocationOverlay) + + //start point + val startPoint = GeoPoint(44.0107,20.9181)//dodati nasu lokaciju TODO + mapController.setCenter(startPoint) + + //rotation gestures + mRotationGestureOverlay = RotationGestureOverlay(this, map) + mRotationGestureOverlay!!.setEnabled(true) + map!!.setMultiTouchControls(true) + map!!.getOverlays().add(this.mRotationGestureOverlay) + //Map scale bar + val dm: DisplayMetrics =this.resources.displayMetrics + mScaleBarOverlay = ScaleBarOverlay(map); + mScaleBarOverlay!!.setCentred(true); + mScaleBarOverlay!!.setScaleBarOffset(dm.widthPixels / 2, 10); + map!!.getOverlays().add(this.mScaleBarOverlay); + + //Compass + this.mCompassOverlay = + CompassOverlay(this, InternalCompassOrientationProvider(this), map) + mCompassOverlay!!.enableCompass() + map!!.getOverlays().add(this.mCompassOverlay) + + + val touchOverlay: Overlay = object : Overlay(this) { + var anotherItemizedIconOverlay: ItemizedIconOverlay<OverlayItem>? = null + override fun onSingleTapConfirmed(e: MotionEvent, mapView: MapView): Boolean { + val marker = ContextCompat.getDrawable(this@MapsActivity, R.drawable.ic_baseline_add_location_24); + val proj: Projection = mapView.projection + val loc = proj.fromPixels(e.x.toInt(), e.y.toInt()) + val longitude = java.lang.Double.toString(loc.longitudeE6.toDouble() / 1000000) + val latitude = java.lang.Double.toString(loc.latitudeE6.toDouble() / 1000000) + val overlayArray = ArrayList<OverlayItem>() + val mapItem = OverlayItem( + "", "", GeoPoint( + loc.latitudeE6.toDouble() / 1000000, + loc.longitudeE6.toDouble() / 1000000 + ) + ) + mapItem.setMarker(marker) + overlayArray.add(mapItem) + if (anotherItemizedIconOverlay == null) { + anotherItemizedIconOverlay = + ItemizedIconOverlay(applicationContext, overlayArray, null) + mapView.overlays.add(anotherItemizedIconOverlay) + mapView.invalidate() + } else { + mapView.overlays.remove(anotherItemizedIconOverlay) + mapView.invalidate() + anotherItemizedIconOverlay = + ItemizedIconOverlay(applicationContext, overlayArray, null) + mapView.overlays.add(anotherItemizedIconOverlay) + } + // dlgThread(); + return true + } + } + map!!.getOverlays().add(touchOverlay) + } + fun checkLocPerm(){ + if (ContextCompat.checkSelfPermission( + this, + Manifest.permission.ACCESS_FINE_LOCATION + ) + != PackageManager.PERMISSION_GRANTED + ) { + ActivityCompat.requestPermissions( + this, + arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), + 101 + ) + } + } + + fun fixNetworkPolicy(){ + val SDK_INT = Build.VERSION.SDK_INT + if (SDK_INT > 8) { + val policy = StrictMode.ThreadPolicy.Builder() + .permitAll().build() + StrictMode.setThreadPolicy(policy) + //your codes here + } + } + fun searchMap(){ + var geocoder= GeocoderHelper.getInstance() + //Log.d("Main",geocoder!!.getFromLocationName("Paris",1)[0].countryName) + var locString=searchBar.text.toString().trim() + if(locString==null || locString=="") + Toast.makeText(this,"Unesite naziv lokacije", Toast.LENGTH_SHORT) + else{ + var result=geocoder!!.getFromLocationName(locString,1)[0] + if(result==null) + Toast.makeText(this,"Nepostojeca lokacija", Toast.LENGTH_SHORT) + else{ + //move to spot + val searchPoint = GeoPoint(result.latitude,result.longitude) + val startMarker = Marker(map) + startMarker.setPosition(searchPoint) + startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM) + map!!.getOverlays().add(startMarker) + map!!.controller.animateTo(searchPoint) + + + } + } + } + private fun getLocation() { + if (ContextCompat.checkSelfPermission( + this, + Manifest.permission + .ACCESS_FINE_LOCATION) + == PackageManager + .PERMISSION_GRANTED + && ContextCompat.checkSelfPermission( + this, + Manifest.permission + .ACCESS_COARSE_LOCATION) + == PackageManager + .PERMISSION_GRANTED) { + // When permission is granted + // Call method + getCurrentLocation() + } + else { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + requestPermissions( + arrayOf( + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION + ), + 111 + ) + } + + } + } + override fun onRequestPermissionsResult( + requestCode: Int, permissions: Array<String?>, + grantResults: IntArray + ) { + super.onRequestPermissionsResult( + requestCode, permissions, grantResults + ) + // Check condition + if (requestCode == 111 && grantResults.size > 0 + && (grantResults[0] + grantResults[1] + == PackageManager.PERMISSION_GRANTED) + ) { + // When permission are granted + // Call method + getCurrentLocation() + } else { + // When permission are denied + // Display toast + Toast + .makeText( + this, + "Permission denied", + Toast.LENGTH_SHORT + ) + .show() + } + } + @Suppress("MissingPermission") + private fun getCurrentLocation() { + val locationManager = this + .getSystemService( + Context.LOCATION_SERVICE + ) as LocationManager + checkLocPerm() + if (locationManager.isProviderEnabled( + LocationManager.GPS_PROVIDER + ) + || locationManager.isProviderEnabled( + LocationManager.NETWORK_PROVIDER + ) + ) { + + client!!.getLastLocation().addOnCompleteListener { task -> + var location = task.result + if (location == null) { + val locationRequest: LocationRequest = LocationRequest() + .setPriority( + LocationRequest.PRIORITY_HIGH_ACCURACY + ) + .setInterval(10000) + .setFastestInterval( + 1000 + ) + .setNumUpdates(1) + + val locationCallback: LocationCallback = object : LocationCallback() { + override fun onLocationResult( + locationResult: LocationResult + ) { + // Initialize + // location + val location1: Location? = locationResult + .lastLocation + // Set latitude + map!!.controller.animateTo( + GeoPoint( + location1!!.latitude, + location1!!.longitude + ) + ) + + } + } + client!!.requestLocationUpdates( + locationRequest, + locationCallback, + Looper.myLooper() + ); + } else { + map!!.controller.animateTo(GeoPoint(location!!.latitude, location!!.longitude)) + } + - binding = ActivityMapsBinding.inflate(layoutInflater) - setContentView(binding.root) - - // Obtain the SupportMapFragment and get notified when the map is ready to be used. - val mapFragment = supportFragmentManager - .findFragmentById(R.id.map) as SupportMapFragment - mapFragment.getMapAsync(this) - } - - /** - * Manipulates the map once available. - * This callback is triggered when the map is ready to be used. - * This is where we can add markers or lines, add listeners or move the camera. In this case, - * we just add a marker near Sydney, Australia. - * If Google Play services is not installed on the device, the user will be prompted to install - * it inside the SupportMapFragment. This method will only be triggered once the user has - * installed Google Play services and returned to the app. - */ - override fun onMapReady(googleMap: GoogleMap) { - mMap = googleMap - - // Add a marker in Sydney and move the camera - val sydney = LatLng(-34.0, 151.0) - mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney")) - mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)) + } + } } }
\ No newline at end of file diff --git a/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_add_location_24.xml b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_add_location_24.xml new file mode 100644 index 0000000..8f88131 --- /dev/null +++ b/Client/BrzoDoLokacije/app/src/main/res/drawable/ic_baseline_add_location_24.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#FF3535" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C8.14,2 5,5.14 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.86 -3.14,-7 -7,-7zM16,10h-3v3h-2v-3L8,10L8,8h3L11,5h2v3h3v2z"/> +</vector> diff --git a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_maps.xml b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_maps.xml index 01c8abd..b45e1f0 100644 --- a/Client/BrzoDoLokacije/app/src/main/res/layout/activity_maps.xml +++ b/Client/BrzoDoLokacije/app/src/main/res/layout/activity_maps.xml @@ -1,9 +1,72 @@ <?xml version="1.0" encoding="utf-8"?> -<fragment xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:map="http://schemas.android.com/apk/res-auto" +<androidx.constraintlayout.widget.ConstraintLayout + xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/map" - android:name="com.google.android.gms.maps.SupportMapFragment" + xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".Activities.MapsActivity" />
\ No newline at end of file + tools:context=".Activities.MapsActivity"> + <org.osmdroid.views.MapView + android:id="@+id/ActivityMapsMapView" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + /> + + + + <com.google.android.material.floatingactionbutton.FloatingActionButton + android:id="@+id/ActivityMapsMyLocation" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentStart="true" + android:backgroundTint="#FFFFFF" + android:layout_marginRight="10dp" + android:layout_marginBottom="80dp" + android:clickable="true" + android:focusable="true" + android:tint="#FFFFFF" + app:layout_constraintBottom_toBottomOf="@+id/ActivityMapsMapView" + app:layout_constraintEnd_toEndOf="parent" + app:rippleColor="#FFFFFF" + app:srcCompat="@android:drawable/ic_menu_mylocation" /> + + <androidx.cardview.widget.CardView + android:id="@+id/ActivityMapsCardViewSearch" + android:layout_width="0dp" + android:layout_marginTop="60dp" + android:layout_height="40dp" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:elevation="0dp" + app:cardCornerRadius="20dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + + <com.google.android.material.textfield.TextInputEditText + android:id="@+id/ActivityMapsSearchBar" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/rounded_white_button_login" + android:hint=" Pretraga" + android:inputType="textPersonName" + android:paddingLeft="15dp" /> + + <com.google.android.material.button.MaterialButton + android:id="@+id/ActivityMapsSearchButton" + android:layout_width="49dp" + android:layout_height="match_parent" + android:layout_gravity="right" + android:background="#00FFFFFF" + app:backgroundTint="#00FFFFFF" + app:cornerRadius="16dp" + app:icon="@drawable/ic_baseline_search_24" + app:iconTint="#333D70" /> + + </androidx.cardview.widget.CardView> + + </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file |