The Friend Finder - MapActivity using GPS - Part: II / II

Tutorials that use the MapActivity. Many using GPS functionality.

The Friend Finder - MapActivity using GPS - Part: II / II

Postby plusminus » Thu Nov 22, 2007 9:04 pm

The Friend Finder - MapActivity using GPS - Part: II / II




:arrow: Having completed Part I of this tutorial, this is where we are now:
Image

:arrow: But, where we want to get to finally is:
Image Image


0. Create a new Class called "FriendFinderMap.java" (extending MapActivity)in the same source-folder/package where "FriendFinderMap.java" is located.

In order to make this second Activity startable through an Intent (what is the way you open other Activities in Android), we have to register that new Activity in the AndroidManifest.xml .

Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1.         // ....
  2.         </activity>
  3.         <activity class=".FriendFinderMap" android:label="@string/map_title">
  4.             <intent-filter>
  5.                 <action android:value="android.intent.action.VIEW" />
  6.                 <category android:value="android.intent.category.DEFAULT" />
  7.             </intent-filter>
  8.         </activity>
  9.     </application>
  10. </manifest>
Parsed in 0.002 seconds, using GeSHi 1.0.8.4


1. So we add the following lines to 'FriendFinder.java' to get obtain our own menu.
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         /** Called only the first time the options menu is displayed.
  2.          * Create the menu entries.
  3.          *  Menus are added in the order they are hardcoded. */
  4.         @Override
  5.         public boolean onCreateOptionsMenu(Menu menu) {
  6.                 boolean supRetVal = super.onCreateOptionsMenu(menu);
  7.                 menu.add(0, 0, getString(R.string.main_menu_open_map));
  8.                 return supRetVal;
  9.         }
  10.         @Override
  11.         public boolean onOptionsItemSelected(Menu.Item item) {
  12.                 switch (item.getId()) {
  13.                         case 0:
  14.                                 startSubActivity(new Intent(this, FriendFinderMap.class), 0);
  15.                                 return true;
  16.                 }
  17.                 return false;
  18.         }
Parsed in 0.032 seconds, using GeSHi 1.0.8.4

There will be no further changes to 'FriendFinder.java'.

2. Lets take a look at 'FriendFinderMap.java's onCreate(...)-method:
It bascially does the same as the FriendFinder(List) but also some Map-Setup and some Graphic/Overlay-Preparation.
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         @Override
  2.         protected void onCreate(Bundle icicle) {
  3.                 super.onCreate(icicle);
  4.                
  5.                 /* Create a new MapView and show it */
  6.                 this.myMapView = new MapView(this);
  7.                 this.setContentView(myMapView);
  8.                 /* MapController is capable of zooming
  9.                  * and animating and stuff like that */
  10.                 this.myMapController = this.myMapView.getController();
  11.                
  12.                 /* With these objects we are capable of
  13.                  * drawing graphical stuff on top of the map */
  14.                 this.myOverlayController = this.myMapView.createOverlayController();
  15.                 MyLocationOverlay myLocationOverlay = new MyLocationOverlay();
  16.                 this.myOverlayController.add(myLocationOverlay, true);
  17.                
  18.                 this.myMapController.zoomTo(2); // Far out
  19.                
  20.                 // Initialize the LocationManager
  21.                 this.myLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
  22.                 this.updateView();
  23.                
  24.                 /* Prepare the things, that will give
  25.                  * us the ability, to receive Information
  26.                  * about our GPS-Position. */
  27.                 this.setupForGPSAutoRefreshing();
  28.                
  29.                 /* Update the list of our friends once on the start,
  30.                  * as they are not(yet) moving, no updates to them are necessary */
  31.                 this.refreshFriendsList(NEARFRIEND_MAX_DISTANCE);
  32.         }
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


3. As the 'refreshFriendsList(...) method does the same as in the first Class ot 99,9% I wont repeat the code here. What it does is putting all friends closer than 'NEARFRIEND_MAX_DISTANCE' to the field 'this.nearFriends'.

