MidMaps is a tiny Google Maps library for Java ME applications.
With MidMaps you can integrate Google Maps into your J2ME applications in few, easy steps!
How to use it?
MidMaps is designed to be simple. You don’t need to deal with threads, connections or other boring stuff like that: all you have to do is to create a map and display it on in your application.
Creating a simple map
To get a map object, you have to perform two steps:
- First, instantiate a new GoogleMaps object:
GoogleMaps gMaps = new GoogleMaps();
- Then, create a new GoogleStaticMap instance by using the createMap() method:
GoogleStaticMap map = gMaps.createMap(mapWidth, mapHeight, GoogleStaticMap.FORMAT_PNG);
Once you have created a map, it is necessary to define its handler. The handler has an important role: it gets automatically called each time the map object is updated, or when an error occurs: this way, you can know when you need to repaint the map, or how to notify the user about what’s going on. The handler has to implement the GoogleStaticMapHandler interface, that defines two methods:
public void GoogleStaticMapUpdated(GoogleStaticMap map); public void GoogleStaticMapUpdateError(GoogleStaticMap map, int errorCode, String errorMessage); |
The first one is called when a map is updated, so that your MIDlet knows that it must be repainted. The second one gets called when an error occurs (e.g.: when there is a network issue and the map image cannot be downloaded).
Once you’ve created your handler, you have to pass it to the GoogleStaticMap instance with the setHandler() method:
map.setHandler(mapHandler); |
Now, how to actually load a map? First, it is necessary to define a location for the map:
- create a GoogleMapsCoordinates instance with the preferred latitude and longitude values
- use the GoogleStaticMap setCenter() method
map.setCenter(new GoogleMapsCoordinates(41.8954656, 12.4823243)); |
and then, you have to update() the map:
map.update(); |
After you’ve called update, the map image will be loaded and, when finished (or when an error occurs) the GoogleStaticMapHandler will be called. If the map is correctly loaded, you can actually draw it by using its draw(Graphics g, int left, int top, int attach) method.
Complete example
Below you can see a full example on how MidMaps can be used to display a map on a Canvas.
import javax.microedition.lcdui.Canvas; import javax.microedition.lcdui.Graphics; import com.jappit.midmaps.googlemaps.GoogleMaps; import com.jappit.midmaps.googlemaps.GoogleMapsCoordinates; import com.jappit.midmaps.googlemaps.GoogleStaticMapHandler; import com.jappit.midmaps.googlemaps.GoogleStaticMap; public class GoogleMapsSimpleCanvas extends Canvas implements GoogleStaticMapHandler { GoogleMaps gMaps = null; GoogleStaticMap map = null; public GoogleMapsSimpleCanvas() { gMaps = new GoogleMaps(); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(41.8954656, 12.4823243)); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } public void GoogleStaticMapUpdateError(GoogleStaticMap map, int errorCode, String errorMessage) { System.out.println("map error: " + errorCode + ", " + errorMessage); } public void GoogleStaticMapUpdated(GoogleStaticMap map) { repaint(); } } |
Markers
You can add markers to a map by using the GoogleMapsMarker class. You create a marker by specifying its location:
GoogleMapsMarker marker = new GoogleMapsMarker(new GoogleMapsCoordinates(41.8954656, 12.4823243)); |
Optionally, you can customize the marker by setting its color, size and and label (must be a single character):
marker.setColor(GoogleStaticMap.COLOR_GREEN); marker.setColor(GoogleMapsMarker.SIZE_TINY); marker.setLabel('P'); |
Then, you add the marker to your GoogleStaticMap instance with the addMarker() method:
map.addMarker(marker); |
Here’s an example of 2 different markers added to the previous map.
GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(41.8954656, 12.4823243)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); GoogleMapsMarker blueMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(41.8964656, 12.4843243)); blueMarker.setColor(GoogleStaticMap.COLOR_BLUE); blueMarker.setSize(GoogleMapsMarker.SIZE_SMALL); blueMarker.setLabel('R'); map.addMarker(redMarker); map.addMarker(blueMarker); |
Paths
Paths can be easily defined by using the GoogleMapsPath class. To create a new Path, just istantiate a new GoogleMapsPath object:
GoogleMapsPath path = new GoogleMapsPath(); |
And then add the path points with the addPoint() method:
path.addPoint(new GoogleMapsCoordinates(41.8954656, 12.4823243)); path.addPoint(new GoogleMapsCoordinates(41.8934656, 12.4833243)); |
Path weight, color and fill color can be customized with the following methods:
bluePath.setColor(GoogleStaticMap.COLOR_BLUE); bluePath.setWeight(5); bluePath.setFillColor(GoogleStaticMap.COLOR_GREEN); |
Below you can see an example of 2 different paths added to the map defined above.
GoogleMapsPath path = new GoogleMapsPath(); path.addPoint(new GoogleMapsCoordinates(41.8954656, 12.4823243)); path.addPoint(new GoogleMapsCoordinates(41.8934656, 12.4833243)); path.addPoint(new GoogleMapsCoordinates(41.8944656, 12.4843243)); path.setColor(GoogleStaticMap.COLOR_RED); path.setWeight(10); map.addPath(path); GoogleMapsPath bluePath = new GoogleMapsPath(); bluePath.addPoint(new GoogleMapsCoordinates(41.8954656, 12.4823243)); bluePath.addPoint(new GoogleMapsCoordinates(41.8964656, 12.4813243)); bluePath.addPoint(new GoogleMapsCoordinates(41.8934656, 12.4803243)); bluePath.setColor(GoogleStaticMap.COLOR_BLUE); bluePath.setFillColor(GoogleStaticMap.COLOR_GREEN); bluePath.setWeight(5); map.addPath(bluePath); |
Geocoding
Geocoding requires a Google Maps API key, so you have to get your own key to use this feature.
To start, you have to instantiate a Google Maps object by using your own API key:
GoogleMaps gMaps = new GoogleMaps("<your_api_key>"); |
Then, you have to get a GoogleMapsGeocoder instance by using the createGeocoder() method:
GoogleMapsGeocoder geocoder = gMaps.createGeocoder(); |
Then, as done for the GoogleStaticMap objects, also the GoogleMapsGeocoder objects require an handler to be defined. The GoogleMapsGeocoderHandler interface defines 2 methods:
public void GoogleMapsGeocodeSuccess(String address, GoogleMapsCoordinates coordinates, int accuracy); public void GoogleMapsGeocodeError(String address, int errorCode, String errorDescription); |
These 2 methods are called when a geocoding request successes or fails, respectively. Once you have implemented your GoogleMapsGeocoderHandler, you have to pass it to the GoogleMapsGeocoder instance created above:
geocoder.setHandler(geocoderHandler); |
Done this, all is ready to geocode an address: to do this, just call the geocodeAddress() method:
geocoder.geocodeAddress("Rome, Italy"); |
When the geocoding ends, your handler will be notified via the GoogleMapsGeocodeSuccess() method. A possible implementation of such method is visible below:
public void GoogleMapsGeocodeSuccess(String address, GoogleMapsCoordinates coordinates, int accuracy) { map.setCenter(coordinates); map.addMarker(new GoogleMapsMarker(coordinates)); map.setZoom(GoogleMaps.getZoomForAccuracy(accuracy)); map.update(); } |
Since the geocoding operation returns an “accuracy” value, you can use this value to get a default zoom value for your map. To do this, you can use the GoogleMaps.getZoomForAccuracy() method, as shown above.
Below you can see the map generated by the previous code:
Moving and zooming the map
MidMaps has inbuilt functionalities that allow to easily move and zoom your maps.
To move a map around, it is enough to call the GoogleStaticMap move(int direction) method, passing as argument one of the four possible directions, specified by the Canvas static properties: UP, RIGHT, DOWN and LEFT.
Important: the move() method automatically calls the map update() functionality, so there is no need to call it explicitly.
Using the same Canvas example shown above, it is enough to add this keyPressed() method to allow users to freely move around on the map:
protected void keyPressed(int key) { int gameAction = getGameAction(key); if(gameAction == Canvas.UP || gameAction == Canvas.RIGHT || gameAction == Canvas.DOWN || gameAction == Canvas.LEFT) { map.move(gameAction); } } |
Similarly, the GoogleStaticMap provides these methods to manage the zoom level:
As for the move() functionality, the zoomIn() and zoomOut() methods automatically call the map update process.
Drawing map images
You have two options to draw a map in your MIDlet.
- The first one, that was used in the examples above, is to use GoogleStaticMap draw() method. This method is especially useful when dealing with Canvas or CustomItem objects.
map.draw(myGraphics, 0, 0, Graphics.TOP | Graphics.LEFT);
- The second method is to get a reference to the map image via its getImage() method, and use it as a standard Image object. The code below shows how this method can be used to add and show a map image within a Form:
ImageItem mapItem = new ImageItem("My Map", map.getImage(), Item.LAYOUT_TOP, "Sample map"); myForm.append(mapItem);
Library, API reference and full sample code
The MidMaps library is available for download here: MidMaps – J2Me Google Maps library. The current release is compatible with devices supporting MIDP 2.0 and CLDC 1.1.
You can also download a full MIDlet, complete with source code, showing the various MidMaps functionalities in action:
To get more details, you can check out the full MidMaps API reference.
Feedback
MidMaps is currently at its first release, so any kind of feedback is highly welcome. Let me know if you find bugs, how MidMaps could be improved, or which features you would like to see implemented. Thank you!
GoogleStaticMap map = gMaps.getMap(mapHandler, mapWidth, mapHeight, GoogleStaticMap.FORMAT_PNG); |
Ajit 10:34 am on January 12, 2011 Permalink
Hi, i used your API for devloping a location application. But it is taking a lot of time to load the map. Why is it so. Is there anyway in which i could reduce this time.
Will 1:21 pm on January 26, 2011 Permalink
hi Ajit hmm am looking fo the API itself coz the one i got tells me an error. Where did you get yours?
Vinnie 8:38 pm on January 26, 2011 Permalink
Mine too had errors!
plus,how can i be able to retrieve latitude and longitude from a map so that i can use them to build a location application.please help…
Ja 5:34 am on February 24, 2011 Permalink
why is it in some cases, if you move around, the map would go to the image of the ocean?
i.e. from this center 14.5833333,120.9666667 it becomes 15.517171248793604,59.03333330163087 when you move up.
Ek 5:45 am on March 29, 2011 Permalink
Hi, i have seen and tried your library that you created. There something wrong when i use map.move(gameAction); if i set the coordinate latitude less than 75.000000 it works but if i set more than 100.000000 the maps display wrong location.
Menion 8:11 pm on April 17, 2011 Permalink
Hi,
how is this with Terms of use for these maps? As I know, usage of Google maps in other places then on web page through their API is not allowed …
Calin 1:22 pm on April 18, 2011 Permalink
Hi,
I tried to develop an mobile app using this library but i get the error:
“java.lang.NoClassDefFoundError: com/jappit/midmaps/googlemaps/GoogleStaticMapHandler”
Did any of you have the same problem and if so, how did you fix it?
Thanks!
jim 6:32 pm on May 17, 2011 Permalink
Its seems freelance developer don want to ans any queries… man we appreciate that u took time to upload but u wont ans then how can anyone take reference of what u uploaded !!!!!!!!!!!!!!
pit 6:44 pm on May 17, 2011 Permalink
Hi all,
@jim: do you have any specific issue with the library?
@Ajit: loading times should only depend on network connectivity and signal strength. Will double check to see if there’s any lag in MIDMaps library.
@Vinnie: could you please clarify your question?
@Ja: I’ve noticed that issue too. There’s something wrong with the method that calculates movement deltas, will check and let you know.
@Ek: can you give me a couple of coordinates (lat, lng) that cause this error to appear?
@Menion: the library is free for both personal and commercial uses. As for Google Maps itself, you have to rely on the Terms of Services of Google.
@Calin: you have to include the MIDMaps library JAR in your project. Which IDE are you using?
Alessandro
jim 9:10 pm on May 17, 2011 Permalink
hi pit..please accept my apologies if u felt bad.. I had queries but was disappointed seeing no response to the past queries… I have same queries… I used Eclipse IDE and imported all source file and lib as instructed.. I tried to run GoogleMapsMIDlet in Emulator but it stopped without displaying anything…Can you please guide me where I am going wrong ..Also jar file that got created was therefore for of no use…
pit 9:28 pm on May 17, 2011 Permalink
Hi jim, no worries at all. I’ve been quite busy lately, and I was unable to properly follow this project. As for your question: have you tried compiling and running the GoogleMapsSimpleCanvas code shown above? Does it work for you?
Alessandro
jim 9:46 pm on May 17, 2011 Permalink
Hi pit
Thank for your replies…
When I run My Midlet or GoogleMapsSimpleCanvas code I get following error in my console….
Running with storage root C:\Users\user\j2mewtk\2.5.2\appdb\MediaControlSkin
Running with locale: English_United States.1252
Running in the identified_third_party security domain
java.lang.ClassNotFoundException: GoogleMapsMIDlet
at com.sun.midp.midlet.MIDletState.createMIDlet(+29)
at com.sun.midp.midlet.Scheduler.schedule(+52)
at com.sun.midp.main.Main.runLocalClass(+28)
at com.sun.midp.main.Main.main(+80)
Execution completed.
3401806 bytecodes executed
26 thread switches
1667 classes in the system (including system classes)
17565 dynamic objects allocated (522448 bytes)
1 garbage collections (0 bytes collected)
pit 9:53 pm on May 17, 2011 Permalink
Jim, It seems that the library is not properly exported with the MIDlet jar. You should find the export option in the Java Build Path section of the project properties.
jim 10:13 pm on May 17, 2011 Permalink
ahaa thanks pit… what a silly mistake… thanks alot…
One more question i have ..its about Symbian C++ …. I was facing difficulties in http post get request there.. I got one link on nokia forum but as i have just started symbian so wasnt able to perform these operations in GUI
jim 10:29 pm on May 17, 2011 Permalink
Hi pit…
have one last question… I tried to install jar file on my nokia C5 .. but unlike other jars its showing invalid jar file !!! what can be the reason for this ?
Ashok 8:04 am on May 18, 2011 Permalink
Hai,
This is very Good App. It will be use full for all . Then can i get the Area name for given Lat and long?
pit 8:32 am on May 18, 2011 Permalink
@Jim: as for your Symbian question, you’d surely find better help on the Forum Nokia discussion boards. Regarding the invalid JAR: have you defined the necessary MIDlet attributes in your manifest file?
@Ashok: that feature is currently not supported by MIDMaps.
Ashok 10:03 am on May 18, 2011 Permalink
Hai Pit,
Thanks for ur immediate reply.. But if i want to get Area Name , is there any possibilty to get current Area Name using MIDMap. And One more Question. can we get Lat Long of current position.?
jim 7:46 pm on May 18, 2011 Permalink
Hi pit.. thanks for your replies again…
I tried ur lib in Netbeans also…
I used following code
public Form getGMaps() {
if (GMaps == null) {
// write pre-init user code here
GMaps = new Form(“Map”);
GMaps.addCommand(getBackCommand2());
GMaps.addCommand(getExitCommand2());
GMaps.setCommandListener(this);
// write post-init user code here
mapItem = new ImageItem(“Loading map…”, null, Item.LAYOUT_TOP, “Sample map”);
GMaps.append(mapItem);
gMaps = new GoogleMaps();
map = gMaps.createMap(GMaps.getWidth(), GMaps.getHeight(), GoogleStaticMap.FORMAT_PNG);
map.setHandler((GoogleStaticMapHandler) this.GMaps);
map.setCenter(new GoogleMapsCoordinates(41.8954656, 12.4823243));
map.setZoom(15);
map.update();
}
return GMaps;
}
and got following error..
TRACE: , Exception caught in Display class
java.lang.ClassCastException: 0
at hello.HelloMIDlet.getGMaps(HelloMIDlet.java:570)
at hello.HelloMIDlet.listAction(HelloMIDlet.java:409)
at hello.HelloMIDlet.commandAction(HelloMIDlet.java:312)
at javax.microedition.lcdui.ChoiceGroupLFImpl.uCallKeyPressed(), bci=271
at javax.microedition.lcdui.FormLFImpl.uCallKeyPressed(), bci=87
at javax.microedition.lcdui.DisplayableLFImpl.uCallKeyEvent(), bci=146
at javax.microedition.lcdui.Display$DisplayEventConsumerImpl.handleKeyEvent(), bci=30
at com.sun.midp.lcdui.DisplayEventListener.process(), bci=277
at com.sun.midp.events.EventQueue.run(), bci=179
at java.lang.Thread.run(Thread.java:662)
Please guide ….
jim 7:51 pm on May 18, 2011 Permalink
hi pit..
yeas i defined the necessary MIDlet attributes in your manifest file… still it was not working
jim 7:52 pm on May 18, 2011 Permalink
your= my
jim 10:40 pm on May 18, 2011 Permalink
Got solution…
I was using “public class HelloMIDlet extends MIDlet implements CommandListener ” in my code so
Changing this to
“public class HelloMIDlet extends MIDlet implements GoogleStaticMapHandler, CommandListener ”
solved my problem
Lina Margarita 2:26 am on May 22, 2011 Permalink
Hello pit i have this problem when run your app.
java.lang.NoClassDefFoundError: com/jappit/midmaps/test/GoogleMapsSimpleCanvas: com/jappit/midmaps/googlemaps/GoogleStaticMapHandler
at com.jappit.midmaps.test.GoogleMapsMIDlet.startApp(+4)
at javax.microedition.midlet.MIDletProxy.startApp(+7)
at com.sun.midp.midlet.Scheduler.schedule(+270)
at com.sun.midp.main.Main.runLocalClass(+28)
at com.sun.midp.main.Main.main(+80)
Victor Gonzales 8:11 am on May 22, 2011 Permalink
Hello Pit your tuto is terrific. I have a question. If i want search a map for the country name or address. How it works? With this Api can i implemented this?
Thank you!
Lina Margarita 5:11 pm on May 22, 2011 Permalink
How use the “geocodeAddress”? i need that i write the address and shows the map. pit can you help me?
Trung Nguyen 7:59 am on May 25, 2011 Permalink
Hi all,
May i get current location with Google Maps API. I can’t use J2ME – JSR 179 Location API to detect my current location. I’m using E72, the error message is: “Location request time out”
Google Maps app on my phone works fine, GPS still good.
Thanks.
Trung Nguyen
pit 8:33 am on May 25, 2011 Permalink
Hi all,
@Ashok: you cannot currently get the area from a geographic point with MIDMaps. Future versions will probably integrate this feature as well. As for getting lat/lon coordinates of the user’s current position: you should use the Location API (JSR 179) for this.
@Lina: have you included the MIDMaps JAR file in your project’s build path?
@Victor: you have to use the geocode functionality of this MIDMaps library. Have you already checked out the downloadable sample code?
@Lina: the geocode address allows you to retrieve coordinates relative to an address. Once you have those coordinates, you simply initialize a map as shown in the code above. Please check out the sample midlet source code to see all the involved steps.
@Trung: the correct solution is to use JSR 179, as you do. The location request timeout usually depends on closed environments that do not allow to correctly retrieve the user’s position: have you tested also in outdoor environments?
Alessandro
Jullev 3:51 am on July 18, 2011 Permalink
Hi All
i have problem with it, when i try to install it into the device it just close before load the map succesfully any advice what should i do?
Thanks
Jullev
Chamroeun 10:31 am on July 29, 2011 Permalink
Pit I have problem the same as Lina I have already included it to my project. when I write code it does not show any error but when run it I got that error
Chris 12:52 pm on August 26, 2011 Permalink
Hi, I’m Chris. I am creating an app that should allow users to search for locations. How do I do this while using MidMaps?
Prateek Jassal 8:43 pm on September 4, 2011 Permalink
@ Allesandro …. I do not have any doubts as of now, but you have surely done some commendable work. It was been helpful for me until now. Thanks for this.
Apart from this I would suggest you to add a Reverse Geocoder just like u added a Geocoder. Using the location API, I was able to get my current coordinates and then I was stuck there because I needed my location to use the Geocoder method. Then I went on with JSON and XML parsing and finally settled for JSON parsing since its kind of light weight to actually get my location. After that I traced a static map using your library. For XML parsing I used the standard kXML 1.2 library and Json-ME library for JSON parsing. I am actually just a student. I would love to work with you if given a chance. Do let me know if there’s something we can work on in the same area.
Fahad 11:08 am on September 15, 2011 Permalink
hi all
When I run your file it gives error
“failed to load main-class manifest attribute from”
Why this error is pop-up ?
Marc 1:05 am on September 19, 2011 Permalink
Hi pit,
Would you ever consider releasing your library as open-source ?
I’m stuck with the integration of Google Maps and a Blackberry application.
Regards,
Marc.
looka 9:54 am on October 4, 2011 Permalink
MY VOTE FOR OPENSOURCE!
Then we make a real offline app for j2me devices!
Foxxor 9:17 pm on October 5, 2011 Permalink
Hi, 1st of all incredible library good work.
I’m wondering if it is posible to retrieve the coordinates of the center of the screen, when you move the screen? or at least do you know how many units of logitude and latitude the map change when you’re moving using the cursors, In example your initial location is (0.0 , 0.0) then if you move the map to the left u’re current coordinates would be (-0.1, 0.0) it gives a delta of 0.1 moving right-left.
Akki 12:52 pm on October 24, 2011 Permalink
Hieee,
Hai how to draw path between two points if we mark that places using GoogleMapsGeocodeCanvas?
Akki 2:42 pm on October 24, 2011 Permalink
Hai any one will help me….
How to get latitude and longitude from geocodeAddress?
Here I am 10:20 am on October 25, 2011 Permalink
Hi,
How to change the image of the marker???