Few months back I had come across Open Street Map because of one of my friend, that time the usage was for frontend purpose, this time while having a discussion with my senior, the thought of using Open Street Map for android came up and I tried it off.
We need to install the necessary dependancy
implementation("org.osmdroid:osmdroid-android:6.1.18")
For the coding part I found this medium article which made major part of coding a lot easier, but what it did allow me to do was to modify the code and what I did do was add the snippet to request for location permission, add a button that would take me right to my location as well as the functionality that zooms in the same place no matter how much you zoom out of the map.
The thing which I really liked about open street map is that it is full open source, no need of any kind of key to integrate, just plug and play.
class MainActivity : AppCompatActivity(), MapListener, LocationListener {
private lateinit var mMap: MapView
private lateinit var controller: IMapController
private lateinit var mMyLocationOverlay: MyLocationNewOverlay
private lateinit var locationManager: LocationManager
private lateinit var binding: ActivityMainBinding
private val targetZoomLevel = 20.0
private val LOCATION_PERMISSION_REQUEST_CODE = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
Configuration.getInstance().load(
applicationContext,
getSharedPreferences(getString(R.string.app_name), MODE_PRIVATE)
)
mMap = binding.osmmap
mMap.setTileSource(TileSourceFactory.MAPNIK)
mMap.mapCenter
mMap.setMultiTouchControls(true)
mMap.getLocalVisibleRect(Rect())
initializeMap()
}
private fun initializeMap() {
mMyLocationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), mMap)
controller = mMap.controller
mMyLocationOverlay.enableMyLocation()
mMyLocationOverlay.enableFollowLocation()
mMyLocationOverlay.isDrawAccuracyEnabled = true
val myLocationButton = binding.myLocationButton
myLocationButton.setOnClickListener {
// Get the current location from the MyLocationNewOverlay
val myLocation = mMyLocationOverlay.myLocation
if (myLocation != null) {
// Move the map to the current location
controller.setCenter(myLocation)
controller.animateTo(myLocation)
controller.setZoom(targetZoomLevel)
} else {
Toast.makeText(this, "Location not available yet.", Toast.LENGTH_SHORT).show()
}
}
Log.e("TAG", "onCreate:in ${controller.zoomIn()}")
Log.e("TAG", "onCreate: out ${controller.zoomOut()}")
mMap.overlays.add(mMyLocationOverlay)
mMap.addMapListener(this)
// Initialize LocationManager
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
// Request location updates
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
requestLocationPermission()
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1f, this)
}
private fun requestLocationPermission() {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
LOCATION_PERMISSION_REQUEST_CODE
)
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
when (requestCode) {
LOCATION_PERMISSION_REQUEST_CODE -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted, initialize the map
initializeMap()
} else {
// Permission denied, handle accordingly (e.g., show a message to the user)
Toast.makeText(this, "Location permission denied.", Toast.LENGTH_SHORT).show()
}
}
else -> super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
}
override fun onScroll(event: ScrollEvent?): Boolean {
Log.e("TAG", "onCreate:la ${event?.source?.mapCenter?.latitude}")
Log.e("TAG", "onCreate:lo ${event?.source?.mapCenter?.longitude}")
return true
}
override fun onZoom(event: ZoomEvent?): Boolean {
Log.e("TAG", "onZoom zoom level: ${event?.zoomLevel} source: ${event?.source}")
return false
}
override fun onLocationChanged(location: Location) {
// Handle location changes here
Log.d("TAG", "Location changed: ${location.latitude}, ${location.longitude}")
}
override fun onProviderDisabled(provider: String) {
// Handle provider disabled
}
override fun onProviderEnabled(provider: String) {
// Handle provider enabled̵
}
}
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<org.osmdroid.views.MapView
android:id="@+id/osmmap"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/myLocationButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="60dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Show My Location" />
</RelativeLayout>
This is how the result looks like, of course it shoes even minute details and names of places nearby but of course I won't be revealing exact location.