4. The same procedure for 'setupForGPSAutoRefreshing()', it it even 100% the same as in the first Class. Also the same for the IntenReceiver, IntentFilter, onFreeze() and onResume() :!:

5. The function that was called updateList in the first Class is nwo called updateView() and does not much except updating our own GPS-Location and calling 'myMapView.invalidate()' what causes a full redraw of your MapView, what leads a draw()-call in our 'MyLocationOverlay'-Class and in the end to a moving circle (== us) on the screen. :)
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         private void updateView() {
  2.                 // Refresh our gps-location
  3.                 this.myLocation = myLocationManager.getCurrentLocation("gps");
  4.                
  5.                 /* Redraws the mapViee, which also makes our
  6.                  * OverlayController redraw our Circles and Lines */
  7.                 this.myMapView.invalidate();
  8.                
  9.                 /* As the location of our Friends is static and
  10.                  * for performance-reasons, we do not call this */
  11.                 // this.refreshFriendsList(NEARFRIEND_MAX_DISTANCE);
  12.         }
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


6. What is different in this Class is the way of visualizing data (in the Map not in a List this time). In onCreate we created an Object of the type MyLocationOverlay, which is doing its work everytime the MapView is being redrawn.
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. MyLocationOverlay myLocationOverlay = new MyLocationOverlay();
Parsed in 0.035 seconds, using GeSHi 1.0.8.4

The MyLocationOverlay-class looks the following, as the method is heavily commented I'll just paste it here:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         /**
  2.          * This method is so huge,
  3.          * because it does a lot of FANCY painting.
  4.          * We could shorten this method to a few lines.
  5.          * But as users like eye-candy apps <img src="http://www.anddev.org/images/smilies/wink.png" alt=";)" title="Wink" /> ...
  6.          */
  7.     protected class MyLocationOverlay extends Overlay {
  8.         @Override
  9.         public void draw(Canvas canvas, PixelCalculator calculator, boolean shadow) {
  10.                 super.draw(canvas, calculator, shadow);
  11.                 // Setup our "brush"/"pencil"/ whatever...
  12.                 Paint paint = new Paint();
  13.                 paint.setTextSize(14);
  14.                
  15.                 // Create a Point that represents our GPS-Location             
  16.                 Double lat = FriendFinderMap.this.myLocation.getLatitude() * 1E6;
  17.                 Double lng = FriendFinderMap.this.myLocation.getLongitude() * 1E6;
  18.                 Point point = new Point(lat.intValue(), lng.intValue());
  19.                
  20.                 int[] myScreenCoords = new int[2];
  21.                 // Converts lat/lng-Point to OUR coordinates on the screen.
  22.                 calculator.getPointXY(point, myScreenCoords);
  23.                
  24.                 // Draw a circle for our location
  25.                 RectF oval = new RectF(myScreenCoords[0] - 7, myScreenCoords[1] + 7,
  26.                                                         myScreenCoords[0] + 7, myScreenCoords[1] - 7);
  27.                
  28.                 // Setup a color for our location
  29.                 paint.setStyle(Style.FILL);
  30.                 paint.setARGB(255, 80, 150, 30); // Nice strong Android-Green    
  31.                 // Draw our name
  32.                 canvas.drawText(getString(R.string.map_overlay_own_name),
  33.                                                         myScreenCoords[0] +9, myScreenCoords[1], paint);
  34.                
  35.                 // Change the paint to a 'Lookthrough' Android-Green
  36.                 paint.setARGB(80, 156, 192, 36);
  37.                 paint.setStrokeWidth(1);
  38.                 // draw an oval around our location
  39.                 canvas.drawOval(oval, paint);
  40.                
  41.                  // With a black stroke around the oval we drew before.
  42.                 paint.setARGB(255,0,0,0);
  43.                 paint.setStyle(Style.STROKE);
  44.                 canvas.drawCircle(myScreenCoords[0], myScreenCoords[1], 7, paint);
  45.                
  46.                 int[] friendScreenCoords = new int[2];
  47.                 //Draw each friend with a line pointing to our own location.
  48.                 for(Friend aFriend : FriendFinderMap.this.nearFriends){
  49.                         lat = aFriend.itsLocation.getLatitude() * 1E6;
  50.                         lng = aFriend.itsLocation.getLongitude() * 1E6;
  51.                         point = new Point(lat.intValue(), lng.intValue());
  52.  
  53.                         // Converts lat/lng-Point to coordinates on the screen.
  54.                         calculator.getPointXY(point, friendScreenCoords);
  55.                         if(Math.abs(friendScreenCoords[0]) < 2000 && Math.abs(friendScreenCoords[1]) < 2000){
  56.                                 // Draw a circle for this friend and his name
  57.                                 oval = new RectF(friendScreenCoords[0] - 7, friendScreenCoords[1] + 7,
  58.                                                                 friendScreenCoords[0] + 7, friendScreenCoords[1] - 7);
  59.                                
  60.                         // Setup a color for all friends
  61.                                 paint.setStyle(Style.FILL);
  62.                                 paint.setARGB(255, 255, 0, 0); // Nice red                     
  63.                                 canvas.drawText(aFriend.itsName, friendScreenCoords[0] +9,
  64.                                                                         friendScreenCoords[1], paint);
  65.                                
  66.                                 // Draw a line connecting us to the current Friend
  67.                                 paint.setARGB(80, 255, 0, 0); // Nice red, more look through...
  68.  
  69.                         paint.setStrokeWidth(2);
  70.                                 canvas.drawLine(myScreenCoords[0], myScreenCoords[1],
  71.                                                                 friendScreenCoords[0], friendScreenCoords[1], paint);
  72.                         paint.setStrokeWidth(1);
  73.                         // draw an oval around our friends location
  74.                                 canvas.drawOval(oval, paint);
  75.                                
  76.                                  // With a black stroke around the oval we drew before.
  77.                                 paint.setARGB(255,0,0,0);
  78.                                 paint.setStyle(Style.STROKE);
  79.                                 canvas.drawCircle(friendScreenCoords[0], friendScreenCoords[1], 7, paint);
  80.                         }
  81.                 }
  82.         }
  83.     }
