Intereting Posts
Устройство отключается в случайном порядке (и появляется несколько раз в автономном режиме) в Eclipse – исправления? Почему поле PackageInfo.signatures является массивом, и когда здесь будет что-то другое, кроме одного? Тестирование нулевых объектов JSON в Java / Android Android NDK: как переопределить onBackPressed в NativeActivity без java? Как включить или отключить GPS программно на Android? SHA-1 отпечаток клеверного сертификата Почему мой ProgressDialog прослушивает ЛЮБОЙ КЛЮЧ (прикосновение) вместо откидывания, чтобы отклонить его? Как добавить данные в charsequence динамически в java? Как начать намерение, если контекст не является контекстом активности, а контекстом приложения Как получить все файлы из папки с ресурсами Управление «устаревшими» предупреждениями в Android-проекте с помощью minSdkVersion Как загрузить собственный Java-класс в C на Android? Использование памяти приложений приложений Xamarin Как удалить уведомление после того, как действие было нажато Проект Android-градиента строит очень медленно

Компас в Android

Я пытаюсь запрограммировать компас с Android с помощью ускорителя и датчика магнитного поля, теперь мне интересно, как получить правильный угол для моего компаса.

Я читаю значения акселерометра и датчика магнитного поля в «accele» и «magne» соответственно. Чтобы получить угол, я выполняю следующее:

float R[] = new float[9]; float I[] = new float[9]; boolean success = SensorManager.getRotationMatrix(R, I, accele, magne); if(success) { float orientation[] = new float[3]; SensorManager.getOrientation(R, orientation); azimuth = orientation[0]; // contains azimuth, pitch, roll .... 

Позже, я использую матрицу вращения, чтобы поместить мою иглу:

 rotation.setRotate(azimuth, compass.getWidth() / 2, compass.getHeight() / 2); canvas.drawBitmap(needle, rotation, null); 

Теперь в документации на getOrientation говорится, что ориентация [0] должна быть вращением вокруг оси z. В документации для TYPE_ORIENTATION говорится, что «азимут, угол между магнитным северным направлением и осью y, вокруг оси z (от 0 до 359). 0 = север, 90 = восток, 180 = юг, 270 = запад».

Мой азимут, однако, не находится между 0 и 359, а примерно от -2 до 2. Что такое азимут от getOrientation и как его преобразовать под углом?

Solutions Collecting From Web of "Компас в Android"

Используйте для преобразования из заданного азимута в радианах (-PI, + PI) в градусы (0, 360)

 float azimuthInRadians = orientation[0]; float azimuthInDegress = (float)Math.toDegrees(azimuthInRadians); if (azimuthInDegress < 0.0f) { azimuthInDegress += 360.0f; } 

Имена переменных, используемые для удобства 😉

Фрагмент кода можно получить из https://github.com/iutinvg/compass

Он не использует устаревшие вещи, применяет фильтр нижних частот.

Я нашел это в ApiDemos Google:

  /* * Copyright (C) 2007 The Android Open Source Project * * 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.example.android.apis.graphics; import android.app.Activity; import android.content.Context; import android.graphics.*; import android.hardware.SensorListener; import android.hardware.SensorManager; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.util.Config; import android.util.Log; import android.view.View; public class Compass extends GraphicsActivity { private static final String TAG = "Compass"; private SensorManager mSensorManager; private SampleView mView; private float[] mValues; private final SensorListener mListener = new SensorListener() { public void onSensorChanged(int sensor, float[] values) { if (Config.LOGD) Log.d(TAG, "sensorChanged (" + values[0] + ", " + values[1] + ", " + values[2] + ")"); mValues = values; if (mView != null) { mView.invalidate(); } } public void onAccuracyChanged(int sensor, int accuracy) { // TODO Auto-generated method stub } }; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); mView = new SampleView(this); setContentView(mView); } @Override protected void onResume() { if (Config.LOGD) Log.d(TAG, "onResume"); super.onResume(); mSensorManager.registerListener(mListener, SensorManager.SENSOR_ORIENTATION, SensorManager.SENSOR_DELAY_GAME); } @Override protected void onStop() { if (Config.LOGD) Log.d(TAG, "onStop"); mSensorManager.unregisterListener(mListener); super.onStop(); } private class SampleView extends View { private Paint mPaint = new Paint(); private Path mPath = new Path(); private boolean mAnimate; private long mNextTime; public SampleView(Context context) { super(context); // Construct a wedge-shaped path mPath.moveTo(0, -50); mPath.lineTo(-20, 60); mPath.lineTo(0, 50); mPath.lineTo(20, 60); mPath.close(); } @Override protected void onDraw(Canvas canvas) { Paint paint = mPaint; canvas.drawColor(Color.WHITE); paint.setAntiAlias(true); paint.setColor(Color.BLACK); paint.setStyle(Paint.Style.FILL); int w = canvas.getWidth(); int h = canvas.getHeight(); int cx = w / 2; int cy = h / 2; canvas.translate(cx, cy); if (mValues != null) { canvas.rotate(-mValues[0]); } canvas.drawPath(mPath, mPaint); } @Override protected void onAttachedToWindow() { mAnimate = true; super.onAttachedToWindow(); } @Override protected void onDetachedFromWindow() { mAnimate = false; super.onDetachedFromWindow(); } } } 

Как вы можете видеть, вы получаете степень от 0 до 360