четверг, 13 декабря 2012 г.

Работа с гироскопом в Android

Недавно с толкнулся с работой датчиком гироскопа, в интернете много при много примеров работы с ним, но мне будет интересно вам рассказать про работу с этим датчиком. Тут все просто и понятно так что добро пожаловать под кат.

Для того что бы нам начать работать с гироскопом нужно подключить класс который работает собственно с этим гироскопом, называется он SensorEventListener. Он позволяет работать с датчиком и обращается на прямую с ним, так же нам нужно добавить все методы которые реализует этот класс, когда вы имлемплементируете этот класс в ваш проект имя вашего класса будет подсвечиваться красным цветом когда вы наведете на этот класс мышкой у вас появится табличка в которой будет надпись «Add unsigned methods», кликаете по нему и у вас добавляются в программу нужные методы, а именно onAccuracyChanged() и onSensorChanged(), собственно они нас и интересуют. 

Нас больше всего интересует метод onSensorChanged() так как в нем мы будем получать все параметры с датчика. Давайте начнем, создаем проект самый обычный, и открываем main.xml и сделаем разметочку обычную в которой у нас будет три текствью в которые мы будем выводить наши полученные параметры.

Пишем в нашу разметку следующее:

main.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout     android:id="@+id/TableLayout01"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                xmlns:android="http://schemas.android.com/apk/res/android">
    <TableRow    android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/row_force"
                android:layout_margin="5dip">
        <TextView    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/label_force"
                    android:text="Force:"
                    android:gravity="right"></TextView>
        <TextView    android:layout_height="wrap_content"
                    android:layout_width="fill_parent"
                    android:layout_weight="1"
                    android:id="@+id/value_force"
                    android:text="-"
                    android:layout_marginLeft="5dip"></TextView>
    </TableRow>
    <TableRow    android:layout_height="wrap_content"
                android:layout_width="fill_parent"
                android:id="@+id/row_x"
                android:layout_margin="5dip">
        <TextView    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="X:"
                    android:id="@+id/label_x"
                    android:gravity="right"></TextView>
        <TextView    android:layout_height="wrap_content"
                    android:text="-"
                    android:layout_width="fill_parent"
                    android:layout_weight="1"
                    android:id="@+id/value_x"
                    android:layout_marginLeft="5dip"></TextView>
    </TableRow>
    <TableRow    android:layout_height="wrap_content"
                android:layout_width="fill_parent"
                android:id="@+id/row_y"
                android:layout_margin="5dip">
        <TextView    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Y:"
                    android:id="@+id/label_y"
                    android:gravity="right"></TextView>
        <TextView    android:layout_height="wrap_content"
                    android:text="-"
                    android:layout_width="fill_parent"
                    android:layout_weight="1"
                    android:id="@+id/value_y"
                    android:layout_marginLeft="5dip"></TextView>
    </TableRow>
    <TableRow    android:layout_height="wrap_content"
                android:layout_width="fill_parent"
                android:id="@+id/row_z"
                android:layout_margin="5dip">
        <TextView    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Z:"
                    android:id="@+id/label_z"
                    android:gravity="right"></TextView>
        <TextView    android:layout_height="wrap_content"
                    android:text="-"
                    android:layout_width="fill_parent"
                    android:layout_weight="1"
                    android:id="@+id/value_z"
                    android:layout_marginLeft="5dip"></TextView>
    </TableRow>
</TableLayout>


Здесь мы создали разметку в которой есть три текствью, в которые выводится параметры из наших констант DATA_X, DATA_Y и DATA_Z которые передают текущее местоположение телефона в пространстве. 

Собственно как реализовать передачу параметров датчика в текствью можно увидеть из следующего кода. Открываем MainActivity.java и вставляем вот такую штуковину внутрь этого файла.

MainActivity.java
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;
import java.util.List;
public class MainActivity extends Activity implements SensorEventListener {
        
        /** Объект типа сенсор менеджер */
        SensorManager mSensorManager;
        /** Создали объект типа сенсор для получения данных угла наклона телефона */
        Sensor mAccelerometerSensor;
        Sensor mMagneticFieldSensor;
        /** Наши текствью в которые будем все выводить */
        TextView mForceValueText;
        TextView mXValueText;
        TextView mYValueText;
        TextView mZValueText;
        
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
        
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                // присвоили менеджеру работу с серсором
                mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
                // создали список сенсоров для записи и сортировки
                List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
                // делаем проверку если больше нуля значит все хорошо и начинаем обрабатывать работу датчика
                if (sensors.size() > 0) {
                        // форич для зацикливания работы, что бы не единожды выполнялось, а постоянно
                        for (Sensor sensor : sensors) {
                                // берем данные с акселерометра
                                switch (sensor.getType()) {
                                        case Sensor.TYPE_ACCELEROMETER:
                                                // если пусто значит возвращаем значения сенсора
                                                if (mAccelerometerSensor == null)
                                                        mAccelerometerSensor = sensor;
                                                break;
                                        default:
                                                break;
                                }
                        }
                }
                // привязываем наши объекты к нашей разметке
                mXValueText = (TextView) findViewById(R.id.value_x);
                mYValueText = (TextView) findViewById(R.id.value_y);
                mZValueText = (TextView) findViewById(R.id.value_z);
        }
        
        @Override
        protected void onPause() {
        
                //говорим что данные будем получать из этого окласса
                mSensorManager.unregisterListener(this);
                super.onPause();
        }
        
        @Override
        protected void onResume() {
        
                super.onResume();
                //регистрируем сенсоры в объекты сенсора
                mSensorManager.registerListener(this, mAccelerometerSensor, SensorManager.SENSOR_DELAY_GAME);
                mSensorManager.registerListener(this, mMagneticFieldSensor, SensorManager.SENSOR_DELAY_GAME);
        }
        
        @Override
        public void onSensorChanged(SensorEvent event) {
        
                //создали массив в которые будем записывать наши данные полученые с датчиков
                float[] values = event.values;
                switch (event.sensor.getType()) {
                        case Sensor.TYPE_ACCELEROMETER: {
                                //собственно выводим все полученые параметры в текствьюшки наши
                                mXValueText.setText(String.format("%1.3f", event.values[SensorManager.DATA_X]));
                                mYValueText.setText(String.format("%1.3f", event.values[SensorManager.DATA_Y]));
                                mZValueText.setText(String.format("%1.3f", event.values[SensorManager.DATA_Z]));
                        }
                                break;
                }
        }
        
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        
        }
}


Надеюсь из комментариев понятно что и как происходит, после запуска у вас появится программа в которой, если вы ничего не меняли будет три текстовых поля в которых будут выводить бегающие цифры. Вот так будет выглядеть собственно программа.



Далее вы можете использовать эти параметры как ваша душа пожелает, можете сделать полет по карте, или например гоночку в которой машина будет управляться с помощью этого датчика, ну вообщем применение я думаю найдете. Спасибо за прочтение статьи, всего хорошего, до свидания.


Скачать исходники & Скачать с Git

3 комментария: