| Author |
Message |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2102 Location: Germany
|
Posted: Thu Nov 22, 2007 9:04 pm Post subject: The Friend Finder - MapActivity using GPS - Part: II / II |
|
|
The Friend Finder - MapActivity using GPS - Part: II / II
Having completed Part I of this tutorial, this is where we are now:
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 .
| XML: | // ....
</activity>
<activity class=".FriendFinderMap" android:label="@string/map_title">
<intent-filter>
<action android:value="android.intent.action.VIEW" />
<category android:value="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest> |
1. So we add the following lines to 'FriendFinder.java' to get obtain our own menu.
| Java: | /** Called only the first time the options menu is displayed.
* Create the menu entries.
* Menus are added in the order they are hardcoded. */
@Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean supRetVal = super.onCreateOptionsMenu(menu);
menu.add(0, 0, getString(R.string.main_menu_open_map));
return supRetVal;
}
@Override
public boolean onOptionsItemSelected(Menu.Item item) {
switch (item.getId()) {
case 0:
startSubActivity(new Intent(this, FriendFinderMap.class), 0);
return true;
}
return false;
} |
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.
| Java: | @Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
/* Create a new MapView and show it */
this.myMapView = new MapView(this);
this.setContentView(myMapView);
/* MapController is capable of zooming
* and animating and stuff like that */
this.myMapController = this.myMapView.getController();
/* With these objects we are capable of
* drawing graphical stuff on top of the map */
this.myOverlayController = this.myMapView.createOverlayController();
MyLocationOverlay myLocationOverlay = new MyLocationOverlay();
this.myOverlayController.add(myLocationOverlay, true);
this.myMapController.zoomTo(2); // Far out
// Initialize the LocationManager
this.myLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
this.updateView();
/* Prepare the things, that will give
* us the ability, to receive Information
* about our GPS-Position. */
this.setupForGPSAutoRefreshing();
/* Update the list of our friends once on the start,
* as they are not(yet) moving, no updates to them are necessary */
this.refreshFriendsList(NEARFRIEND_MAX_DISTANCE);
} |
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.
| Java: | private void updateView() {
// Refresh our gps-location
this.myLocation = myLocationManager.getCurrentLocation("gps");
/* Redraws the mapViee, which also makes our
* OverlayController redraw our Circles and Lines */
this.myMapView.invalidate();
/* As the location of our Friends is static and
* for performance-reasons, we do not call this */
// this.refreshFriendsList(NEARFRIEND_MAX_DISTANCE);
} |
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.
| Java: | MyLocationOverlay myLocationOverlay = new MyLocationOverlay(); |
The MyLocationOverlay-class looks the following, as the method is heavily commented I'll just paste it here:
| Java: | /**
* This method is so huge,
* because it does a lot of FANCY painting.
* We could shorten this method to a few lines.
* But as users like eye-candy apps ...
*/
protected class MyLocationOverlay extends Overlay {
@Override
public void draw (Canvas canvas, PixelCalculator calculator, boolean shadow ) {
super. draw(canvas, calculator, shadow );
// Setup our "brush"/"pencil"/ whatever...
Paint paint = new Paint();
paint. setTextSize(14);
// Create a Point that represents our GPS-Location
Double lat = FriendFinderMap. this. myLocation. getLatitude() * 1E6;
Double lng = FriendFinderMap. this. myLocation. getLongitude() * 1E6;
Point point = new Point(lat. intValue(), lng. intValue());
int[] myScreenCoords = new int[2];
// Converts lat/lng-Point to OUR coordinates on the screen.
calculator. getPointXY(point, myScreenCoords );
// Draw a circle for our location
RectF oval = new RectF (myScreenCoords [0] - 7, myScreenCoords [1] + 7,
myScreenCoords [0] + 7, myScreenCoords [1] - 7);
// Setup a color for our location
paint. setStyle(Style. FILL);
paint. setARGB(255, 80, 150, 30); // Nice strong Android-Green
// Draw our name
canvas. drawText(getString (R. string. map_overlay_own_name),
myScreenCoords [0] +9, myScreenCoords [1], paint );
// Change the paint to a 'Lookthrough' Android-Green
paint. setARGB(80, 156, 192, 36);
paint. setStrokeWidth(1);
// draw an oval around our location
canvas. drawOval(oval, paint );
// With a black stroke around the oval we drew before.
paint. setARGB(255, 0, 0, 0);
paint. setStyle(Style. STROKE);
canvas. drawCircle(myScreenCoords [0], myScreenCoords [1], 7, paint );
int[] friendScreenCoords = new int[2];
//Draw each friend with a line pointing to our own location.
for(Friend aFriend : FriendFinderMap. this. nearFriends){
lat = aFriend. itsLocation. getLatitude() * 1E6;
lng = aFriend. itsLocation. getLongitude() * 1E6;
point = new Point(lat. intValue(), lng. intValue());
// Converts lat/lng-Point to coordinates on the screen.
calculator. getPointXY(point, friendScreenCoords );
if(Math. abs(friendScreenCoords [0]) < 2000 && Math. abs(friendScreenCoords [1]) < 2000){
// Draw a circle for this friend and his name
oval = new RectF (friendScreenCoords [0] - 7, friendScreenCoords [1] + 7,
friendScreenCoords [0] + 7, friendScreenCoords [1] - 7);
// Setup a color for all friends
paint. setStyle(Style. FILL);
paint. setARGB(255, 255, 0, 0); // Nice red
canvas. drawText(aFriend. itsName, friendScreenCoords [0] +9,
friendScreenCoords [1], paint );
// Draw a line connecting us to the current Friend
paint. setARGB(80, 255, 0, 0); // Nice red, more look through...
paint. setStrokeWidth(2);
canvas. drawLine(myScreenCoords [0], myScreenCoords [1],
friendScreenCoords [0], friendScreenCoords [1], paint );
paint. setStrokeWidth(1);
// draw an oval around our friends location
canvas. drawOval(oval, paint );
// With a black stroke around the oval we drew before.
paint. setARGB(255, 0, 0, 0);
paint. setStyle(Style. STROKE);
canvas. drawCircle(friendScreenCoords [0], friendScreenCoords [1], 7, paint );
}
}
}
} |
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.
| Java: | // Called only the first time the options menu is displayed.
// Create the menu entries.
// Menu adds items in the order shown.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean supRetVal = super.onCreateOptionsMenu(menu);
menu.add(0, 0, getString(R.string.map_menu_zoom_in));
menu.add(0, 1, getString(R.string.map_menu_zoom_out));
menu.add(0, 2, getString(R.string.map_menu_toggle_street_satellite));
menu.add(0, 3, getString(R.string.map_menu_back_to_list));
return supRetVal;
}
@Override
public boolean onOptionsItemSelected(Menu.Item item){
switch (item.getId()) {
case 0:
// Zoom not closer than possible
this.myMapController.zoomTo(Math.min(21, this.myMapView.getZoomLevel() + 1));
return true;
case 1:
// Zoom not farer than possible
this.myMapController.zoomTo(Math.max(1, this.myMapView.getZoomLevel() - 1));
return true;
case 2:
// Switch to satellite view
myMapView.toggleSatellite();
return true;
case 3:
this.finish();
return true;
}
return false;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_I) {
// Zoom not closer than possible
this.myMapController.zoomTo(Math.min(21, this.myMapView.getZoomLevel() + 1));
return true;
} else if (keyCode == KeyEvent.KEYCODE_O) {
// Zoom not farer than possible
this.myMapController.zoomTo(Math.max(1, this.myMapView.getZoomLevel() - 1));
return true;
} else if (keyCode == KeyEvent.KEYCODE_T) {
// Switch to satellite view
myMapView.toggleSatellite();
return true;
}
return false;
} |
Regards,
plusminus
_________________
| Android Development Community / Tutorials
Last edited by plusminus on Wed Nov 28, 2007 2:46 am; edited 2 times in total |
|
| Back to top |
|
 |
