Использование сенсора ориентации
Сенсор ориентации может измерять три типа направлений.
- Азимут — это сенсорный компас. Он определяет разность с углом, направленным на север, когда телефон лежит на полу.
- Pitch (тангаж) — показывает угол от оси Z, когда телефон находится в вертикальном положении. Он работает как штурвал в самолете или автомобиле в компьютерных играх.
- Roll (рыскание) показывает угол с осью Y, когда телефон лежит в пейзажном положении.
Обычно используется для управления скоростью самолета или автомобиля в играх.
Когда телефон находится в портретном положении, его горизонтальным направлением будет ось X, а вертикальным - Y, прямым и обратным направлением будет ось Z. Используйте панель управления в эмуляторе для изменения положения устройства.
Определение поддержки сенсора ориентации устройством
Создайте проект 'SensorOrientation.' Внесите изменения в начало файла исходного кода.
#include "sensororientation.h" #include <sensor.h> typedef struct appdata { Evas_Object *win; Evas_Object *conform; Evas_Object *label0; Evas_Object *label1; } appdata_s;
sensor.h — это файл заголовка библиотеки различных сенсоров.
Добавим две функции выше create_base_gui().
static void show_is_supported(appdata_s *ad) { char buf[PATH_MAX]; bool is_supported = false; sensor_is_supported(SENSOR_ORIENTATION, &is_supported); sprintf(buf, "Orientation Sensor is %s", is_supported ? "support" : "not support"); elm_object_text_set(ad->label0, buf); } static void my_box_pack(Evas_Object *box, Evas_Object *child, double h_weight, double v_weight, double h_align, double v_align) { /* create a frame we shall use as padding around the child widget */ Evas_Object *frame = elm_frame_add(box); /* use the medium padding style. there is "pad_small", "pad_medium", * "pad_large" and "pad_huge" available as styles in addition to the * "default" frame style */ elm_object_style_set(frame, "pad_medium"); /* set the input weight/aling on the frame insted of the child */ evas_object_size_hint_weight_set(frame, h_weight, v_weight); evas_object_size_hint_align_set(frame, h_align, v_align); { /* tell the child that is packed into the frame to be able to expand */ evas_object_size_hint_weight_set(child, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); /* fill the expanded area (above) as opposaed to center in it */ evas_object_size_hint_align_set(child, EVAS_HINT_FILL, EVAS_HINT_FILL); /* actually put the child in the frame and show it */ evas_object_show(child); elm_object_content_set(frame, child); } /* put the frame into the box instead of the child directly */ elm_box_pack_end(box, frame); /* show the frame */ evas_object_show(frame); }
show_is_supported() - это функция, определяющая поддерживается ли сенсор устройством.
sensor_is_supported(sensor_type_e, bool *) - это API, который определяет поддерживается ли данный сенсор
my_box_pack() - это функция, которая добавляет контролы к контейнеру Box. Нам нужно вызвать функцию show_is_supported() при запуске приложения. Добавьте код в конец функции create_base_gui() function.
/* Conformant */ ad->conform = elm_conformant_add(ad->win); elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW); elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE); evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_win_resize_object_add(ad->win, ad->conform); evas_object_show(ad->conform); { /* child object - indent to how relationship */ Evas_Object * box, *btn; /* A box to put things in verticallly - default mode for box */ box = elm_box_add(ad->win); evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_object_content_set(ad->conform, box); evas_object_show(box); { /* child object - indent to how relationship */ /* Label-0 */ ad->label0 = elm_label_add(ad->conform); elm_object_text_set(ad->label0, "Msg - "); my_box_pack(box, ad->label0, 1.0, 0.0, -1.0, 0.0); /* Label-1 */ ad->label1 = elm_label_add(ad->conform); elm_object_text_set(ad->label1, "Orientation - "); my_box_pack(box, ad->label1, 1.0, 1.0, -1.0, 0.0); } } /* Show window after base gui is set up */ evas_object_show(ad->win); show_is_supported(ad); }
Запустите проект
Запрос события сенсора ориентации
Добавьте код в начало файла исходного кода.
typedef struct appdata { Evas_Object *win; Evas_Object *conform; Evas_Object *label0; Evas_Object *label1; } appdata_s; typedef struct _sensor_info { sensor_h sensor; /**< Sensor handle */ sensor_listener_h sensor_listener; } sensorinfo; static sensorinfo sensor_info;
sensorinfo — это структура, содержащая тип сенсорного объекта и переменную слушателя событий
sensor_info — глобальная переменная для структуры.
Добавьте две функции выше create_base_gui() function.
static void _new_sensor_value(sensor_h sensor, sensor_event_s *sensor_data, void *user_data) { if( sensor_data->value_count < 3 ) return; char buf[PATH_MAX]; appdata_s *ad = (appdata_s*)user_data; sprintf(buf, "Azimuth : %0.1f <br>Pitch : %0.1f <br>Roll : %0.1f", sensor_data->values[0], sensor_data->values[1], sensor_data->values[2]); elm_object_text_set(ad->label1, buf); } static void start_orientation_sensor(appdata_s *ad) { sensor_error_e err = SENSOR_ERROR_NONE; sensor_get_default_sensor(SENSOR_ORIENTATION, &sensor_info.sensor); err = sensor_create_listener(sensor_info.sensor, &sensor_info.sensor_listener); sensor_listener_set_event_cb(sensor_info.sensor_listener, 100, _new_sensor_value, ad); sensor_listener_start(sensor_info.sensor_listener); }
_new_sensor_value() - это функция вызова события для сенсора ориентации.
Выведем новые сенсорные данные на экран. Сенсорные данные передаются в качестве второго параметра в виде массива. Данные направления, такие, как азимут, тангаж и рыскание сохраняются в переменных values[0], vales[1], и values[2], соответственно.
start_orientation_sensor() - это функция, которая запускает сенсор ориентации и определяет события.
sensor_get_default_sensor(sensor_type_e, sensor_h *) - это API, который возвращает объект sensor . Использование значения SENSOR_ORIENTATION в качестве первого параметра возвращает объект orientation sensor второму параметру.
sensor_create_listener(sensor_h, sensor_listener_h *) - это API, который создает объект listener. Использование объекта sensor в качестве второго параметра возвращает объект listener второму параметру.
sensor_listener_set_event_cb(sensor_listener_h, unsigned int, sensor_event_cb, void *) - это API, который определяет функцию вызова для слушателя. Параметры передаются в следующем порядке: слушатель события, временной интервал (в миллисекундах), имя функции вызова, данные пользователя.
sensor_listener_start(sensor_listener_h) - это API, который запускает слушатель.
Вызовем функцию слушателя событий в конце функции create_base_gui().
/* Show window after base gui is set up */ evas_object_show(ad->win); show_is_supported(ad); start_orientation_sensor(ad); }
При запуске приложения телефон может оказаться в пейзажном режиме за счет поворота телефона. Исправим это положение. В начале функции create_base_gui() есть следующие строки.
int rots[4] = { 0, 90, 180, 270 }; elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
Замените ее на следующий код.
int rots[1] = { 0 }; elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 1);
Запустите пример.
Попробуйте поменять положение телефона с помощью панели управления