I followed Google's Map View tutorial from this link http://developer.android.com/resources/tutorials/views/hello-mapview.html
I've done the first about Creating Map activity, but have problems with Adding Overlays. Here is the source code:
package rs.iz.stevy.wifi;
import java.util.ArrayList;
import android.graphics.drawable.Drawable;
import android.app.AlertDialog;
import android.content.Context;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;
public class Overlay extends ItemizedOverlay {
public Overlay(Drawable defaultMarker, Context context) {
super(defaultMarker);
Context mContext;
mContext = context;
}
private ArrayList<OverlayItem>mOverlays= new ArrayList<OverlayItem>();
public Overlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
#Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i); }
#Override
public int size() {
return mOverlays.size();
}
#Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
}
Error appear at this line:
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
Eclipse shows mContext cannot be resolved to variable.
Here is the Activity class:
rs.iz.stevy.wifi;
import java.util.List;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
public class WiFiKupacicaActivity extends MapActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapView mapa= (MapView) findViewById(R.id.Mapa1);
mapa.setBuiltInZoomControls(true);
mapa.setSatellite(true);
GeoPoint initGeoPoint = mapa.getMapCenter();
List<Overlay> mapOverlays = mapa.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.kupacica);
Overlay itemizedoverlay = new Overlay (drawable);
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
Eclipse show error Cannot instantiate Overlay at this line:
Overlay itemizedoverlay = new Overlay (drawable);
If you see here any error that can be easily fixed please answer cause this are my first attempts to write an android app.
The first error is because you defined mContext as a local variable in the constructor instead of as an instance variable. To remedy, move the Context mContext; line out of the constructor (put it right before this line public Overlay(Drawable defaultMarker, Context context) {). You want to declare instance variables outside of any method, but inside the class itself.
Your second error occurs because Overlay is an Abstract class. You cannot instantiate an abstract class with "new". What you want to do here is instantiate your Overlay subclass. In your import statements, you're importing com.google.android.maps.Overlay so it thinks you're instantiating that rather than your subclass. To fix, replace
Overlay itemizedoverlay = new Overlay (drawable);
with
rs.iz.stevy.wifi.Overlay itemizedoverlay = new rs.iz.stevy.wifi.Overlay (drawable);
In practice, you should avoid giving a class the name of an abstract class already in its own hierarchy (to avoid import errors like this).
Related
I am developing an application where I want to plot latitudes and longitudes from my database on Maps. In my database schema I have three columns:
Name | Latitude | Longitude
I can retrieve the data from SQLite in an ArrayList, but the problem I am facing is how should I go about visualizing these values on a Google Map along with the name of the location as stored in the database? Also, how can I draw a path from the start geopoint to the end geopoint.
I got my code working by creating an itemized overlay class
package com.rahul.besttracker;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;
public class HelloItemizedOverlay extends ItemizedOverlay {
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
Context mContext;
public HelloItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
// TODO Auto-generated constructor stub
}
public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
super(boundCenterBottom(defaultMarker));
mContext = context;
}
#Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
#Override
public int size() {
return mOverlays.size();
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
#Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
}
I created an instance of this in my main class and every-time i need to add an item to overlay i called the add overlay function. finally i plotted the overlay on map
I am doing the MapView tutorial found here: https://developers.google.com/maps/documentation/android/v1/hello-mapview
The problem is that it keeps crashing. Here's the code:
package com.example.googlemapstest;
import java.util.List;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.view.Menu;
public class MainActivity extends MapActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MapView mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
List<Overlay> mapOverlays = mapView.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker);
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable, this);
GeoPoint point = new GeoPoint(19240000,-99120000);
OverlayItem overlayitem = new OverlayItem(point, "Hola, Mundo!", "I'm in Mexico City!");
drawable.setBounds(0,0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
overlayitem.setMarker(drawable);
itemizedoverlay.addOverlay(overlayitem, drawable);
mapOverlays.add(itemizedoverlay);
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
And the HelloItemizedOverlay class:
package com.example.googlemapstest;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;
public class HelloItemizedOverlay extends ItemizedOverlay
{
private ArrayList<OverlayItem> mOverlays;
Context mContext;
public HelloItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
mOverlays = new ArrayList<OverlayItem>();
populate();
}
public void addOverlay(OverlayItem overlay, Drawable drawable) {
overlay.setMarker(drawable);
mOverlays.add(overlay);
populate();
}
#Override
public int size() {
return mOverlays.size();
}
public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
super(boundCenterBottom(defaultMarker));
mContext = context;
mOverlays = new ArrayList<OverlayItem>();
populate();
}
#Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
#Override
protected OverlayItem createItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
}
The exception I keep getting is
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.googlemapstest/com.example.googlemapstest.MainActivity} : java.lang.NullPointerException
The crash happens at the populate() line in itemizedoverlay.addOverlay(overlayitem, drawable);
Now, initially I found that the mMarker variable of the OverlayItem I was adding was null, and added two lines to manually set it. However, the program still kept crashing!
I then found this question: Problem with crash with ItemizedOverlay which seemed to be dealing with the same error.
I did as recommended in the best answer there, but still no luck.
I believe I've vigourously combed this, and can't imagine where the null error is coming from. Any help is much appreciated.
I'm pretty sure you shouldn't be returning null in createItem(int index), meaning you should change the following method in your HelloItemizedOverlay class:
#Override
protected OverlayItem createItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
The most basic implementation should return the OverlayItem object appropriate for the given index. Quite probably, you'll just want to return whatever object is located in the list of OverlayItems at the same index. For example:
#Override
protected OverlayItem createItem(int index) {
return mOverlays.get(index);
}
That will only make sense if you also populate that list somewhere. Also, to avoid confusion, you should probably rename the variable to mOverlayItems, since that is what it contains (as opposed to 'overlays').
More importantly, as #ianhanniballake already mentioned: the Android Maps SDK v1 has been deprecated in favour of v2. This means that from March 3rd, 2013 you will no longer be able to request an API key for v1. Better hurry up and generate a key now, if you haven't done so yet, or just migrate to v2 now, which probably wouldn't be a bad move.
Version 1 of the Google Maps Android API as been officially deprecated as of December 3rd, 2012
Go with Google Map API V2 and make your life easy
https://developers.google.com/maps/documentation/android/
Happy coding
I have a map activity which displays the map, I want to add a marker when I touch on the screen ..
This is my Activity ...
package com.adhamenaya.android;
import java.util.List;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
public class MapApp extends MapActivity {
private MapView mapView;
private MapController mapController;
private LocationManager locationManager;
private Context context;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context=this;
initLayout();
initMap();
}
private void initLayout(){
mapView = (MapView) findViewById(R.id.mapview);
//blueIcon = (Drawable)this.getResources().getDrawable(R.drawable.blueicon);
}
private void initMap(){
mapView.setBuiltInZoomControls(true);
mapView.setStreetView(true);
mapController=mapView.getController();
mapController.setZoom(10);// 1 is world view
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0, 0, new GeoUpdateHandler());
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
class GeoUpdateHandler implements LocationListener {
#Override
public void onLocationChanged(Location location) {
int lat=(int)(location.getLatitude()*1E6);
int lng=(int)(location.getLongitude()*1E6);
GeoPoint point=new GeoPoint(lat,lng);
//GeoPoint point = new GeoPoint(19240000,-99120000);
mapController.animateTo(point);
mapController.setCenter(point);
Drawable redIcon = context.getResources().getDrawable(R.drawable.redicon);
List<Overlay> mapOverlays = mapView.getOverlays();
MyItemizedOverlay itemizedoverlay = new MyItemizedOverlay(redIcon);
OverlayItem overlayitem = new OverlayItem(point, "Hello !", "I'm here");
itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);
}
#Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
public boolean onTouchEvent(MotionEvent event){
int x=(int)event.getX();
int y=(int)event.getY();
Toast.makeText(context, x, Toast.LENGTH_LONG).show();
GeoPoint point = mapView.getProjection().fromPixels(x, y);
Drawable redIcon = context.getResources().getDrawable(R.drawable.blueicon);
List<Overlay> mapOverlays = mapView.getOverlays();
MyItemizedOverlay itemizedoverlay = new MyItemizedOverlay(redIcon);
OverlayItem overlayitem = new OverlayItem(point, "New Place", "I clicked here !");
itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);
return false;
}
}
}
Edit : This is the class for ItemizedOverlay, where I have implemented onTap() method , but nothing happens ...
package com.adhamenaya.android;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.widget.Toast;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
public class MyItemizedOverlay extends ItemizedOverlay{
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
private Context mContext;
public MyItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}
public MyItemizedOverlay(Drawable defaultMarker, Context context) {
super(defaultMarker);
mContext = context;
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
#Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
#Override
public int size() {
return mOverlays.size();
}
#Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
#Override
public boolean onTouchEvent(MotionEvent event, MapView mapView) {
int x=(int)event.getX();
int y=(int)event.getY();
Toast.makeText(mContext, x, Toast.LENGTH_LONG).show();
return super.onTouchEvent(event, mapView);
}
}
Hello, MapView! tutorial covers showing markers on MapView. In the tutorial markers are added as soon as the activity starts, but you can also add markers at later time, for example, when user touches screen. If you try this approach, you'll likely want to override onTap in your subclass of ItemizedOverlay.
Update:
If you follow the tutorial, you'll have your own subclass of ItemizedOverlay. onTap is one of its methods. Now that I look at the documentation, unfortunately onTap(GeoPoint p, MapView mapView) is not public or protected so you cannot override it.
What you can do, is have another overlay, solely for detecting taps. Instead of subclassing ItemizedOverlay, subclass Overlay.
private class TapOverlay extends Overlay {
public boolean onTap(GeoPoint p, MapView mapView) {
// code that adds item in your ItemizedOverlay
// goes here
return true;
}
}
I currently have modified 'Google Map View' code (found below) but when the map loads and you click on the item on the map it returns an error.
I believe it has something to do with the null value for mContext but I'm not sure, I would really appreciate it if anyone could help me out with this:
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
Context mContext = null;
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
My Map class:
package testing.map;
import java.util.List;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
public class Mapview extends MapActivity {
/** Called when the activity is first created. */
protected boolean isRouteDisplayed(){
return false;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mapview);
MapView mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
List<Overlay> mapOverlays = mapView.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.jd_sports_logo);
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable);
//Declared longitude/latitude as doubles as GeoPoint only uses 'int' - converted to microdegrees
double latitude = 51.545538;
double longitude = -0.477247;
GeoPoint point = new GeoPoint((int)(latitude * 1e6), (int)(longitude * 1e6));
OverlayItem overlayitem = new OverlayItem(point, "Hola, Mundo!", "I'm in Mexico City!");
itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);
}
}
My HelloItemizedOverlay class:
package testing.map;
import java.util.ArrayList;
import android.graphics.drawable.Drawable;
import android.app.AlertDialog;
import android.content.Context;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;
public class HelloItemizedOverlay extends ItemizedOverlay {
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
public HelloItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
super(defaultMarker);
Context mContext = context;
}
#Override
protected OverlayItem createItem(int i) {
// TODO Auto-generated method stub
return mOverlays.get(i);
}
#Override
public int size() {
// TODO Auto-generated method stub
return mOverlays.size();
}
#Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
Context mContext = null;
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
}
You are missing the Context in the main class.
Add this :
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable, mContext);
where mContext = this;
instead of this:
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable);
Change two places:
1.
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable, this);
2.
public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
super(boundCenterBottom(defaultMarker));
mContext = context;
}
I also found that the HelloGoogleMaps tutorial code failed with a npe when you tap the marker.
If you pass this (from an instance that extends MapActivity) the dialog shows.
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable, this);
Constructor required:
public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
super(defaultMarker);
mContext = context;
}
you can pass context like this, here is the pseudo code:
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(this,drawable);
I'm having some troubles with displaying ItemizedOverlay(s) on a map.
Here I extracted a simplified example of what I need to do.
Here's my Map class:
import java.util.Timer;
import java.util.TimerTask;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
public class Map extends MapActivity {
protected static final String TAG = "Map";
private int test = 0;
private TestItemized items = null;
private Timer timer = new Timer();
private MapView map = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.map = (MapView) this.findViewById(R.id.myMapView1);
this.map.setBuiltInZoomControls(true);
this.map.setSatellite(false);
this.map.setStreetView(true);
this.map.setClickable(true);
this.timer.scheduleAtFixedRate(new TimerTask(){
#Override
public void run() {
Log.d(TAG, "refeshing: "+ String.valueOf(test));
Drawable drawable = Map.this.getResources().getDrawable(R.drawable.androidmarker);
test++;
if (Map.this.items instanceof TestItemized && Map.this.map.getOverlays().contains(Map.this.items))
Map.this.map.getOverlays().remove(Map.this.items);
//some code might go here to retrieve new coordinates but this isn't a problem
Map.this.items = new TestItemized(drawable, Map.this);
double lat = 46.491734;
Log.d(TAG,"Latitude : "+ String.valueOf(lat));
double lng = 11.320365;
Log.d(TAG,"Longitude : "+ String.valueOf(lng));
OverlayItem item = new OverlayItem(new GeoPoint((int)(lat * 1E6), (int)(lng * 1E6)), String.valueOf(Map.this.test), "blah!");
Map.this.items.addOverlay(item);
Map.this.map.getOverlays().add(Map.this.items);
Log.d(TAG,"refreshing "+String.valueOf(test)+" is over");
}}, 1000,60000);
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
}
I followed the guide provided by google to extends the ItemizedOverlay class
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.widget.Toast;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;
#SuppressWarnings("rawtypes")
public class TestItemized extends ItemizedOverlay {
private Context mCtx;
private List<OverlayItem> mItems = new ArrayList<OverlayItem>();
public TestItemized(Drawable arg0) {
super(arg0);
}
/**
* #param defaultMarker
* #param mCtx
*/
public TestItemized(Drawable defaultMarker, Context mCtx) {
super(defaultMarker);
this.mCtx = mCtx;
}
public void addOverlay(OverlayItem overlay) {
this.mItems.add(overlay);
populate();
}
#Override
protected OverlayItem createItem(int i) {
return this.mItems.get(i);
}
#Override
public int size() {
return mItems.size();
}
/* (non-Javadoc)
* #see com.google.android.maps.ItemizedOverlay#onTap(int)
*/
#Override
protected boolean onTap(int index) {
OverlayItem item = this.mItems.get(index);
Toast.makeText(this.mCtx, item.getTitle() +" : " +item.getSnippet(), Toast.LENGTH_LONG).show();
return true;
}
}
As it is clear from the code I need to update at fixed times a map UI with possibly new positions to do so I'm using a timer, but I think I might fall in some kind of thread issues I don't know how to handle, since when running a test I can see in the Log what happens but no marker is drawn on the map. Does anybody know how to solve this kind of problem?
At the end of the run() method, after you finish updating your MapView you should call
Map.this.map.postInvalidate();