글래스에서 오리엔테이션을 관리하기위한 도우미 클래스를 작성했습니다. 그 이유는 내가 여러 번 a Glass app showing real-time transit info의 일부로 계산했기 때문입니다. ,
package com.joulespersecond.oba.glass;
/**
* A utility class containing arithmetic and geometry helper methods.
*
* (from Glass Compass sample)
*/
public class MathUtils {
/**
* Calculates {@code a mod b} in a way that respects negative values (for example,
* {@code mod(-1, 5) == 4}, rather than {@code -1}).
*
* @param a the dividend
* @param b the divisor
* @return {@code a mod b}
*/
public static float mod(float a, float b) {
return (a % b + b) % b;
}
}
... 및 자북을 보정하는 데 사용되는 LocationHelper
을 here를 나타낸다 :
/*
* Copyright (C) 2014 Sean J. Barbeau, University of South Florida
*
* 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.joulespersecond.oba.glass;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import java.util.ArrayList;
/**
* Implements a sensor-based orientation helper for Glass, which allows listeners to receive
* orientation updates
*/
public class OrientationHelper implements SensorEventListener {
public interface Listener {
/**
* Called every time there is an update to the orientation
*
* @param deltaHeading change in heading from last heading value
* @param deltaPitch change in pitch from last pitch value
*/
void onOrientationChanged(float heading, float pitch, float deltaHeading, float deltaPitch);
}
static final String TAG = "OrientationHelper";
Context mContext;
SensorManager mSensorManager;
private float[] mRotationMatrix = new float[16];
private float[] mOrientation = new float[9];
private float[] history = new float[2];
private float mHeading;
private float mPitch;
ArrayList<Listener> mListeners = new ArrayList<Listener>();
public OrientationHelper(Context context) {
mContext = context;
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
}
public synchronized void registerListener(Listener listener) {
if (!mListeners.contains(listener)) {
mListeners.add(listener);
}
// If this is the first listener, make sure we're monitoring the sensors to provide updates
if (mListeners.size() == 1) {
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),
SensorManager.SENSOR_DELAY_UI);
}
}
public synchronized void unregisterListener(Listener listener) {
if (mListeners.contains(listener)) {
mListeners.remove(listener);
}
if (mListeners.size() == 0) {
mSensorManager.unregisterListener(this);
}
}
public synchronized void onResume() {
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),
SensorManager.SENSOR_DELAY_UI);
}
public synchronized void onPause() {
mSensorManager.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);
SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X,
SensorManager.AXIS_Z, mRotationMatrix);
SensorManager.getOrientation(mRotationMatrix, mOrientation);
mHeading = (float) Math.toDegrees(mOrientation[0]);
mPitch = (float) Math.toDegrees(mOrientation[1]);
float xDelta = history[0] - mHeading; // Currently unused
float yDelta = history[1] - mPitch;
history[0] = mHeading;
history[1] = mPitch;
// Use magnetic field to compute true (geographic) north, if data is available
// Note that if Glass doesn't have location info (e.g., it isn't paired and doesn't have a data connection), this should still work, you just can't correct for magnetic north
Float magneticDeclination = LocationHelper.getMagneticDeclination();
if (magneticDeclination != null) {
mHeading += magneticDeclination;
}
// Make sure value is between 0-360
mHeading = MathUtils.mod(mHeading, 360.0f);
for (Listener l : mListeners) {
l.onOrientationChanged(mHeading, mPitch, xDelta, yDelta);
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
여기 MathUtil.java이다. 위치를 결정할 수없는 경우 (예 : Glass가 페어링되지 않았고 데이터 연결이 없음)이 작업은 계속 진행될 수 있습니다. 자기 북쪽을 수정할 수는 없습니다 (오류는 달라질 수 있습니다. 당신이 세계에있는 곳).
는 방위각이 (호) 때 방향에 따라 뭔가를 다시 그릴 것
View
, 피치 변화, 예를 들어, 당신이 리스너 인터페이스를 구현하려는 방향 도우미를 사용하려면
public class MyView extends View implements OrientationHelper.Listener {
private float mHeading;
private float mPitch;
private float mXDelta;
private float mYDelta;
...
@Override
public void onOrientationChanged(float heading, float pitch, float xDelta, float yDelta) {
mHeading = heading;
mPitch = pitch;
mXDelta = xDelta;
mYDelta = yDelta;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
// Draw something based on orientation
...
}
}
당신이 당신의 서비스 또는 활동에 뷰를 만들 때 리스너를 등록 .. 그리고 : 당신의 활동에 mOrientationHelper.onPause();
을
mOrientationHelper = new OrientationHelper(this);
mOrientationHelper.registerListener(mMyView);
그리고 당신의 활동 onResume()
에 mOrientationHelper.onResume();
를 호출센서를 시작/정지하려면을 누르십시오.
Google Glass GDK Compass sample은 Glass에서 방향을 사용하는 또 다른 좋은 예입니다.
이 모든 것은 일반적인 Android에서도 작동합니다. 여기에서 좌표 재 매핑은 Glass의 방향으로 고정됩니다. 오리엔테이션을 변경할 수있는 장치에서 이것을 사용하려면 오리엔테이션에 따라 좌표계를 다시 매핑해야합니다 (자세한 내용은 here 참조).
내 생각에는 좋은 솔루션이지만 GPS가 장착되어 있지 않으므로 Google Glass 앱에서 사용할 수 없습니다 (해당 스마트 폰이있는 스마트 폰과 페어링되지 않았 음) – jan
위에서 설명한 것처럼, LocationHelper는 위치를 사용할 수 없다면 LocationHelper가 null 값을 돌려 주어야한다고 믿습니다. (비록 당신이 세계 어느 곳에 있는지에 따라, 나침반이 자성 북쪽). 또한 Glass가 페어링되지 않은 경우에도 Wi-Fi를 통해 위치 제공 업체를 계속 지원해야한다고 생각합니다. –