I'm trying to draw a path on google maps while moving from my location.
For this I have created a google map activity and a gps service running on background but when I try to run the application I can see my location changed but the route is not showing.
public class HomeActivity extends AppCompatActivity
implements OnMapReadyCallback, NavigationView.OnNavigationItemSelectedListener {
SessionManager session;
private User user;
private ImageView profileImage;
Bitmap bitmap;
TextView user_name, user_email;
ImageView user_picture;
NavigationView navigation_view;
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
//UI elements
private TextView txtDuration;
private TextView txtDistance;
private Button btnStart;
private Button btnStop;
//kep track if the activity started
private boolean isStarted = false;
//location manager
private LocationManager locManager;
//location listener
private LocationListener myLocationListener;
//route object
private Route route = null;
//list of route coordinates
private List<Coordinate> coordinates = null;
//coordinate object
private Coordinate coordinate = null;
//starting point location
private Location startLocation;
//location service
private Getlocation locationService;
//intent to start location service
private Intent serviceIntent;
//keep track if we are bound to the service
private boolean serviceBound = false;
private final String TAG = "walk";
//minimum time between updates in milliseconds
private static long MIN_TIME = 1000 * 1 * 3; // 3 seconds
//polyline options
private PolylineOptions polylineOptions;
//polyline
private Polyline polyline;
//list of LatLng objects
private List<LatLng> path = new ArrayList<LatLng>();
//broadcast receiver
private BroadcastReceiver receiver;
//average speed
private double avSpeed = 0.0;
//flag for gps enabled status
private boolean isGPSEnabled = false;
//map type
private int MAP_TYPE = GoogleMap.MAP_TYPE_NORMAL;
//route colour
private int ROUTE_COLOUR = Color.BLUE;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Run");
// btnStart = (Button) findViewById(R.id.btn_start);
Intent intent = getIntent();
String jsondata = intent.getStringExtra("jsondata");
setNavigationHeader(); // call setNavigationHeader Method.
setUserProfile(jsondata); // call setUserProfile Method.
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
navigation_view.setNavigationItemSelectedListener(this);
//get reference to UI elements
btnStart = (Button) findViewById(R.id.btn_start_activity);
btnStop = (Button) findViewById(R.id.btn_stop);
txtDuration = (TextView) findViewById(R.id.txt_duration);
txtDistance = (TextView) findViewById(R.id.txt_distance);
//if walking session is not running set duration text to default value
if (!isStarted)
txtDuration.setText("00:00:00");
locManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
isGPSEnabled = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
bindToService();
//set UI elements visibility
setVisibility();
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
moveTaskToBack(true);
}
}
/*
Set Navigation header by using Layout Inflater.
*/
public void setNavigationHeader(){
navigation_view = (NavigationView) findViewById(R.id.nav_view);
View header = LayoutInflater.from(this).inflate(R.layout.nav_header_home, null);
navigation_view.addHeaderView(header);
user_name = (TextView) header.findViewById(R.id.username);
user_picture = (ImageView) header.findViewById(R.id.profile_pic);
user_email = (TextView) header.findViewById(R.id.email);
}
/*
Set User Profile Information in Navigation Bar.
*/
public void setUserProfile(String data){
user = PrefUtils.getCurrentUser(HomeActivity.this);
session = new SessionManager(getApplicationContext());
HashMap<String, String> userpm = session.getUserDetailsfb();
String imgurl = userpm.get(SessionManager.KEY_IMGURL);
user_email.setText(userpm.get(SessionManager.KEY_EMAIL));
user_name.setText(userpm.get(SessionManager.KEY_NAME));
// new LoadProfileImage(user_picture).execute(imgurl);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.home, menu);
getMenuInflater().inflate(R.menu.menu_session, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_parcours) {
} else if (id == R.id.nav_historique) {
} else if (id == R.id.nav_friends) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_logout) {
PrefUtils.clearCurrentUser(HomeActivity.this);
// We can logout_layout from facebook by calling following method
LoginManager.getInstance().logOut();
Intent i = new Intent(HomeActivity.this, MainActivity.class);
startActivity(i);
finish();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
/**
* connect to the service
*/
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Getlocation.LocationBinder binder = ( Getlocation.LocationBinder) service;
//get service
locationService = binder.getService();
Log.e(TAG, "on service connected, bound is: " + serviceBound + " service: " + locationService + " intent: " + serviceIntent);
}
//the following gets called when connection with service gets unexpectidly disconnected
@Override
public void onServiceDisconnected(ComponentName name) {
locationService = null;
serviceBound = false;
}
};
/**
* bind to service to access its public methods
*/
private void bindToService() {
Log.e(TAG, "binding to service, bound is: " + serviceBound + " service: " + locationService + " intent: " + serviceIntent);
//if intent is not created
if (serviceIntent == null) {
//create intent
serviceIntent = new Intent(this, Getlocation.class);
}
//start service
startService(serviceIntent);
//bind to service
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
serviceBound = true;
Log.e(TAG, "after, bound is: " + serviceBound + " service: " + locationService + " intent: " + serviceIntent);
}
/**
* set click listeners for UI elements
*/
private void setListeners() {
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//activity started
isStarted = true;
//set UI elements visibility
setVisibility();
//start tracking
startTracking();
//}
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//activity stopped - reset flags
isStarted = false;
Log.e(TAG, "stop clicked, started: " + isStarted );
//set UI elements visibility
setVisibility();
//stop tracking
stopTracking();
//show history
}
});
}
/**
* set UI elements visibility
*/
private void setVisibility() {
Log.e(TAG, "set visible, started: " + isStarted );
//if activity is started
if (isStarted) {//show activity controls
findViewById(R.id.activity_controls).setVisibility(View.VISIBLE);
//hide start activty button
findViewById(R.id.btn_start_activity).setVisibility(View.INVISIBLE);
//toggle lock button appearance depending on its status
} else {//if activity is stopped or the app is just loaded
//hide activity controls
findViewById(R.id.activity_controls).setVisibility(View.INVISIBLE);
//show start activity button
findViewById(R.id.btn_start_activity).setVisibility(View.VISIBLE);
}
setActionBarVisibility();
}
@Override
protected void onResume() {
super.onResume();
if (!serviceBound && isStarted)
bindToService();
setActionBarVisibility();
//get location updates from receiver
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//Log.e(TAG,"on recieve");
Bundle b = intent.getExtras();
final Location loc = (Location) b.get(android.location.LocationManager.KEY_LOCATION_CHANGED);
Location loc2 = (Location)b.getParcelable("location");
//Log.e(TAG, "on recieve, loc:" + loc + " loc2(extra)" + loc2);
//get corresponding values from service (distance, speed, location)
final String distance = String.format("%.2f", locationService.getDistance());
final double distanceKm = Double.parseDouble(distance);
//if location is not null - add new value to list of LatLng objects
if (loc != null) {
path.add(getLatLng(loc));
}
runOnUiThread(new Runnable() {
@Override
public void run() {
//update route info on display
txtDistance.setText(distance);
updateCamera(loc);
updatePolyline(loc);
}
});
}
};
setUpMapIfNeeded();
setListeners();
Log.e(TAG, "on resume, bound: " + serviceBound + " started: " + isStarted );
}
@Override
protected void onStart() {
super.onStart();
if (!serviceBound && isStarted)
bindToService();
//LocalBroadcastManager.getInstance(this).registerReceiver((receiver),
// new IntentFilter(LocationService.LOCATION_UPDATE));
Log.e(TAG, "on start, bound: " + serviceBound);
}
@Override
protected void onStop() {
Log.e(TAG, "on stop, bound: " + serviceBound);
if (serviceBound)
unbindFromService();
super.onStop();
Log.e(TAG, "on stop, bound: " + serviceBound);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(TAG, "on destroy, bound: " + serviceBound);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.e(TAG, "on new intent, bound: " + serviceBound + " intent: " + intent);
if (!serviceBound)
bindToService();
setActionBarVisibility();
}
/**
* unbind from service
*/
private void unbindFromService() {
if (serviceBound) {
unbindService(serviceConnection);
serviceBound = false;
}
}
private void setUpMapIfNeeded() {
Log.e(TAG, "in setup map if needed, map: " + mMap);
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map_view))
.getMap();
//Map Settings
mMap.getUiSettings().setMyLocationButtonEnabled(true);
mMap.getUiSettings().setCompassEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
//map type
mMap.setMapType(MAP_TYPE);
// Check if we were successful in obtaining the map.
if (mMap != null) {
mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
Log.e(TAG, "map loaded");
setUpMap();
}
});
}
}
}
// initialise map to reflect current position
private void setUpMap() {
//initialise polyline options
polylineOptions = new PolylineOptions();
//path colour from shared preferences
polylineOptions.color(ROUTE_COLOUR).width(4);
//check if GPS is enabled on the device
if (!isGPSEnabled) {
//if GPS is off - show warning
gpsOffAlert();
} else {//if GPS is on
//get current location
Location location = getLastKnownLocation();
Log.e(TAG, "in setup map, location: " + location);
//if such location exists/registered - update camera position
if (location != null) {
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(getLatLng(location), 16));
Log.e(TAG, "in setup map, found last location, location: " + location);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#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 ActivityCompat#requestPermissions for more details.
return;
}
mMap.setMyLocationEnabled(true);
//set route start location
setStartLocation(location);
//draw initial polyline
polyline = mMap.addPolyline(polylineOptions.add(getLatLng(location)));
//add first element to list of LatLng objects
if (path.size() == 0)
path.add(getLatLng(location));
}
}
//}
}
/**
* show alert dialog if gps is off
*/
public void gpsOffAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
// Setting Dialog Title
alertDialog.setTitle("GPS is off");
// alert dialog message
alertDialog.setMessage("GPS is off. This application requires enabled GPS to function. Do you want to go to settings menu and activate GPS?");
// open settings menu on button press
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
HomeActivity.this.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
finish();
//context.startActivity(new Intent(context,MainActivity.class));
}
});
//show alert
alertDialog.show();
}
/**
* get last known location querying all available providers
* @return location
*/
private Location getLastKnownLocation() {
//locManager = (LocationManager)getApplicationContext().getSystemService(LOCATION_SERVICE);
List<String> providers = locManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Location loc = locManager.getLastKnownLocation(provider);
return loc;
}
Location loc = locManager.getLastKnownLocation(provider);
Log.e(TAG, "provider found: " + provider + " location: " + loc);
if (loc == null) {
continue;
}
if (bestLocation == null || loc.getAccuracy() < bestLocation.getAccuracy()) {
// Found best last known location: %s", l);
bestLocation = loc;
}
}
return bestLocation;
}
@Override
public void onMapReady(GoogleMap googleMap) {
Log.e(TAG, "on map ready ");
mMap = googleMap;
setUpMap();
}
/**
* start walking activity tracking
*/
private void startTracking() {
//ensure we are bound to service
if (!serviceBound)
bindToService();
//get time now
String routeStartTime = Utils.getCurrentTimeStringShort();
//instantiate route object
route = new Route();
//get today's date in different formats (long, short)
String routeName = Utils.getFullDateString();
String routeDate = Utils.getShortDateString();
//set corresponding route values
route.setName(routeName);
route.setDate(routeDate);
route.setStartTime(routeStartTime);
//instantiate coordinates list
coordinates = new ArrayList<Coordinate>();
//if there is a starting point for the route
if (getStartLocation() != null) {
//add that location to list of coordinates
addPoint(getStartLocation());
}
if (coordinates.size() > 0) {
route.setStartPoint(coordinates.get(0));
}
//double check that we are bound to the service
if (serviceBound) {
//start tracking
locationService.startTracking(isStarted);
}
//register receiever for location updates
LocalBroadcastManager.getInstance(this).registerReceiver((receiver),
new IntentFilter( Getlocation.LOCATION_UPDATE));
}
/**
* stop tracking
*/
private void stopTracking() {
//get session duration
String routeDuration = txtDuration.getText().toString();
//get finish time
String routeFinishTime = Utils.getCurrentTimeStringShort();
// Log.e(TAG,"stopping session, coordinate size: "+coordinates.size());
//set route duration and finish time
route.setFinishTime(routeFinishTime);
route.setDuration(routeDuration);
route.setDistance(txtDistance.getText().toString());
//get reference to db
RoutesDBHelper.init(HomeActivity.this);
//insert route object to db
long routeId = RoutesDBHelper.createRoute(route);
Log.e(TAG, "route id: " + routeId);
//read list of coordinates for the route
coordinates = locationService.getCoordinates();
//if we have at least two coordinates for the route
if (coordinates.size() > 1) {
//set start and finish point from coordinates list
route.setFinishPoint(coordinates.get(coordinates.size() - 1));
route.setStartPoint(coordinates.get(0));
}//if there is only one coordinate for the route
else if (coordinates.size() == 1) {
//set start and finish points
route.setFinishPoint(coordinates.get(0));
route.setStartPoint(coordinates.get(0));
}
//insert list of coordinates to db
RoutesDBHelper.createCoordinates(coordinates, routeId);
//}
//stop tracking
locationService.stopTracking(isStarted);
//Log.e(TAG, "route: " + route);
//Log.e(TAG,"coordinates: "+coordinates);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#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 ActivityCompat#requestPermissions for more details.
return;
}
mMap.setMyLocationEnabled(false);
//if bound to service
if(serviceBound){
//stop service and unbind
stopService(serviceIntent);
unbindService(serviceConnection);
serviceBound = false;
}
//unregister receiever
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}
public Location getStartLocation() {
return startLocation;
}
public void setStartLocation(Location startLocation) {
this.startLocation = startLocation;
}
private void addPoint(Location location){
//provided location is not null
if(location!=null) {
//add new coordinate to the list of coordinates
Coordinate point = new Coordinate(location.getLatitude(), location.getLongitude(), location.getAltitude(), location.getSpeed());
coordinates.add(point);
}
}
private void updatePolyline(Location location){
polyline.setPoints(path);
Log.e(TAG, "setting points with loc: " + path);
}
private void updateCamera(Location location){
Log.e(TAG, "updating camera with loc: " + location);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
//include route points to the boundary builder
for (LatLng latLng : path) {
builder.include(latLng);
}
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 30));
}
private LatLng getLatLng(Location location){
return new LatLng(location.getLatitude(), location.getLongitude());
}
public Coordinate getStartPoint(){
return new Coordinate(getStartLocation().getLatitude(),getStartLocation().getLongitude());
}
private void setActionBarVisibility(){
if(isStarted)
getSupportActionBar().hide();
else
getSupportActionBar().show();
}
This is what I do and it works for me: I create a Google Api Client and implement LocationListener
Every time a new Location is detected, I add the latest LatLng point to my Polyline.