android maps auto-rotate

后端 未结 5 1764
自闭症患者
自闭症患者 2020-12-12 19:45

If you open the Google maps app, there is a button on the top right of the screen that you can press to center the map on your current location. The button\'s icon then chan

相关标签:
5条回答
  • 2020-12-12 20:06

    It is possible by registering your application with Sensor Listener for Orientation and getting the angle relative to true north inside onSensorChanged and update camera accordingly. Angle can be used for bearing. The following code can be used:

    Instead of using Sensor.TYPE_ORIENTATION try using getOrinetation api. Sensor.TYPE_ORIENTATION
    has been deprecated.
    
    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        if (sensorManager != null)
            sensorManager.registerListener(this,
                    sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                    SensorManager.SENSOR_DELAY_GAME);
    }
    
    public void onSensorChanged(SensorEvent event) {
    
        float degree = Math.round(event.values[0]);
    
        Log.d(TAG, "Degree ---------- " + degree);
    
        updateCamera(degree);
    
    }
    
    private void updateCamera(float bearing) {
        CameraPosition oldPos = googleMap.getCameraPosition();
    
        CameraPosition pos = CameraPosition.builder(oldPos).bearing(bearing)
                .build();
    
        googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(pos));
    
    }
    
    0 讨论(0)
  • 2020-12-12 20:15

    Ok here's how I think it should be done a year later. Please correct me if you spot any issues.

    Most of the following code deals with a discrepancy between coordinate systems. I'm using a rotation vector sensor. From the docs: Y is tangential to the ground at the device's current location and points towards magnetic north. Bearing in google maps, on the other hand, seems to point to true north. this page shows how the conversion is done

    1) get the current declination from your current GPS location

    @Override
    public void onLocationChanged(Location location) {
        GeomagneticField field = new GeomagneticField(
                (float)location.getLatitude(),
                (float)location.getLongitude(),
                (float)location.getAltitude(),
                System.currentTimeMillis()
            );
    
        // getDeclination returns degrees
        mDeclination = field.getDeclination();
    } 
    

    2) calculate bearing from declination and magnetic north

        @Override
    public void onSensorChanged(SensorEvent event) {
        if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
            SensorManager.getRotationMatrixFromVector(
                    mRotationMatrix , event.values);
            float[] orientation = new float[3];
            SensorManager.getOrientation(mRotationMatrix, orientation);
            float bearing = Math.toDegrees(orientation[0]) + mDeclination;
            updateCamera(bearing);  
        }
    }
    

    3) update maps

    private void updateCamera(float bearing) {
        CameraPosition oldPos = mMap.getCameraPosition();
    
        CameraPosition pos = CameraPosition.builder(oldPos).bearing(bearing).build();
                mMap.moveCamera(CameraUpdateFactory.newCameraPosition(pos));
    }
    
    0 讨论(0)
  • 2020-12-12 20:21

    The new Location class already gives you the bearing automatically, why not use it?

    Sample code:

    private void updateCameraBearing(GoogleMap googleMap, Location myLoc) {
        if ( googleMap == null) return;
        CameraPosition camPos = CameraPosition
                .builder(googleMap.getCameraPosition())
                .bearing(myLoc.getBearing())
                 // if you want to stay centered - then add the line below
                .target(new LatLng(myLoc.getLatitude(), myLoc.getLongitude()))
                .build();
        googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(camPos));
    }
    
    0 讨论(0)
  • 2020-12-12 20:25

    Sorry, you'll have to implement it yourself with the sensor manager and the camera

    if those functions were available to the map api V2 they would certainly be either on the GoogleMap or the UiSettings

    0 讨论(0)
  • 2020-12-12 20:33

    I have successfully implemented aleph_null solution and here I will add some details that are not mentioned in the accepted solution:

    For the above solution to work you need to implement android.hardware.SensorEventListener interface.

    You need also to register to the SensorEventListener in your onResume and onPause methods as follow:

    @Override
        protected void onResume() {
         super.onResume();
         mSensorManager.registerListener(this,
                 mRotVectSensor,
                 SensorManager.SENSOR_STATUS_ACCURACY_LOW);
        }
    
    @Override
    protected void onPause() {
        // unregister listener
        super.onPause();
        mSensorManager.unregisterListener(this);
    }
    

    Note to "@Bytecode": To avoid flickering, use low value for the sampling period, something like SensorManager.SENSOR_STATUS_ACCURACY_LOW.

    I have noticed also that the sensor sends sometime more data than the device can handle and as a result, the map camera starts to move in a strange way!

    To control the amount of data handled by onSensorChanged, I suggest the following implementation:

    @Override
    public void onSensorChanged(SensorEvent event) {
        if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
            SensorManager.getRotationMatrixFromVector(
                    mRotationMatrix, event.values);
            float[] orientation = new float[3];
            SensorManager.getOrientation(mRotationMatrix, orientation);
            if (Math.abs(Math.toDegrees(orientation[0]) - angle) > 0.8) {
                float bearing = (float) Math.toDegrees(orientation[0]) + mDeclination;
                updateCamera(bearing);
            }
            angle = Math.toDegrees(orientation[0]);
        }
    }
    
    0 讨论(0)
提交回复
热议问题