Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (9.04 MB, 688 trang )
Figure 14-14.
14.22 Getting location updates with OpenStreetMaps | 585
www.it-ebooks.info
Figure 14-15.
586 | Chapter 14: Location and Map Applications
www.it-ebooks.info
Problem
You need to react to the changes in the device's location and move the map focus to
changed location
Solution
Using LocationListener, an application can request for location updates and then react
to these changes in location
Discussion
• The activity that includes the OSM MapView needs to implement "LocationListener" to be able to request for changes in the device's location. An activity implementing LocationListener will also need to add the unimplemented (abstract)
methods from LocationListener interface (Eclipse will do this for you). We set the
center of the map to the GeoPoint named mapCenter so that the application starts
with map focussed around that point.
• Now we need to get an instance of "LocationManager" and use to to request for
location updates using the requestLocationUpdates method.
• One of the overridden methods (which were abstract in the LocationListener interface) named 'onLocationChanged' we can write the code that we want to be
executed when the location of the device changes.
• In the onLocationChanged method we obtain the latitude and longitude of the new
location and set the map's center to the new GeoPoint.
Example 14-64.
public class LocationChange extends Activity implements LocationListener {
private LocationManager myLocationManager;
private MapView mapView;
private MapController mapController;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView)findViewById(R.id.mapview);
mapController = this.mapView.getController();
mapController.setZoom(15);
GeoPoint mapCenter = new GeoPoint(53554070, -2959520);
mapController.setCenter(mapCenter);
myLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
myLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 100, this);
}
@Override
public void onLocationChanged(Location location) {
int latitude = (int) (location.getLatitude() * 1E6);
14.22 Getting location updates with OpenStreetMaps | 587
www.it-ebooks.info
int longitude = (int) (location.getLongitude() * 1E6);
GeoPoint geopoint = new GeoPoint(latitude, longitude);
mapController.setCenter(geopoint);
mapView.invalidate();
}
@Override
public void onProviderDisabled(String arg0) {
}
@Override
public void onProviderEnabled(String arg0) {
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
}
When the application starts, the map is centered around the mapCenter GeoPoint.
Since the application is listening to location changes, the icon in the top bar of the
phone is visible:
Now using the Emulator controls new GPS coordinates (-122.094095, 37.422006) are
sent to the emulator. The application reacts to it and centers the map around then new
coordinates:
Similarly, different GPS coordinates are given from the Emulator controls and the application centers the map around the new location:
Also, to allow the application to listen for location changes, include these permissions
in the AndroidManifest.
Example 14-65.
android:name="android.permission.ACCESS_COARSE_LOCATION"/>
android:name="android.permission.ACCESS_FINE_LOCATION"/>
android:name="android.permission.ACCESS_NETWORK_STATE" />
android:name="android.permission.INTERNET" />
Source Download URL
The source code for this example may be downloaded from this URL: https://docs.goo
gle.com/leaf?id=0B_rESQKgad5LNGViMzhmM2ItZG
FiZC00NGVhLWJmNjctNTRjNTA0M2QzMjdh&hl=en_US
588 | Chapter 14: Location and Map Applications
www.it-ebooks.info
Figure 14-16.
14.22 Getting location updates with OpenStreetMaps | 589
www.it-ebooks.info
Figure 14-17.
590 | Chapter 14: Location and Map Applications
www.it-ebooks.info
Figure 14-18.
14.22 Getting location updates with OpenStreetMaps | 591
www.it-ebooks.info
Binary Download URL
The executable code for this example may be downloaded from this URL: https://docs
.google.com/leaf?id=0B_rESQKgad5LNDM0NWVlYTUtNjAzNy00ODJjLTkwM
mItNTFhOTFiZjk0ODdk&hl=en_US
592 | Chapter 14: Location and Map Applications
www.it-ebooks.info
CHAPTER 15
Accellerometer
15.1 Using the accelerometer to detect shaking of the device
Thomas Manthey
Problem
Sometimes it makes sense to evaluate not only on-screen input, but also gestures like
tilting or shaking the telephone. But how can you use the accelerometer to detect
whether the phone has been shaken?
Solution
The solution is to register with the accelerometer and to compare the current acceleration values on all three axes to the previous ones. If the values have repeatedly changed
on at least two axises and those changes exceed a high enough threshold, you can clearly
determine shaking.
Discussion
Let us first define shaking as a fairly rapid movement of the device in one direction
followed by further one in another direction, mostly but not necessarily the opposite.
If we want to detect such a shake motion in an activity, we need a connection to the
hardware sensors, those are exposed by the class SensorManager. Furthermore we need
to define a SensorEventListener and register it with the SensorManager.
So the source of our activity starts like this:
Example 15-1.
public class ShakeActivity extends Activity {
/* The connection to the hardware */
private SensorManager mySensorManager;
/* The SensorEventListener lets us wire up to the real hardware events */
private final SensorEventListener mySensorEventListener = new SensorEventListener() {
593
www.it-ebooks.info
public void onSensorChanged(SensorEvent se) {
/* we will fill this one later */
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
/* can be ignored in this example */
}
};
....
To implement SensorEventListener, we have to implement to methods - onSensorCh
anged(SensorEvent se) and onAccuracyChanged(Sensor sensor, int accuracy). The
first one gets called whenever new sensor data is available, the second one whenever
the accuracy of measurement changes, e.g. when the location service switches from
GPS to network-based. In our example we just need to cover onSensorChanged.
Before we continue, let us define some more variables, which will store the information
about values of acceleration and some state.
Example 15-2.
/* Here we store the current values of acceleration, one for each axis */
private float xAccel;
private float yAccel;
private float zAccel;
/* And here the previous ones */
private float xPreviousAccel;
private float yPreviousAccel;
private float zPreviousAccel;
/* Used to suppress the first shaking */
private boolean firstUpdate = true;
/*What acceleration difference would we assume as a rapid movement? */
private final float shakeThreshold = 1.5f;
/* Has a shaking motion been started (one direction) */
private boolean shakeInitiated = false;
I hope that the names and comments do explain enough about what is stored in these
variables, if not, it will become clearer in the next steps. Now let us connect to the
hardware sensors and wire up for their events, onCreate is the perfect place to do so.
Example 15-3.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mySensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); // (1)
mySensorManager.registerListener(mySensorEventListener, mySensorManager
594 | Chapter 15: Accellerometer
www.it-ebooks.info