Listing 815 Pinning a View to a geographical location

Available for download on Wrax.com

Double lat = 37.422134*1E6; Double lng = -122.084069*1E6; GeoPoint geoPoint = new GeoPoint(lat.intValue(), lng.intValue());

MapView.LayoutParams geoLP;

geoLP = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT,

MapView.LayoutParams.WRAP_CONTENT, geoPoint,

MapView.LayoutParams.TOP_LEFT);

EditText editText2 = new EditText(getApplicationContext()); editText2.setText("Location Pinned");

mapView.addView(editText2, geoLP);

Panning the map will leave the first Textview stationary in the upper left corner, while the second Textview will move to remain pinned to a particular position on the map.

To remove a View from a Map View, call removeView, passing in the View instance you wish to remove, as shown here.

mapView.removeView(editText2);

MAPPING EARTHQUAKES EXAMPLE

The following step-by-step guide demonstrates how to build a map-based Activity for the Earthquake project you started in Chapter 5. The new MapActivity will display a map of recent earthquakes using techniques you learned within this chapter.

1. Create a new earthquake_map.xml layout resource that includes a MapView, being sure to include an android:id attribute and an android:apiKey attribute that contains your Android Maps API key.

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.google.android.maps.MapView android:id="@+id/map_view" android:layout_width="fill_parent" android:layout_height="fill_parent" android:enabled="true" android:clickable="true" android:apiKey="myapikey"

</LinearLayout>

2. Create a new EarthquakeMap Activity that inherits from MapActivity. Use setContentView within onCreate to inflate the earthquake_map resource you created in Step 1.

package com.paad.earthquake; import android.os.Bundle;

import com.google.android.maps.MapActivity;

public class EarthquakeMap extends MapActivity { ©Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.earthquake_map);

©Override protected boolean isRouteDisplayed() { return false;

3. Update the application manifest to include your new EarthquakeMap Activity and import the map library.

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.paad.earthquake"> <application android:icon="©drawable/icon"> <activity android:name=".Earthquake"

android:label="©string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>

<activity android:name=".Preferences"

android:label="Earthquake Preferences"/> <activity android:name=".EarthquakeMap"

android:label="View Earthquakes"/> <provider android:name=".EarthquakeProvider"

android:authorities="com.paad.provider.earthquake" /> <uses-library android:name="com.google.android.maps"/> </application>

<uses-permission android:name="android.permission.INTERNET"/> </manifest>

4. Add a new menu option to the Earthquake Activity to display the EarthquakeMap Activity.

4.1. Start by adding a new string to the strings.xml resource for the menu text.

<?xml version="1.0" encoding="autf-8"?> <resources>

<string name="app_name">Earthquake</string> <string name="quake_feed">

http://earthquake.usgs.gov/eqcenter/catalogs/1day-M2.5.xml </string>

<string name="menu_update">Refresh Earthquakes</string> <string name="auto_update_prompt">Auto Update?</string> <string name="update freq prompt">Update Frequency</string> <string name="min_quake_mag_prompt">

Minimum Quake Magnitude </string>

<string name="menu_preferences">Preferences</string> <string name="menu_earthquake_map">Earthquake Map</string>

</resources>

Prepared for ASHLEE KABAT, email: [email protected] Order number: 56760408 This PDF is for the purchaser's personal use in accordance with the Wrox Terms of Service and under US copyright as stated on this book's copyright page. If you did not purchase this copy, please visit www.wrox.com to purchase your own copy.

4.2. Then add a new menu identifier before modifying the onCreateOptionsMenu handler to add the new Menu Item. It should use the text defined in Step 4.1, and when selected it should fire an Intent to explicitly start the EarthquakeMap Activity. static final private int MENU_EARTHQUAKE_MAP = Menu.FIRST+2;

©Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu);

menu.add(0, MENU_UPDATE, Menu.NONE, R.string.menu_update); menu.add(0, MENU_PREFERENCES, Menu.NONE,

R.string.menu_preferences); Intent startMap = new Intent(this, EarthquakeMap.class); menu.add(0, MENU_EARTHQUAKE_MAP, Menu.NONE,

R.string.menu_earthquake_map).setIntent(startMap);

return true;

5. Now create a new EarthquakeOverlay class that extends Overlay. It will draw the position and magnitude of each earthquake on the Map View.

package com.paad.earthquake;

import java.util.ArrayList;

import android.database.Cursor;

import android.database.DataSetObserver;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.Point;

import android.graphics.RectF;

import com.google.android.maps.GeoPoint;

import com.google.android.maps.MapView;

import com.google.android.maps.Overlay;

import com.google.android.maps.Projection;