Parsed in 0.067 seconds, using GeSHi 1.0.8.4


7. The very last thing we need to do is to add some HotKeys and the Menu, both for Toggling the Sattelite-View and zooming in/out.
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         // Called only the first time the options menu is displayed.
  2.         // Create the menu entries.
  3.         // Menu adds items in the order shown.
  4.         @Override
  5.         public boolean onCreateOptionsMenu(Menu menu) {
  6.                 boolean supRetVal = super.onCreateOptionsMenu(menu);
  7.                 menu.add(0, 0, getString(R.string.map_menu_zoom_in));
  8.                 menu.add(0, 1, getString(R.string.map_menu_zoom_out));
  9.                 menu.add(0, 2, getString(R.string.map_menu_toggle_street_satellite));
  10.                 menu.add(0, 3, getString(R.string.map_menu_back_to_list));
  11.                 return supRetVal;
  12.         }
  13.        
  14.         @Override
  15.         public boolean onOptionsItemSelected(Menu.Item item){
  16.             switch (item.getId()) {
  17.                     case 0:
  18.                         // Zoom not closer than possible
  19.                         this.myMapController.zoomTo(Math.min(21, this.myMapView.getZoomLevel() + 1));
  20.                         return true;
  21.                     case 1:
  22.                         // Zoom not farer than possible
  23.                         this.myMapController.zoomTo(Math.max(1, this.myMapView.getZoomLevel() - 1));
  24.                         return true;
  25.                     case 2:
  26.                         // Switch to satellite view
  27.                     myMapView.toggleSatellite();
  28.                         return true;
  29.                     case 3:
  30.                         this.finish();
  31.                         return true;
  32.             }
  33.             return false;
  34.         }
  35.        
  36.         @Override
  37.     public boolean onKeyDown(int keyCode, KeyEvent event) {
  38.         if (keyCode == KeyEvent.KEYCODE_I) {
  39.                 // Zoom not closer than possible
  40.                 this.myMapController.zoomTo(Math.min(21, this.myMapView.getZoomLevel() + 1));
  41.             return true;
  42.         } else if (keyCode == KeyEvent.KEYCODE_O) {
  43.                 // Zoom not farer than possible
  44.                 this.myMapController.zoomTo(Math.max(1, this.myMapView.getZoomLevel() - 1));
  45.             return true;
  46.         } else if (keyCode == KeyEvent.KEYCODE_T) {
  47.                 // Switch to satellite view
  48.             myMapView.toggleSatellite();
  49.             return true;
  50.         }
  51.         return false;
  52.     }
