Lab 9 - Android Sensors and Location Based Services
In this lab session, we will:
- Read data from the accelerometer
- Use Google maps API and GPS to locate the phone
1. Orientation indicator that displays the device orientation as Left, Middle and Right
- Create a new project with empty activity
- In the activity_main.xml, add six text views in two rows, label the first row items as “Left, Middle, Right”, and the second row will be dynamically filled with a color (as shown in the above figure).
- In the MainActivity.kt,
- Create an instance of SensorManager to access the sensor service
- Create an instance of Sensor class, access the Accelerometer sensor through the SensorManager, and then register to the sensor listener.
- to register Activity as a sensor listener, you have to implement the SensorEventListener interface and implement its two methods:
- onAccuracyChanged ( .. )
- onSensorChanged( .. )
- to register Activity as a sensor listener, you have to implement the SensorEventListener interface and implement its two methods:
mSensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
mAccelerometer= mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
mSensorManager!!.registerListener(this, mAccelerometer,SensorManager.SENSOR_DELAY_NORMAL)
- Now read the Accelerometer data of with the function onSensorChanged(event: SensorEvent?)
override fun onSensorChanged(event: SensorEvent?) { if (event == null) return x = event.values[0] y = event.values[1] z = event.values[2] . . . . . . . . }
- Get the relevant axis's values, and do the necessary actions accordingly (hint: you can set the visibility or change the color of the text views accordingly)
2. Google Maps
2.0 Add the Google Maps SDK to your project
- Create a new project, with Google Maps Activity
- To use Google Map in your application you need to create a Google API key (Refer : https://developers.google.com/maps/gmp-get-started to get your API key)
- Insert your API key inside the google_maps_api.xml (res->values)
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">YOUR_KEY_HERE</string>
Run the project. You can see the default pin is added to Sydney. So, let us modify the onMapReady()function, which pins to Delta Center, move camera there and zoom to 12.
val delta = LatLng(58.385254, 26.725064) mMap.addMarker(MarkerOptions().position(delta).title("Delta Centre")) mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(delta,12F))
2.1 Reading the current location from the GPS and show it on the map
For this, we can use the Android Location API that can be used to track your mobile device’s current location.
- Create a new kotlin class file called TrackLocation.kt, which implements LocationListener interface. (add this code to your project)
- Permission Handling
- Add the following to the onCreate function of the MapsActivity class, give the permission and restart the application.
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) !== PackageManager.PERMISSION_GRANTED ) { ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 1 ) return }
- In the MapsActivity class, write a function to create an instance from the TrackLocation class, and return the current location.
fun getCurrentLocation():Location{ . . . . . . . . return location }
- Now call getCurrentLocation() function inside onMapReady() and pins the current location on the map
override fun onMapReady(googleMap: GoogleMap) { . . . . . . . . mMap.addMarker(MarkerOptions().position(currentLocation).title("You are here ")) mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLocation,15F)) }
2.2 My Location Button
Alternatively, we can use the "My Location" Button, which just pins to the current location.
- Add the following line to onMapReady() function (before that it is better to comment the code that related to the GPS tracking e.g. // getCurrentLocation(), etc.)
mMap.setMyLocationEnabled(true)
Once you click on the button, it will show your current location. Let’s make this app more interactive. Once you touch on the current location it will pin the location with the address. For this, we need our MapsActivity class implements OnMyLocationClickListener interface.
class MapsActivity : AppCompatActivity(), OnMapReadyCallback ,GoogleMap.OnMyLocationClickListener { . . . . }
To get the address of the current location, we use google Reverse Geocoding API. https://developers.google.com/maps/documentation/geocoding/intro#ReverseGeocoding
- Add the following codes to the override fun onMyLocationClick(location: Location) function
override fun onMyLocationClick(location: Location) { latitude=location.latitude longitude=location.longitude var nLocation=LatLng(latitude,longitude) val geocoder = Geocoder(this) val addresses = geocoder.getFromLocation(latitude, longitude, 1) val loc=addresses[0].getAddressLine(0) mMap.addMarker(MarkerOptions().position(nLocation).title("You are here $loc")) mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(nLocation,15F)) }
- After that add mMap.setOnMyLocationClickListener(this) to the onMapReady() function
3. Draw a line on the map
Here we just draw a straight line between two locations without considering the real routes between them. We draw the line from the Delta building to the current location of the device. However, google maps API provides a facility to draw a route on the map with waypoints.
- Create a function which use Polyline
fun drawPolyLine(){ var start = LatLng(58.385254, 26.725064 ) var end=LatLng(latitude,longitude) mMap.addPolyline(PolylineOptions().add(start,end)) }
- Now call this function in the onMyLocationClick() to draw the line
- you can fine the sample code (https://pastebin.com/85TyU5pr)