flowdi Freshman

Joined: 25 Nov 2007 Posts: 7
|
Posted: Sun Nov 25, 2007 6:45 pm Post subject: coordinates accuracy |
|
|
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
|
|
| Back to top |
|
 |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2102 Location: Germany
|
Posted: Sun Nov 25, 2007 8:27 pm Post subject: |
|
|
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:
Mock LocationProvider - Structure/Explanation (NMEA, $GPRMC)
Regards,
plusminus
_________________
| Android Development Community / Tutorials |
|
| Back to top |
|
 |
quauhtlimtz Junior Developer
Joined: 26 Nov 2007 Posts: 13 Location: Mexico
|
Posted: Tue Nov 27, 2007 11:57 pm Post subject: |
|
|
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.
|
|
| Back to top |
|
 |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2102 Location: Germany
|
Posted: Wed Nov 28, 2007 2:43 am Post subject: |
|
|
| 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.
- Remember the last SelectionIndex, if there was already an ListAdapter before, that could return us a SelectionIndex.
- Update the List Adapter
- Try to set the selectionIndex back
| Java: | private void updateList() {
// .... many lines....
}
ArrayAdapter<String> notes = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, listItems);
// these 3 lines are new
long beforeIndex = 0;
if(this.getListAdapter() != null)
beforeIndex = this.getSelectionRowID();
this.setListAdapter(notes);
// these 3 lines are also new
try{
this.setSelection((int)beforeIndex);
}catch (Exception e){}
} |
Was a good issue, so I added it to the Tutorial-Code
Regards,
plusminus
_________________
| Android Development Community / Tutorials |
|
| Back to top |
|
 |