public class EarthquakeOverlay extends Overlay { ©Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { Projection projection = mapView.getProjection();

5.1. Add a new constructor that accepts a Cursor to the current earthquake data, and store that Cursor as an instance variable. Cursor earthquakes;

public EarthquakeOverlay(Cursor cursor, ContentResolver resolver) { super();

earthquakes = cursor;

5.2. Create a new refreshQuakeLocations method that iterates over the results Cursor and extracts the location of each earthquake, extracting the latitude and longitude before storing each coordinate in a List of GeoPoints.

ArrayList<GeoPoint> quakeLocations;

private void refreshQuakeLocations() { if (earthquakes.moveToFirst()) do {

Double lat =

earthquakes.getFloat(EarthquakeProvider.LATITUDE_COLUMN) * 1E6; Double lng =

earthquakes.getFloat(EarthquakeProvider.LONGITUDE_COLUMN) * 1E6;

GeoPoint geoPoint = new GeoPoint(lng.intValue(), lat.intValue());

quakeLocations.add(geoPoint); } while(earthquakes.moveToNext());

5.3. Call refreshQuakeLocations from the Overlay's constructor. Also register a DataSetObserver on the results Cursor that refreshes the Earthquake Location list if a change in the Earthquake Cursor is detected.

public EarthquakeOverlay(Cursor cursor) { super();

earthquakes = cursor;

quakeLocations = new ArrayList<GeoPoint>(); refreshQuakeLocations();

earthquakes.registerDataSetObserver(new DataSetObserver() { @Override public void onChanged() { refreshQuakeLocations();

5.4. Complete the EarthquakeOverlay by overriding the draw method to iterate over the list of GeoPoints, drawing a marker at each earthquake location. In this example a simple red circle is drawn, but you could easily modify it to include additional information, such as by adjusting the size of each circle based on the magnitude of the quake.

@Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { Projection projection = mapView.getProjection();

// Create and setup your paint brush Paint paint = new Paint(); paint.setARGB(250, 255, 0, 0); paint.setAntiAlias(true); paint.setFakeBoldText(true);

for (GeoPoint point : quakeLocations) { Point myPoint = new Point(); projection.toPixels(point, myPoint);

RectF oval = new RectF(myPoint.x-rad, myPoint.y-rad, myPoint.x+rad, myPoint.y+rad);

canvas.drawOval(oval, paint);

6. Return to the EarthquakeMap class. Within the onCreate method, create a Cursor that returns the earthquakes you want to display on the map. Use this Cursor to create a new EarthquakeOverlay before adding the new instance to the Map View's list of Overlays.

Cursor earthquakeCursor;

©Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.earthquake_map);

String earthquakeURI = EarthquakeProvider.CONTENT_URI; earthquakeCursor = getContentResolver().query(earthquakeURI, null, null, null, null);

MapView earthquakeMap = (MapView)findViewById(R.id.map_view); EarthquakeOverlay eo = new EarthquakeOverlay(earthquakeCursor); earthquakeMap.getOverlays().add(eo);

7. Finally, override onResume to call requery on the Earthquake result set whenever this Activity becomes visible. Also, override onPause and onDestroy to optimize use of the Cursor resources.

©Override public void onResume() {

earthquakeCursor.requery(); super.onResume();

©Override public void onPause() {

earthquakeCursor.deactivate(); super.onPause();

©Override public void onDestroy() { earthquakeCursor.close();

super.onDestroy();

8. If you run the application and select Earthquake Map from the main menu, your application should appear as shown in Figure 8-7.

All code snippets in this example are part of the Chapter 8 Earthquake project, available for download at Wrox.com.

SUMMARY

Location-based services, the Geocoder, and MapViews are available to create intuitive, location-aware applications that feature geographical information.

This chapter introduced the Geocoder and showed how to perform forward and reverse geocoding lookups to translate between map coordinates and street addresses. You were introduced to location-based services, used to find the current geographical position of a device. You also used them to track movement and create proximity alerts.

Then you created interactive map applications. Using Overlays and Views you annotated MapViews with 2D graphics, as well as markers in the form of OverlayItems and Views (including View Groups and layouts).

In Chapter 9 you'll learn how to work from the background. You'll be introduced to the Service component and learn how to move processing onto background threads. To interact with the user while hidden from view, you'll use Toasts to display transient messages and the Notification Manager to ring, vibrate, and flash the phone.

FIGURE 8-7
Mobile Apps Made Easy

Mobile Apps Made Easy

Quick start guide to skyrocket your offline and online business success with mobile apps. If you know anything about mobile devices, you’ve probably heard that famous phrase coined by one of the mobile device’s most prolific creators proclaiming that there’s an app for pretty much everything.

Get My Free Training Guide


Post a comment