Back to project page Mapyst.
The source code is released under:
Apache License
If you think the Android project Mapyst listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * Copyright (C) 2013 Mapyst//from w w w .j a v a 2 s . co m * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mapyst.android; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.Log; public class Compass implements SensorEventListener { // Evan // nicely implements a compass in its own thread, with some extra stuff // (like smoothing) public boolean debug = false; private double smoothRotDeg = 0; // smoothed out rotation (less jittery) private double rotDegVel = 0; // velocity for changing smooth rotation private SensorManager mSensorManager; // manages the sensors private Sensor accelerometer; // basically tells us which direction is down // (gravity) private Sensor magnetometer; // tells us the magnetic declination from the // phone's current orientation private float[] mGravity; // all the gravity data (accelerometer) private float[] mGeomagnetic; // all the magnetic data (magnetometer) // if it is needed, the current degree rotation can be manually requested public double getDegreeRotation() { return smoothRotDeg; } // this is where we'll send rotation data automatically private CompassUpdateListener compassUpdateListener; public Compass(Context context) { mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); } public void setCompassUpdateListener(CompassUpdateListener compassUpdateListener) { this.compassUpdateListener = compassUpdateListener; } public void stop() { mSensorManager.unregisterListener(this); mSensorManager.unregisterListener(this); } public void start() { mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME); mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_GAME); } // provides an interface so data can be sent in a multithread, event like // manner public interface CompassUpdateListener { public void compassUpdate(double compassRotDegs); } // turn our raw data into nice degree data, and send it to the automatic // listener public void updateCompass(double rotRad, double pitch, double roll) { if (rotRad < 0) // negative angles included in raw. This fixes that. rotRad = Math.PI * 2 + rotRad; final double rotDeg = (rotRad) / Math.PI * 180; // simple degree value // [0,...) double rotDegVelMod = 0; // value is used for smoothing. // the purpose of the next few lines is to get velocity in the // correct direction. For example, if we have smoothrot at 358 degs, // and rotDeg at 4 degs, we obviously want to increase smoothrot // with a positive velocity double r1 = rotDeg - smoothRotDeg; if (r1 < 0) r1 += 360; double r2 = smoothRotDeg - rotDeg; if (r2 < 0) r2 += 360; if (r1 < r2) { rotDegVelMod = r1; } else { rotDegVelMod = -r2; } // divV effects the influence of the velocity. a value of // 1 would mean we would just be setting smoothrotdeg to // rot deg. 4 means it adjusts slowly, cutting out some // noise. int divV = 4; rotDegVelMod /= divV; rotDegVel = rotDegVel / divV + rotDegVelMod; smoothRotDeg += rotDegVel; if (smoothRotDeg < 0) // just incase we're below 0, normalize smoothRotDeg += 360; smoothRotDeg %= 360; // in case we went over 360, go back to our normal // range if (debug) logCompassDebug(rotRad, rotDeg, pitch, roll); // debug info if (compassUpdateListener != null) compassUpdateListener.compassUpdate(smoothRotDeg); // send data in // an event like // manner to a // set location // to // be consumed } public void logCompassDebug(double rotRad, double rotDeg, double pitch, double roll) { final String str0 = "ROT RAD:\t\t\t\t\t" + (rotRad); final String str1 = "ROT DEG:\t\t\t\t\t" + rotDeg; final String str2 = "SMOOTH ROT DEG:\t" + smoothRotDeg; final String str3 = "PITCH:\t\t\t\t\t" + pitch; final String str4 = "ROLL:\t\t\t\t\t\t" + roll; String str = str0 + "\n" + str1 + "\n" + str2 + "\n" + str3 + "\n" + str4 + "\n"; str += "\n\n"; Log.d("LOLOLOLOL: Compass Debug", str); } // this is what android calls to give us orientation stuff @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { if (event.values != null) mGravity = event.values.clone(); // clone for continuity } if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { if (event.values != null) mGeomagnetic = event.values.clone(); // clone for continuity } if (mGravity != null && mGeomagnetic != null) { // we got data! float R[] = new float[9]; // will store matrix data float I[] = new float[9]; // will store matrix data // following line uses knowledge of direction of gravity and // magnetic field to get the orientation data boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic); if (success) { float orientation[] = new float[3]; SensorManager.getOrientation(R, orientation); // pull useful // stuff from R double rotRad = 1.0 * orientation[0]; // azimut (rotation / // compass) double pitch = 1.0 * orientation[1]; // pitch double roll = 1.0 * orientation[2]; // roll // System.out.println(orientation[0] + " " + orientation[1] + // " " + orientation[2]); updateCompass(rotRad, pitch, roll); } } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }