I need to draw a path on the map. To do so, i thought about using Polyline since the new google maps. My problem is that my application works, but it doesnt draw a thing on the map. I want it to draw everytime i change position, basically to draw my path.
public class MapActivity extends FragmentActivity implements LocationListener {
GoogleMap myMap;
Location lastLocation;
private LocationManager locManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_layout);
myMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean networkEnabled = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!networkEnabled) {
Toast.makeText(this, "network not enabled", 0);
}
}
#Override
protected void onResume() {
super.onResume();
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
}
#Override
public void onLocationChanged(Location location) {
if (location != null) {
lastLocation=locManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Polyline line=myMap.addPolyline(new PolylineOptions().add(new LatLng(location.getLatitude(),location.getLongitude())).color(Color.RED));
}
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Lines require a minimum of two points. You are attempting to draw a line using only a single point. This will draw an infinitely small line, which you will have difficulty seeing, since it is infinitely small.
If you want to draw a line, use two or more points. If you want to draw something at a single point, use a marker, not a polyline.
Related
I am working on an Android application in which I would like to display the users immediate location, not when the location has changed. Also, I would like to mark the area with a circle as soon as location is determined by zooming in. Unfortunately, the code is only working when location is changed. I tried the code sitting on my desk, and it doesn't work, but when I am walking around, it did work. What should I do.
Here is the code :
public class MapsActivityFragment extends FragmentActivity implements LocationListener {
private MapAreaManager circleManager;
static GoogleMap googleMap;
LocationManager locationManager;
String provider;
double longitude, latitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_maps_activitiy);
SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.googleMap);
googleMap = fm.getMap();
googleMap.setMyLocationEnabled(true);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
setUpMapIfNeeded();
onLocationChanged(location);
}
}
private void setUpMapIfNeeded() {
if (googleMap == null) {
googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.googleMap)).getMap();
if (googleMap != null) {
setupMap();
}
}
}
#Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(provider, 400, 0, this);
}
#Override
public void onLocationChanged(Location location) {
googleMap.clear();// clean the map
Toast.makeText(this, "Location Changed", Toast.LENGTH_SHORT).show();
setUpMapIfNeeded();
}
#Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String arg0) {
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
setUpMapIfNeeded();
}
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
private void setupMap() {
circleManager = new MapAreaManager(googleMap,
4, Color.RED, Color.HSVToColor(70, new float[] {1, 1, 200}), //styling
R.drawable.move, R.drawable.resize, //custom drawables for move and resize icons
0.5f, 0.5f, 0.5f, 0.5f, //sets anchor point of move / resize drawable in the middle
new MapAreaMeasure(100, MapAreaMeasure.Unit.pixels), //circles will start with 100 pixels (independent of zoom level)
new MapAreaManager.CircleManagerListener() { //listener for all circle events
#Override
public void onResizeCircleEnd(MapAreaWrapper draggableCircle) {
Toast.makeText(MapsActivityFragment.this, "do something on drag end circle: " + draggableCircle, Toast.LENGTH_SHORT).show();
}
#Override
public void onCreateCircle(MapAreaWrapper draggableCircle) {
Toast.makeText(MapsActivityFragment.this, "do something on crate circle: " + draggableCircle, Toast.LENGTH_SHORT).show();
}
#Override
public void onMoveCircleEnd(MapAreaWrapper draggableCircle) {
Toast.makeText(MapsActivityFragment.this, "do something on moved circle: " + draggableCircle, Toast.LENGTH_SHORT).show();
}
#Override
public void onMoveCircleStart(MapAreaWrapper draggableCircle) {
Toast.makeText(MapsActivityFragment.this, "do something on move circle start: " + draggableCircle, Toast.LENGTH_SHORT).show();
}
#Override
public void onResizeCircleStart(MapAreaWrapper draggableCircle) {
Toast.makeText(MapsActivityFragment.this, "do something on resize circle start: " + draggableCircle, Toast.LENGTH_SHORT).show();
}
#Override
public void onMinRadius(MapAreaWrapper draggableCircle) {
Toast.makeText(MapsActivityFragment.this, "do something on min radius: " + draggableCircle, Toast.LENGTH_SHORT).show();
}
#Override
public void onMaxRadius(MapAreaWrapper draggableCircle) {
Toast.makeText(MapsActivityFragment.this, "do something on max radius: " + draggableCircle, Toast.LENGTH_LONG).show();
}
});
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 6));
}
}
I have changed a bit of circle marking and using this library for the same. Any help would be nice. Thanks a lot.
If your device never had a decent GPS fix, the getLastKnownLocation(...)method probably returns null. When I acquired my first GPS fix outside, I had my app working fine inside my room and also after restarting my app.
Hie i tried to implement this codes in my application but it doesnt work , i dont know where i went wrong.
basically, when i launch the sample of the device location. it doesnt show me where is my current location and i dont see any blue dots that resembles the current location i am at.
the only thing that i see is the map . just a plain zoom out map.
I would be really thankful if someone who could help me out on how to get the current location with the blue dots that is displayed on the map..
this is my MainActivity.class
public class HelloWorld extends Activity {
MapView mMapView = null;
ArcGISTiledMapServiceLayer tileLayer;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Retrieve the map and initial extent from XML layout
mMapView = (MapView) findViewById(R.id.map);
mMapView.addLayer(new ArcGISTiledMapServiceLayer(
"http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"));
mMapView.setOnStatusChangedListener(new OnStatusChangedListener() {
public void onStatusChanged(Object source, STATUS status) {
if (source == mMapView && status == STATUS.INITIALIZED) {
LocationService ls = mMapView.getLocationService();
ls.setAutoPan(false);
ls.start();
}
}
});
}
protected void onPause() {
super.onPause();
mMapView.pause();
}
#Override
protected void onResume() {
super.onResume();
mMapView.unpause();
}
}
this is a code that draws my location every 1 second via provider and GPS .
let's first declare variables :
private GraphicsLayer myGraphicalLayer;
MapView mMapView;
ArcGISLocalTiledLayer baseLayer;
private LocationManager mlocManager;
private LocationListener mlocListener;
in onCreate function WE CALL LocationListener:
mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, mlocListener);
mlocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, mlocListener);
// loading the map
mMapView = (MapView) findViewById(R.id.localMap);
baseLayer = new ArcGISLocalTiledLayer(basemapurl);
mMapView.addLayer(baseLayer);
// defining my position layer
myGraphicalLayer = new GraphicsLayer();
then a function to draw my location :
private void SetMyLocationPoint(final double x, final double y) {
PictureMarkerSymbol myPin = new PictureMarkerSymbol(getResources().getDrawable(
R.drawable.mylocation_icon));
Point wgspoint = new Point(x, y);
Point mapPoint = (Point) GeometryEngine.project(wgspoint, SpatialReference.create(4326),
mMapView.getSpatialReference());
Graphic myPinGraphic = new Graphic(mapPoint, myPin);
try {
myGraphicalLayer.removeAll();
} catch (Exception e) {
e.printStackTrace();
}
myGraphicalLayer.addGraphic(myPinGraphic);
myGraphicalLayer.setVisible(true);
mMapView.addLayer(myGraphicalLayer);
}
make internal class that implements MyLocationListener to get you instant location, and let it call the function named SetMyLocationPoint like this way :
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
SetMyLocationPoint(loc.getLongitude(), loc.getLatitude());
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(getApplicationContext(), "provider enabled", Toast.LENGTH_SHORT)
.show();
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(getApplicationContext(), "provider disabled", Toast.LENGTH_SHORT)
.show();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
You need to use your own location manager or the location client to get the device's current location and then you will have to add that point on the map.
Your map should be in a MapFragment.
Get the googleMap object from the fragment and then add your custom blue dot on it.
LocationManager locationManager = (LocationManager) getApplicationContext()
.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
5000, 5, listener);
}
private LocationListener listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
Log.e("Google", "Location Changed");
if (location == null)
return;
Log.e("latitude", location.getLatitude() + "");
Log.e("longitude", location.getLongitude() + "");
}
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
};
The above code gets you the location in onLocationChanged method.
Note: i have used GPS_PROVIDER to get the location.
There are other ways to get the current location too.
I am testing the option to send coordinates to the Android Emulator using the Built in Eclipse tool.But it doesn't seem to receive them.I have this simple code:
public class Main extends MapActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapView view = (MapView) findViewById(R.id.themap);
view.setBuiltInZoomControls(true);
final MapController mp = view.getController();
LocationManager manager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
LocationListener listener = new LocationListener() {
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onLocationChanged(final Location location) {
// TODO Auto-generated method stub
mp.setCenter(new GeoPoint((int)location.getLatitude(), (int)location.getLongitude()));
}
};
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
I have the permissions for ACCESS_FINE_LOCATION and INTERNET in the Manifest.
If someone has any explanation I would be grateful.
Did you add
<uses-library android:name="com.google.android.maps" />
to the application tag in the manifest?
You also need a MD5 Fingerprint of the SDK Debug Certificate from Google to receive Google Maps data. You can get it here.
Try to put a breakpoint inside the onLocationChanged method and see if it stops when sending the location command to the emulator. this should also work when you don't have a certificate yet.
This works for me.
Listener implementation...
public class MyLocationListener implements LocationListener {
public static final String TAG = "MyLocationListener";
private Context context;
public MyLocationListener(Context c) {
this.context = c;
}
public void onLocationChanged(android.location.Location location) {
Log.d(TAG,"LocationChanged: Lat: "+location.getLatitude()+" Lng: "+location.getLongitude());
}
}
Usage...
MyLocationListener locationListener = new MyLocationListener(this);
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,locationListener);
i'm new in java/android app and i'm creating an app that uses user-location. I want the location to be updated at the begining of the app.
The problem is that my location class is an activity and i don't want to show another contentview for this class.
Actually, i want the location thing to be done in background, without changing the UI, in a separated class.
Is it possible? How?
Thanks :P
There is no need to put the location in a different activity, the LocationManager already does it in the background:
public void getLocation(){
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
gpsLocationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onLocationChanged(Location location) {
//do something with the new location
if (location != null)
gpsLocation = location;
}
};
gpsLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 0, gpsLocationListener);
}
Using the LocationManager you should be able to use what ever kind of activity (or service) you want.
Hi I am New to android programming and currently developing an application that uses location manager to get user location and place a marker on a map. i am attempting to use AsyncTask to run the LocationListener and Constantly update the marker when the user location has changed.
this is the class i am working on...
public class IncidentActivity extends MapActivity{
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.setContentView(R.layout.incidentactivity);
mapView = (MapView)findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
mapView.setTraffic(true);
mapController = mapView.getController();
String coordinates[] = {"-26.167004","27.965505"};
double lat = Double.parseDouble(coordinates[0]);
double lng = Double.parseDouble(coordinates[1]);
geoPoint = new GeoPoint((int)(lat*1E6), (int)(lng*1E6));
mapController.animateTo(geoPoint);
mapController.setZoom(16);
mapView.invalidate();
new MyLocationAsyncTask().execute();
}
private class MyLocationAsyncTask extends AsyncTask<Void, Location, Void> implements LocationListener{
private double latLocation;
private Location l;
//location management variables to track and maintain user location
protected LocationManager locationManager;
protected LocationListener locationListener;
#Override
protected Void doInBackground(Void... arg0) {
Looper.prepare();
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 1, locationListener);
this.publishProgress(l);
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Location... values) {
super.onProgressUpdate(values);
}
//this method is never executed i dont know why...?
public void onLocationChanged(Location location) {
if (location != null){
latLocation = location.getLatitude();
Toast.makeText(getBaseContext(), " Your latLocation :" + latLocation, Toast.LENGTH_LONG).show();
//Log.d("Your Location", ""+latLocation);
}
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
}
I've just implemented such AsyncTask:
class GetPositionTask extends AsyncTask<Void, Void, Location> implements LocationListener
{
final long TWO_MINUTES = 2*60*1000;
private Location location;
private LocationManager lm;
protected void onPreExecute()
{
// Configure location manager - I'm using just the network provider in this example
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this);
nearProgress.setVisibility(View.VISIBLE);
}
protected Location doInBackground(Void... params)
{
// Try to use the last known position
Location lastLocation = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
// If it's too old, get a new one by location manager
if (System.currentTimeMillis() - lastLocation.getTime() > TWO_MINUTES)
{
while (location == null)
try { Thread.sleep(100); } catch (Exception ex) {}
return location;
}
return lastLocation;
}
protected void onPostExecute(Location location)
{
nearProgress.setVisibility(View.GONE);
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.removeUpdates(this);
// HERE USE THE LOCATION
}
#Override
public void onLocationChanged(Location newLocation)
{
location = newLocation;
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
}
From what I have read and tried, you cannot use a looper (which is needed by the locationlistener), inside an ASyncTask. Click Here
Actually it mean the two threading models are not compatible, so you can't
use these together. Looper expects to to own the thread that you associate
it with, while AsyncTask owns the thread it creates for you to run in the
background. They thus conflict with each other, and can't be used together.
Dianne Hackborn suggested using a HandlerThread, but I succeeded in getting mine to work inside of an IntentService. I will admit that my code is still a bit of a hack.