Parsed in 0.049 seconds, using GeSHi 1.0.8.4


:run: :run: :run: Thats it, we are done. :run: :run: :run:

View: >> Full Source for this Tutorial <<


Regards,
plusminus
Last edited by plusminus on Wed Nov 28, 2007 2:46 am, edited 2 times in total.
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Top

coordinates accuracy

Postby flowdi » Sun Nov 25, 2007 6:45 pm

is it 1,000,000 instead of 10,000 to multiply the coordinates (Double) with
(for the integer values required by the Point-Constructor?)

How does these 'mock locationrovider' work?
i put a .kml-file in data/misc/location/gps/ but it doesn't seem to work?

flo
User avatar
flowdi
Junior Developer
Junior Developer
 
Posts: 11
Joined: Sun Nov 25, 2007 6:39 pm

Postby plusminus » Sun Nov 25, 2007 8:27 pm

Hello flowdi,

Yap, should be 1.000.000 instead of 10.000. Fixed it :!:

I'm just making a small tutorial of what was supposed to the second part of your post :)

Wont take longer than an hour from now :!:
So, stay tuned :)

[Edit:]
Did it:
:arrow: :arrow: :arrow: Mock LocationProvider - Structure/Explanation (NMEA, $GPRMC)

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Postby quauhtlimtz » Tue Nov 27, 2007 11:57 pm

Hey, plusminus:

How can you keep the selected item on the ListActivity screen? Everytime the updateList() method is invoked, the screen "loses" its selected item.
quauhtlimtz
Junior Developer
Junior Developer
 
Posts: 13
Joined: Mon Nov 26, 2007 5:56 pm
Location: Mexico

Postby plusminus » Wed Nov 28, 2007 2:43 am

quauhtlimtz wrote:Hey, plusminus:

How can you keep the selected item on the ListActivity screen? Everytime the updateList() method is invoked, the screen "loses" its selected item.


Hello quauhtlimtz,

we need to modify only a few lines in the updateList()-method.
  1. Remember the last SelectionIndex, if there was already an ListAdapter before, that could return us a SelectionIndex.
  2. Update the List Adapter
  3. Try to set the selectionIndex back


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         private void updateList() {
  2.  
  3.                 // .... many lines....
  4.  
  5.  
  6.  
  7.                 }
  8.  
  9.  
  10.  
  11.                 ArrayAdapter<String> notes =  new ArrayAdapter<String>(this,
  12.  
  13.                                 android.R.layout.simple_list_item_1, listItems);
  14.  
  15.  
  16.  
  17.                 // these 3 lines are new
  18.  
  19.                 long beforeIndex = 0;
  20.  
  21.                 if(this.getListAdapter() != null)
  22.  
  23.                         beforeIndex = this.getSelectionRowID();
  24.  
  25.                        
  26.  
  27.                 this.setListAdapter(notes);
  28.  
  29.  
  30.  
  31.                 // these 3 lines are also new
  32.  
  33.                 try{
  34.  
  35.                         this.setSelection((int)beforeIndex);
  36.  
  37.                 }catch (Exception e){}
  38.  
  39.         }
Parsed in 0.042 seconds, using GeSHi 1.0.8.4


Was a good issue, so I added it to the Tutorial-Code :!:

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Postby venkat » Mon Dec 03, 2007 4:21 pm

now i can see the distance. for example,

