Разработка нативных приложений Tizen

Использование сенсора ориентации

Показывать лекцию целиком

Сенсор ориентации может измерять три типа направлений.

  • Азимут — это сенсорный компас. Он определяет разность с углом, направленным на север, когда телефон лежит на полу.
  • 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);
    

    Запустите пример.

    Попробуйте поменять положение телефона с помощью панели управления

    Вернуться к учебному плану