Bus Assistant
This project is an addition or sub-project of BVRIT Bus Tracker, the functionality of this app is to fetch the location of bus (through the GPS of BUS driver’s mobile), latitude, longitude and update it in the Firebase Realtime Database as a data-model
-
Permissions
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET"/>
-
Activities
- MainActivity it is the launcher activity of our app, initially checks if there is authentication provided, if not authenticated, it pops-up a screen asking to choose bus number. After continuing with this process, it automatically fetches the registered number of bus driver and sends an otp to his mobile, he has to enter that to get authenticated
Code checking if authentication is provided
if(FirebaseAuth.getInstance().getCurrentUser() != null){
startActivity(new Intent(MainActivity.this, StartService.class));
finish();
}
if authentication is provided or user verified with code, it redirects to StartService Activity…
- Authentication Activity, this activity is all about verifying the user, as shown in above screens, it sends an OTP generated by Firebase Auth to the registered mobile number. Once verification is done, it fetches the token of verification and stores the data as a client model inf Firebase Database, so that BVRIT Bus Tracker app can track the bus using that client id.
- Tracking Service Activity, as shown in the screenshots, this is standalone screen that does the whole work of our purpose, it uses GPS and internet connection to fetch the location of the device and store it in the database
Let me explain the work done by this activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start_service);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setTitle("Bus Tracker Assistant");
actionBar.hide();
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Please wait...");
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
clientData = FirebaseDatabase.getInstance().getReference().child("Clients");
clientData.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot d : dataSnapshot.getChildren() ){
ClientDataModel cm = d.getValue(ClientDataModel.class);
if (FirebaseAuth.getInstance().getUid().equals(cm.getUid())){
index = Integer.parseInt(cm.getIndex());
progressDialog.dismiss();
break;
}
}
progressDialog.dismiss();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
routeCode = getResources().getStringArray(R.array.codes);
phones = getResources().getStringArray(R.array.numbers);
databaseReference = FirebaseDatabase.getInstance().getReference().child("Bus Tracker").child(routeCode[index]);
start = findViewById(R.id.serviceStartSwitch);
lastUpdateTextView = findViewById(R.id.lastupdate);
locationTextView = findViewById(R.id.locationPresent);
latitudeTextView = findViewById(R.id.latitude);
longitudeTextView = findViewById(R.id.longitude);
routeTextView = findViewById(R.id.routeCodeT);
nearbyPlaces = findViewById(R.id.nearby);
start.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b){
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
startMyService();
}else {
stopMyService();
}
}
});
progressDialog.dismiss();
}
-
Let’s split it up
- Initializing a location managet object
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
- Checking the database if the client is registered to avoid spam, if client is real(registered) we will get the id of the client to perform further actions
clientData = FirebaseDatabase.getInstance().getReference().child("Clients");
clientData.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot d : dataSnapshot.getChildren() ){
ClientDataModel cm = d.getValue(ClientDataModel.class);
if (FirebaseAuth.getInstance().getUid().equals(cm.getUid())){
index = Integer.parseInt(cm.getIndex());
progressDialog.dismiss();
break;
}
}
progressDialog.dismiss();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});

- Using the id we have got from database, we are initializing string resources and getting reference to save tracking instance data by creating a tree there in the database
routeCode = getResources().getStringArray(R.array.codes);
phones = getResources().getStringArray(R.array.numbers);
databaseReference = FirebaseDatabase.getInstance().getReference().child("Bus Tracker").child(routeCode[index]);
- As the user turns on the tracking service this method gets executed, re-intialising the location manager with system service
private void startMyService(){
if (ContextCompat.checkSelfPermission(StartService.this, "android.permission.ACCESS_FINE_LOCATION")!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(StartService.this,
"android.permission.ACCESS_FINE_LOCATION")) {
} else {
ActivityCompat.requestPermissions(StartService.this,
new String[]{"android.permission.ACCESS_FINE_LOCATION","android.permission.ACCESS_COARSE_LOCATION"},
1);
}
}else {
Toast.makeText(getApplicationContext(),"GPS Permission Granted",Toast.LENGTH_SHORT).show();
}
progressDialog.show();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000, 100, mLocationListener);
}
- The location listener service, the functionality of this is to continously check for location changes locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000, 100, mLocationListener); for this line of code in the startService() method, here I have taken for 60000 milliseconds and 10 meters distance, after this span, it fetches tha latitude, longitude and updates in the database as a DataModel. Using DateFormat function we will get the appropriate date & time, using Geocoder function
private final LocationListener mLocationListener = new LocationListener() {
@Override
public void onLocationChanged(final Location location) {
if (progressDialog.isShowing())
progressDialog.dismiss();
locationGlobal = location;
LatLng sydney = new LatLng(location.getLatitude(),location.getLongitude());
DataModel dataModel = new DataModel();
dataModel.setLongitude(String.valueOf(location.getLongitude()));
longitudeTextView.setText(String.valueOf(location.getLongitude()));
dataModel.setLatitude(String.valueOf(location.getLatitude()));
latitudeTextView.setText(String.valueOf(location.getLatitude()));
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss yyyy/MM/dd");
Date date = new Date();
dataModel.setLastSeen(dateFormat.format(date));
lastUpdateTextView.setText(dateFormat.format(date));
dataModel.setRouteCode(String.valueOf(routeCode[index]));
routeTextView.setText(String.valueOf(routeCode[index]));
dataModel.setPhone(String.valueOf(phones[index]));
Geocoder gcd = new Geocoder(getApplicationContext(), Locale.getDefault());
try {
addresses = gcd.getFromLocation(location.getLatitude(), location.getLongitude(), 10);
} catch (IOException e) {
e.printStackTrace();
}
if (addresses.size() > 0) {
dataModel.setPresentLocation(addresses.get(0).getLocality());
locationTextView.setText(addresses.get(0).getLocality());
String nearbyplacesString="";
for (int i = 1 ; i<addresses.size();i++) {
if (addresses.get(i).getLocality()!=null)
nearbyplacesString += addresses.get(i).getLocality() + "\n";
}
nearbyPlaces.setText(nearbyplacesString);
dataModel.setNearbyPlaces(nearbyplacesString);
}
else {
dataModel.setPresentLocation("Unknown Location");
}
databaseReference.setValue(dataModel);
}
That’s it now we are done
.png)
Comments
Post a Comment