This video shows the steps to setup the location listener in your App’s java code. It uses Google Maps API Key to get the maps google maps in your App. It registers the location listener using the location manager which uses the phone’s system service to get location service. This location service is responsible to get the current location of the device/ phone and display it on the edit text boxes – latitude and longitude respectively. It uses both GPS and NETWORK information to get the precise coordinates of the location.
Then it gives an Update button which is responsible to update the location information to the Firebase database. How to configure the Firebase database for your Android Application is shown in details. Though in this App it uses a button to update the database, but the database update can be automated using any desired concept by the App developer.
Finally in the map it shows/ displays the latest location updated in the database. It fetches the database” data on any change of data and extracts the required information from the datasnapshot variable. A bit of text processing id done to extract only the latest latitude and longitude updated in the database. The information of the latest latitude and longitude is used to move the camera on the map and put the marker accordingly.
We hope you like this video. For any query, suggestions or appreciations we will be glad to hear from you at: programmerworld1990@gmail.com.
Source code:
package com.example.mylocationtrackoverfbdb; import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; import androidx.fragment.app.FragmentActivity; import android.Manifest; import android.content.pm.PackageManager; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.view.View; import android.widget.EditText; 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 com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.database.ValueEventListener; import java.util.Arrays; public class MapsActivity extends FragmentActivity implements OnMapReadyCallback { private GoogleMap mMap; private DatabaseReference databaseReference; private LocationListener locationListener; private LocationManager locationManager; private final long MIN_TIME = 1000; private final long MIN_DIST = 5; private EditText editTextLatitude; private EditText editTextLongitude; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); // Obtain the SupportMapFragment and get notified when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, PackageManager.PERMISSION_GRANTED); editTextLatitude = findViewById(R.id.editText); editTextLongitude = findViewById(R.id.editText2); databaseReference = FirebaseDatabase.getInstance().getReference("Location"); databaseReference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { try { String databaseLatitudeString = dataSnapshot.child("latitude").getValue().toString().substring(1, dataSnapshot.child("latitude").getValue().toString().length()-1); String databaseLongitudedeString = dataSnapshot.child("longitude").getValue().toString().substring(1, dataSnapshot.child("longitude").getValue().toString().length()-1); String[] stringLat = databaseLatitudeString.split(", "); Arrays.sort(stringLat); String latitude = stringLat[stringLat.length-1].split("=")[1]; String[] stringLong = databaseLongitudedeString.split(", "); Arrays.sort(stringLong); String longitude = stringLong[stringLong.length-1].split("=")[1]; LatLng latLng = new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude)); mMap.addMarker(new MarkerOptions().position(latLng).title(latitude + " , " + longitude)); mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); } catch (Exception e){ e.printStackTrace(); } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { } }); } /** * 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 public void onMapReady(GoogleMap googleMap) { mMap = googleMap; // // Add a marker in Sydney and move the camera // LatLng sydney = new LatLng(-34, 151); // mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney")); // mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); locationListener = new LocationListener() { @Override public void onLocationChanged(Location location) { try { editTextLatitude.setText(Double.toString(location.getLatitude())); editTextLongitude.setText(Double.toString(location.getLongitude())); } catch (Exception e) { e.printStackTrace(); } } @Override public void onStatusChanged(String s, int i, Bundle bundle) { } @Override public void onProviderEnabled(String s) { } @Override public void onProviderDisabled(String s) { } }; locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // Activity#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for Activity#requestPermissions for more details. return; } try { locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME, MIN_DIST, locationListener); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME, MIN_DIST, locationListener); } catch (Exception e){ e.printStackTrace(); } } public void updateButtonOnclick(View view){ databaseReference.child("latitude").push().setValue(editTextLatitude.getText().toString()); databaseReference.child("longitude").push().setValue(editTextLongitude.getText().toString()); } }
<resources> <!-- TODO: Before you run your application, you need a Google Maps API key. To get one, follow this link, follow the directions and press "Create" at the end: https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=C3:E7:EC:00:59:FC:44:F3:06:AB:E1:EF:F8:9C:3D:8C:85:8B:53:3C%3Bcom.example.mylocationtrackoverfbdb You can also add your credentials to an existing key, using these values: Package name: C3:E7:EC:00:59:FC:44:F3:06:AB:E1:EF:F8:9C:3D:8C:85:8B:53:3C SHA-1 certificate fingerprint: C3:E7:EC:00:59:FC:44:F3:06:AB:E1:EF:F8:9C:3D:8C:85:8B:53:3C Alternatively, follow the directions here: https://developers.google.com/maps/documentation/android/start#get-key Once you have your key (it starts with "AIza"), replace the "google_maps_key" string in this file. --> <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">AIzaSyA9vD-5rTAXDfVCMxoGWVrfrAMd83MVkrs</string> </resources>
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MapsActivity"> <fragment android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="550dp" tools:context=".MapsActivity" tools:layout="@android:layout/simple_spinner_dropdown_item" /> <EditText android:id="@+id/editText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="30dp" android:layout_marginTop="550dp" android:ems="10" android:hint="@string/latitude" android:inputType="textPersonName" android:autofillHints="" /> <EditText android:id="@+id/editText2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="220dp" android:layout_marginTop="550dp" android:ems="10" android:hint="@string/longitude" android:inputType="textPersonName" android:autofillHints="" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="150dp" android:layout_marginTop="600dp" android:onClick="updateButtonOnclick" android:text="@string/update" /> </FrameLayout>
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.5.2' classpath 'com.google.gms:google-services:4.3.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
apply plugin: 'com.android.application' android { compileSdkVersion 29 defaultConfig { applicationId "com.example.mylocationtrackoverfbdb" minSdkVersion 28 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'com.google.android.gms:play-services-maps:17.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation 'com.google.firebase:firebase-core:17.0.0' implementation 'com.google.firebase:firebase-database:17.0.0' } apply plugin: 'com.google.gms.google-services'
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.mylocationtrackoverfbdb"> <!-- The ACCESS_COARSE/FINE_LOCATION permissions are not required to use Google Maps Android API v2, but you must specify either coarse or fine location permissions for the 'MyLocation' functionality. --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <!-- The API key for Google Maps-based APIs is defined as a string resource. (See the file "res/values/google_maps_api.xml"). Note that the API key is linked to the encryption key used to sign the APK. You need a different API key for each encryption key, including the release key that is used to sign the APK for publishing. You can define the keys for the debug and release targets in src/debug/ and src/release/. --> <meta-data android:name="com.google.android.geo.API_KEY" android:value="@string/google_maps_key" /> <activity android:name=".MapsActivity" android:label="@string/title_activity_maps"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Thanks for this. God bless you.
Welcome 🙂
This app will show live location??
Yes, it will show live location.
Good Luck
Programmer World
–
Hello, it is great, but how to track another phone through phone number please give me hint.
For tracking, you can either follow the steps shown in this video or you can refer to the below link:
https://programmerworld.co/android/how-to-track-your-location-using-gps-and-send-it-over-sms-in-your-andoid-app-complete-source-code/
I assume you have seen both the pages as I can see your comments in both the pages. If you are facing any specific issue or error then please post it here.
Good Luck
Programmer World
–
Is there any way we could retrieve the data from firebase and plot it realtime?
I think that’s exactly what is shown in this tutorial. The location coordinates is stored in the Firebase database. And on any data change in the Firebase database, the location information is retrieved and marked on the map. Refer to the below lines in the code in the addValueEventListener of the databasereference object:
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
try {
String databaseLatitudeString = dataSnapshot.child(“latitude”).getValue().toString().substring(1, dataSnapshot.child(“latitude”).getValue().toString().length()-1);
String databaseLongitudedeString = dataSnapshot.child(“longitude”).getValue().toString().substring(1, dataSnapshot.child(“longitude”).getValue().toString().length()-1);
String[] stringLat = databaseLatitudeString.split(“, “);
Arrays.sort(stringLat);
String latitude = stringLat[stringLat.length-1].split(“=”)[1];
String[] stringLong = databaseLongitudedeString.split(“, “);
Arrays.sort(stringLong);
String longitude = stringLong[stringLong.length-1].split(“=”)[1];
LatLng latLng = new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude));
mMap.addMarker(new MarkerOptions().position(latLng).title(latitude + ” , ” + longitude));
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
Hope above helps.
Cheers
Programmer World
–
please can you give me a guide or hint if I want to build a track and trace app. what the functions that it will consists of
Simple, the App should have following work-flow:
– Record the username/ unique ID of the user of the App.
– Regularly record the location coordinates in some database (as shown in this page)
– Data (location coordinates) should be saved against the username.
– Now, to trace the location, a user selection menu should be provided in the App.
– Once a user is selected then his/her last recorded location in the database should be retrieved and marked on the map.
The above steps should help.
Cheers
Programmer World
–
Thanks for the reply. please what guide or idea do have to build a trace and trace app for equine infection disease in strangle for horses.
To track any location, just use this App to store the data in the Firebase database and visualize the data (location coordinates) from the database.
Cheers
Programmer World
https://programmerworld.co
–
I would like to save some latitudes and longitudes as trusted Locations. Hence after that I can make sure that I am in trusted location or not. is this possible? if yes, then please provide me coding of that requirement. Thank you
I think it can simply be done by creating the database structure with node of “trusted” locations and storing the coordinates within it. Something like below would help:
databaseReference.child(“trusted”).child(“latitude”).push().setValue(editTextLatitude.getText().toString());
databaseReference.child(“trusted”).child(“longitude”).push().setValue(editTextLongitude.getText().toString());
And while fetching these trusted values, below code can be used:
dataSnapshot.child(“trusted”).child(“latitude”).getValue()
dataSnapshot.child(“trusted”).child(“longitude”).getValue()
Cheers
Programmer World
–