venkat Senior Developer
Joined: 27 Nov 2007 Posts: 152 Location: India
|
Posted: Mon Dec 03, 2007 4:21 pm Post subject: |
|
|
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 |
|
| Back to top |
|
 |
venkat Senior Developer
Joined: 27 Nov 2007 Posts: 152 Location: India
|
Posted: Mon Dec 03, 2007 4:28 pm Post subject: |
|
|
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
|
|
| Back to top |
|
 |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2102 Location: Germany
|
|
| Back to top |
|
 |
venkat Senior Developer
Joined: 27 Nov 2007 Posts: 152 Location: India
|
Posted: Tue Dec 04, 2007 7:58 am Post subject: |
|
|
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
|
|
| Back to top |
|
 |
venkat Senior Developer
Joined: 27 Nov 2007 Posts: 152 Location: India
|
Posted: Tue Dec 04, 2007 8:00 am Post subject: |
|
|
Sorry, my attachment is here...
| Description: |
| my Friend Finder attachment |
|
| Filesize: |
8.63 KB |
| Viewed: |
18818 Time(s) |

|
|
|
| Back to top |
|
 |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2102 Location: Germany
|
Posted: Tue Dec 04, 2007 9:48 am Post subject: |
|
|
Hello venkat,
answered in the other post.
Regards,
plusminus
_________________
| Android Development Community / Tutorials |
|
| Back to top |
|
 |
cybersat Freshman
Joined: 18 Dec 2007 Posts: 5
|
Posted: Thu Jan 03, 2008 7:19 pm Post subject: Plz help |
|
|
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.
| Description: |
|
| Filesize: |
126 KB |
| Viewed: |
16057 Time(s) |

|
|
|
| Back to top |
|
 |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2102 Location: Germany
|
Posted: Thu Jan 03, 2008 8:18 pm Post subject: |
|
|
Hello cybersat,
in the emulator the GPS-"Signal" is a fake one (Near the Google-Headquarters in MountainView California)!
Have a look at this explanations/tutorial.
If you are fed up with the built in Moch(Fake) Location-Provider, read here.
Regards,
plusminus
_________________
| Android Development Community / Tutorials |
|
| Back to top |
|
 |
glider Freshman
Joined: 03 Jan 2008 Posts: 4
|
Posted: Tue Jan 08, 2008 10:52 am Post subject: |
|
|
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!
|
|
| Back to top |
|
 |
plusminus Site Admin

Joined: 14 Nov 2007 Posts: 2102 Location: Germany
|
| |