venkat(3.557 km), and number is keep on changing. if i click any one of the menu , nothing is happening.:?:
Last edited by venkat on Mon Dec 03, 2007 4:35 pm, edited 2 times in total.
venkat
Senior Developer
Senior Developer
 
Posts: 152
Joined: Tue Nov 27, 2007 5:42 am
Location: India

Top

Postby venkat » Mon Dec 03, 2007 4:28 pm

dear +-,
i can see one dot and my name on blank map. i can't see any satellite or street view. :(

can u solve my problem.

Thanks in advance,

Regards,
venkat
venkat
Senior Developer
Senior Developer
 
Posts: 152
Joined: Tue Nov 27, 2007 5:42 am
Location: India

Postby plusminus » Mon Dec 03, 2007 9:04 pm

Hello venkat,

the sattelite-View is toggle over KeyPress to T:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. ....
  2.  
  3.      else if (keyCode == KeyEvent.KEYCODE_T) {
  4.  
  5.           // Switch to satellite view
  6.  
  7.           myMapView.toggleSatellite();
  8.  
  9. ....
Parsed in 0.036 seconds, using GeSHi 1.0.8.4

or through the menu-Button on your Emulator.


You should see one "Dot" moving around in San Fransico with the name "ME" and as you have had listed "venkat" in the List on the start, it should also appear on the MapView :!:

Perhaps you forgot to copy-paste sth. :| :?:

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Postby venkat » Tue Dec 04, 2007 7:58 am

Dear Plusminus,
i have tried to open sample "maps" application which is given along with emulator. it's also showing blank map only. :!:

i have attach my friendfinder application screen shot below. please take a look on that. :)

can u please tell me, how to enable map on my emulator????? :?:

Thanks in advance,

Regards,
venkat
venkat
Senior Developer
Senior Developer
 
Posts: 152
Joined: Tue Nov 27, 2007 5:42 am
Location: India

Postby venkat » Tue Dec 04, 2007 8:00 am

Sorry, my attachment is here...
Attachments
FriendFinder.png
my Friend Finder attachment
FriendFinder.png (8.63 KiB) Viewed 70737 times
venkat
Senior Developer
Senior Developer
 
Posts: 152
Joined: Tue Nov 27, 2007 5:42 am
Location: India

Postby plusminus » Tue Dec 04, 2007 9:48 am

Hello venkat,

:arrow: answered in the other post. ;)

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Plz help

Postby cybersat » Thu Jan 03, 2008 7:19 pm

Code snippet is Superrrr and is working.

Only problem is my gps map pointer location (round dot) is not pointing to right location.

I am from State: kerala, Country: india, and i got "geo:9.590078,72.521792#" from googlemap "link to..." to be placed in Notes of contact address.

But when looked through FriendFinder map, it shows location somewhere near united states .Plz check screen shot attached.
Attachments
sc.JPG
sc.JPG (126 KiB) Viewed 67976 times
cybersat
Freshman
Freshman
 
Posts: 5
Joined: Tue Dec 18, 2007 8:09 am

Postby plusminus » Thu Jan 03, 2008 8:18 pm

Hello cybersat,

in the emulator the GPS-"Signal" is a fake one (Near the Google-Headquarters in MountainView California)!

Have a look at this :src: explanations/tutorial.
If you are fed up with the built in Moch(Fake) Location-Provider, read :src: here.

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Postby glider » Tue Jan 08, 2008 10:52 am

So how do I keep the 'me' in focus and in the middle ?
(even after zoom in/out /pan - i want center to be where the
gps coord is at all times)

Thanks for an awesome howto!
glider
Freshman
Freshman
 
Posts: 4
Joined: Thu Jan 03, 2008 2:37 am

Postby plusminus » Tue Jan 08, 2008 4:39 pm

Hello glider,

sth. like this should work:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.           // Animate to the center
  2.  
  3.           myMapController.animateTo(new Point(myLatitude,myLongitude));
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


Tell us if worked :)

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Top
Next

Return to Map Tutorials

Who is online

Users browsing this forum: No registered users and 2 guests