0

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;
}

}

Community
  • 1
  • 1
Nick
  • 51
  • 2
  • 7

2 Answers2

0

What is location provider? If it NETWORK_PROVIDER, then you won't get bearing, because its accuracy is to low, to detect bearing.

Try your app outside and with GPS_PROVIDER?

Aleksejs Mjaliks
  • 8,647
  • 6
  • 38
  • 44
  • See the Location Manager in the Main Activity - uses GPS_PROVIDER. I can currently get accurate GPS result which is printed in a textview at the top of the window along with altitude and bearing. Bearing is the only result returning 0.0... – Nick Apr 21 '12 at 11:57
  • Problem solved. Will post answer as soon as the system allows. - PICNIC – Nick Apr 21 '12 at 12:17
0

Problem solved! Thanks to Aleksejs for your efforts - turned out it was a case of PICNIC.

I had set the GPS to update at the smallest movement, and as the location was jumping around I assumed it should be able to work out bearing and get on with it.

When testing out the result from 'getSpeed()' I noticed bearing working - turns out you have to move a little further than around the garden to give it time to work out your bearing.

Regards

Nick

Nick
  • 51
  • 2
  • 7