This is in part an extension to a previous question: Android programming, mapview locationoverlay: how to change the default blue location dot, with another image
I have been working to get the devices location to display on the map (easy with enablemylocation) but I need to replace the default icon (easy enough, sorted that) and then rotate it to correspond to the current device bearing - acquired from GPS, as it needs to be direction of movement, not direction the phone is facing.
I am using 'getbearing()' in the same way as I've been successfully using 'getlatitude()' and 'getaltitude()', but getbearing always returns 0. (To make sure it wasn't the code that rotates the icon that was the problem the variable for the bearing is printed in a textview before anything else happens)
The very peculiar thing is that it has worked twice now for all of 5 seconds, then gone back to returning 0 - so in theory the code seems correct?
Code follows.
Kind regards
Nick
Mainactivity:
package com.nick.kestrel;
import android.content.Context;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
public class KestrelActivity extends MapActivity {
/** Called when the activity is first created. */
static TextView LocationText;
MapView mapView;
@Override
protected boolean isRouteDisplayed() {
return false;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Identifies the textview 'locationtext' as the variable LocationText. Planned usage just for debugging
LocationText = (TextView)findViewById(R.id.locationtext);
//defines the mapview as variable 'mapView' and enables zoom controls
mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
/**
* Code required to receive gps location. Activates GPS provider, and is set to update only after
* at least 10 seconds and a position change of at least 10 metres
*/
LocationListener locationListener = new MyLocationListener();
//setting up the location manager
LocationManager locman = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locman.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, (float) 0.01, locationListener);
//Adds a current location overlay to the map 'mapView' and turns on the map's compass
MyLocation myLocationOverlay = new MyLocation(this, mapView);
myLocationOverlay.enableMyLocation();
myLocationOverlay.enableCompass();
mapView.getOverlays().add(myLocationOverlay);
mapView.postInvalidate();
}
}
mylocationlistener
package com.nick.kestrel;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
public class MyLocationListener implements LocationListener {
private boolean hasbearing;
/**
* Code to run when the listener receives a new location
*/
@Override
public void onLocationChanged(Location locFromGps) {
//Toast.makeText(getApplicationContext(), "Location changed, Lat: "+locFromGps.getLatitude()+" Long: "+ locFromGps.getLongitude(), Toast.LENGTH_SHORT).show();
//LocationText.setText("Your Location: Latitude " +locFromGps.getLatitude() + " Longitude: " +locFromGps.getLongitude());
double dbllatitude = locFromGps.getLatitude();
double dbllongitude = locFromGps.getLongitude();
double dblaltitude = locFromGps.getAltitude();
float bearing = locFromGps.getBearing();
KestrelActivity.LocationText.setText("Your Location: Latitude " + dbllatitude + " Longitude: " +dbllongitude + " Altitude " + dblaltitude + " Bearing: " + bearing);
hasbearing = locFromGps.hasBearing();
if (hasbearing = false) {
//Toast.makeText(getApplicationContext(), "No bearing", Toast.LENGTH_SHORT).show();
}
else
{
//Toast.makeText(getApplicationContext(), "I HAZ bearing: " + locFromGps.getBearing(), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onProviderDisabled(String provider) {
// called when the GPS provider is turned off (user turning off the GPS on the phone)
}
@Override
public void onProviderEnabled(String provider) {
// called when the GPS provider is turned on (user turning on the GPS on the phone)
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// called when the status of the GPS provider changes
}
}
mylocation
package com.nick.kestrel;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Point;
import android.location.Location;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
public class MyLocation extends MyLocationOverlay {
private Context mContext;
static float mOrientation;
public MyLocation(Context context, MapView mapView) {
super(context, mapView);
mContext = context;
}
@Override
protected void drawMyLocation(Canvas canvas, MapView mapView, Location lastFix, GeoPoint myLocation, long when) {
// translate the GeoPoint to screen pixels
Point screenPts = mapView.getProjection().toPixels(myLocation, null);
// create a rotated copy of the marker
Bitmap arrowBitmap = BitmapFactory.decodeResource( mContext.getResources(), R.drawable.pin_icon);
Matrix matrix = new Matrix();
matrix.postRotate(mOrientation);
Bitmap rotatedBmp = Bitmap.createBitmap(
arrowBitmap,
0, 0,
arrowBitmap.getWidth(),
arrowBitmap.getHeight(),
matrix,
true
);
// add the rotated marker to the canvas
canvas.drawBitmap(
rotatedBmp,
screenPts.x - (rotatedBmp.getWidth() / 2),
screenPts.y - (rotatedBmp.getHeight() / 2),
null
);
mapView.postInvalidate();
}
public void setOrientation(float newOrientation) {
mOrientation = newOrientation;
}
}