Page Example

Geofence Sample Overview

Mobile native

The Geofence sample application demonstrates how to manage fences and places using the Geofence API.

The following figure illustrates the main view of the Geofence application.

Figure: Application main view

Application control view

In the main view, the user can select one of the available operations.

Prerequisites

To ensure proper application execution, the following privileges must be set:

  • http://tizen.org/privilege/location
  • http://tizen.org/privilege/network.get

Implementation

Application Main View

The create_base_gui() function has a panel for 10 buttons and 3 entries for displaying the result.

static void
create_base_gui(appdata_s *ad)
{
   Evas_Object *grid, *panel;
   Elm_Object_Item *nf_it;

   // Window
   ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
   elm_win_conformant_set(ad->win, EINA_TRUE);
   elm_win_autodel_set(ad->win, EINA_TRUE);
   evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);

   // Conformant
   ad->conform = elm_conformant_add(ad->win);
   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);

   // Indicator
   elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
   elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE);

   // Layout
   ad->layout = elm_layout_add(ad->conform);
   evas_object_size_hint_weight_set(ad->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   elm_layout_theme_set(ad->layout, "layout", "application", "default");
   elm_object_content_set(ad->conform, ad->layout);
   evas_object_show(ad->layout);

   ad->nf = elm_naviframe_add(ad->layout);
   elm_object_part_content_set(ad->layout, "elm.swallow.content", ad->nf);
   eext_object_event_callback_add(ad->nf, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
   evas_object_show(ad->nf);

   // Grid
   grid = elm_grid_add(ad->nf);
   evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_object_content_set(ad->nf, grid);

   // Entry
   ad->entry = create_entry(grid);
   elm_grid_pack(grid, ad->entry, 0, 5, 90, 10);

   ad->event_entry = create_entry(grid);
   elm_grid_pack(grid, ad->event_entry, 0, 15, 90, 10);

   ad->status_entry = create_entry(grid);
   elm_grid_pack(grid, ad->status_entry, 0, 25, 90, 10);

   // Panel
   panel = create_panel(grid, ad);
   elm_grid_pack(grid, panel, 0, 55, 100, 45);

   nf_it = elm_naviframe_item_push(ad->nf, "Geofence", NULL, NULL, grid, NULL);
   elm_naviframe_item_pop_cb_set(nf_it, win_delete_request_cb, ad);
   // Show the window after the base GUI is set up
   evas_object_show(ad->win);
}

The create_panel_basic_content() function creates 10 buttons.

static Evas_Object *
create_panel_basic_content(Evas_Object *parent, appdata_s *ad)
{
   Evas_Object *table;

   table = elm_table_add(parent);
   elm_table_padding_set(table, 10, 0);

   ad->create_btn = elm_button_add(table);
   evas_object_size_hint_weight_set(ad->create_btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(ad->create_btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_object_text_set(ad->create_btn, "<font_size=30>Create</font_size>");
   elm_object_disabled_set(ad->create_btn, EINA_FALSE);
   evas_object_smart_callback_add(ad->create_btn, "clicked", clicked_create_cb, ad);
   evas_object_show(ad->create_btn);
   elm_table_pack(table, ad->create_btn, 0, 0, 1, 1);

   ad->fence_status_btn = elm_button_add(table);
   evas_object_size_hint_weight_set(ad->fence_status_btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(ad->fence_status_btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_object_text_set(ad->fence_status_btn, "<font_size=30>Fence Status</font_size>");
   elm_object_disabled_set(ad->fence_status_btn, EINA_TRUE);
   evas_object_smart_callback_add(ad->fence_status_btn, "clicked", show_popup_cb, ad);
   evas_object_show(ad->fence_status_btn);
   elm_table_pack(table, ad->fence_status_btn, 1, 0, 1, 1);

   ad->add_fence_btn = elm_button_add(table);
   evas_object_size_hint_weight_set(ad->add_fence_btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(ad->add_fence_btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_object_text_set(ad->add_fence_btn, "<font_size=30>Add Fence</font_size>");
   elm_object_disabled_set(ad->add_fence_btn, EINA_TRUE);
   evas_object_smart_callback_add(ad->add_fence_btn, "clicked", show_popup_cb, ad);
   evas_object_show(ad->add_fence_btn);
   elm_table_pack(table, ad->add_fence_btn, 0, 1, 1, 1);

   ad->add_place_btn = elm_button_add(table);
   evas_object_size_hint_weight_set(ad->add_place_btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(ad->add_place_btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_object_text_set(ad->add_place_btn, "<font_size=30>Add Place</font_size>");
   elm_object_disabled_set(ad->add_place_btn, EINA_TRUE);
   evas_object_smart_callback_add(ad->add_place_btn, "clicked", show_popup_cb, ad);
   evas_object_show(ad-"add_place_btn);
   elm_table_pack(table, ad-"add_place_btn, 1, 1, 1, 1);

   ad->start_btn = elm_button_add(table);
   evas_object_size_hint_weight_set(ad->start_btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(ad->start_btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_object_text_set(ad->start_btn, "<font_size=30>Start</font_size>");
   elm_object_disabled_set(ad->start_btn, EINA_TRUE);
   evas_object_smart_callback_add(ad->start_btn, "clicked", show_popup_cb, ad);
   evas_object_show(ad->start_btn);
   elm_table_pack(table, ad->start_btn, 0, 2, 1, 1);

   ad->stop_btn = elm_button_add(table);
   evas_object_size_hint_weight_set(ad->stop_btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(ad->stop_btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_object_text_set(ad->stop_btn, "<font_size=30>Stop</font_size>");
   elm_object_disabled_set(ad->stop_btn, EINA_TRUE);
   evas_object_smart_callback_add(ad->stop_btn, "clicked", show_popup_cb, ad);
   evas_object_show(ad->stop_btn);
   elm_table_pack(table, ad->stop_btn, 1, 2, 1, 1);

   ad->remove_fence_btn = elm_button_add(table);
   evas_object_size_hint_weight_set(ad->remove_fence_btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(ad->remove_fence_btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_object_text_set(ad->remove_fence_btn, "<font_size=30>Remove Fence</font_size>");
   elm_object_disabled_set(ad->remove_fence_btn, EINA_TRUE);
   evas_object_smart_callback_add(ad->remove_fence_btn, "clicked", show_popup_cb, ad);
   evas_object_show(ad->remove_fence_btn);
   elm_table_pack(table, ad->remove_fence_btn, 0, 3, 1, 1);

   ad->remove_place_btn = elm_button_add(table);
   evas_object_size_hint_weight_set(ad->remove_place_btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(ad->remove_place_btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_object_text_set(ad->remove_place_btn, "<font_size=30>Remove Place</font_size>");
   elm_object_disabled_set(ad->remove_place_btn, EINA_TRUE);
   evas_object_smart_callback_add(ad->remove_place_btn, "clicked", show_popup_cb, ad);
   evas_object_show(ad->remove_place_btn);
   elm_table_pack(table, ad->remove_place_btn, 1, 3, 1, 1);

   ad->update_place_btn = elm_button_add(table);
   evas_object_size_hint_weight_set(ad->update_place_btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(ad->update_place_btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_object_text_set(ad->update_place_btn, "<font_size=30>Update Place</font_size>");
   elm_object_disabled_set(ad->update_place_btn, EINA_TRUE);
   evas_object_smart_callback_add(ad->update_place_btn, "clicked", show_popup_cb, ad);
   evas_object_show(ad->update_place_btn);
   elm_table_pack(table, ad->update_place_btn, 0, 4, 1, 1);

   ad->destroy_btn = elm_button_add(table);
   evas_object_size_hint_weight_set(ad->destroy_btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(ad->destroy_btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
   elm_object_text_set(ad->destroy_btn, "<font_size=30<Destroy</font_size>");
   elm_object_disabled_set(ad->destroy_btn, EINA_TRUE);
   evas_object_smart_callback_add(ad->destroy_btn, "clicked", clicked_destroy_cb, ad);
   evas_object_show(ad->destroy_btn);
   elm_table_pack(table, ad->destroy_btn, 1, 4, 1, 1);

   evas_object_show(table);

   return table;
}

The show_popup_cb() function has several functions for the remaining buttons.

static void
show_popup_cb(void *data, Evas_Object *obj, void *event_info)
{
   appdata_s *ad = (appdata_s *)data;

   if (obj == ad->fence_status_btn)
      select_fence_list(ad, get_status_cb);
   else if (obj == ad->add_fence_btn)
      select_place_list(ad, add_fence_cb);
   else if (obj == ad->add_place_btn)
      insert_place_name(ad, ad->add_place_btn, -1, NULL);
   else if (obj == ad->start_btn)
      select_fence_list(ad, start_fence_cb);
   else if (obj == ad->stop_btn)
      select_fence_list(ad, stop_fence_cb);
   else if (obj == ad->remove_fence_btn)
      select_fence_list(ad, remove_fence_cb);
   else if (obj == ad->remove_place_btn)
      select_place_list(ad, remove_place_cb);
   else if (obj == ad->update_place_btn)
      select_place_list(ad, update_place_cb);
}

Application Operation

Each application operation is activated by clicking the applicable button on the main view:

  • Create a geofence manager handle:

    static void
    clicked_create_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
    {
       appdata_s *ad = (appdata_s *) data;
       int ret = 0;
    
       ret = geofence_manager_create(&(ad->geo_manager));
    
       elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_manager_create</align></font_size>");
       showError(ad->event_entry, ret);
       elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left></align></font_size>");
    
       if (ret == GEOFENCE_MANAGER_ERROR_NONE) 
       {
          elm_object_disabled_set(ad->create_btn, EINA_TRUE);
          elm_object_disabled_set(ad->fence_status_btn, EINA_FALSE);
          elm_object_disabled_set(ad->add_fence_btn, EINA_FALSE);
          elm_object_disabled_set(ad->add_place_btn, EINA_FALSE);
          elm_object_disabled_set(ad->start_btn, EINA_FALSE);
          elm_object_disabled_set(ad->stop_btn, EINA_FALSE);
          elm_object_disabled_set(ad->remove_fence_btn, EINA_FALSE);
          elm_object_disabled_set(ad->remove_place_btn, EINA_FALSE);
          elm_object_disabled_set(ad->update_place_btn, EINA_FALSE);
          elm_object_disabled_set(ad->destroy_btn, EINA_FALSE);
    
          geofence_manager_set_geofence_event_cb(ad->geo_manager, show_event_cb, ad);
          geofence_manager_set_geofence_state_changed_cb(ad->geo_manager, show_state_changed_cb, ad);
       }
    }
    
  • Destroy the geofence manager handle:

    static void
    clicked_destroy_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
    {
       appdata_s *ad = (appdata_s *) data;
       int ret = 0;
    
       geofence_manager_unset_geofence_event_cb(ad->geo_manager);
       geofence_manager_unset_geofence_state_changed_cb(ad->geo_manager);
    
       ret = geofence_manager_destroy(ad->geo_manager);
    
       elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_manager_destroy</align></font_size>");
       showError(ad->event_entry, ret);
       elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left></align></font_size>");
    
       if (ret == GEOFENCE_MANAGER_ERROR_NONE) 
       {
          elm_object_disabled_set(ad->create_btn, EINA_FALSE);
          elm_object_disabled_set(ad->fence_status_btn, EINA_TRUE);
          elm_object_disabled_set(ad->add_fence_btn, EINA_TRUE);
          elm_object_disabled_set(ad->add_place_btn, EINA_TRUE);
          elm_object_disabled_set(ad->start_btn, EINA_TRUE);
          elm_object_disabled_set(ad->stop_btn, EINA_TRUE);
          elm_object_disabled_set(ad->remove_fence_btn, EINA_TRUE);
          elm_object_disabled_set(ad->remove_place_btn, EINA_TRUE);
          elm_object_disabled_set(ad->update_place_btn, EINA_TRUE);
          elm_object_disabled_set(ad->destroy_btn, EINA_TRUE);
    
          ad->geo_manager = NULL;
       }
    }
    
  • Get the status of the selected fence:

    static void
    get_status_cb(void *data, Evas_Object *obj, void *event_info)
    {
       appdata_s *ad = evas_object_data_get(obj, "app_data");
       int geofence_id = (int) data;
       geofence_status_h status = NULL;
       geofence_state_e state;
       int seconds = 0;
       int ret = 0;
       char buf[50] = {};
       char *state_str[] = {"UNCERTAIN", "IN", "OUT"};
    
       evas_object_del(ad->popup);
    
       ret = geofence_status_create(geofence_id, &status);
       elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_status_create</align></font_size>");
       showError(ad->event_entry, ret);
       elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left></align></font_size>");
    
       if (ret != GEOFENCE_MANAGER_ERROR_NONE)
          return;
    
       ret = geofence_status_get_state(status, &state);
       elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_status_get_state</align></font_size>");
       showError(ad->event_entry, ret);
       elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left></align></font_size>");
    
       ret = geofence_status_get_duration(status, &seconds);
       elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_status_get_duration</align></font_size>");
       showError(ad->event_entry, ret);
       elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left></align></font_size>");
    
       if (ret != GEOFENCE_MANAGER_ERROR_NONE)
          return;
    
       ret = geofence_status_destroy(status);
       elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_status_destroy</align></font_size>");
       showError(ad->event_entry, ret);
       snprintf(buf, sizeof(buf), "Fence ID: %d, State: %s, Duration: %d", geofence_id, state_str[state], seconds);
       elm_entry_entry_append(ad->status_entry, "<font_size=25><align=left>");
       elm_entry_entry_append(ad->status_entry, buf);
       elm_entry_entry_append(ad->status_entry, "</align></font_size>");
    }
    
  • Add a fence according to the input data:

    static void
    popup_method_value_cb(void *data, Evas_Object *obj, void *event_info)
    {
       appdata_s *ad = evas_object_data_get(obj, "app_data");
       int place_id = (int)evas_object_data_get(obj, "place_id");
       int method = (int)data;
    
       const char *value = elm_entry_entry_get(ad->gen_entry);
       const char *value_nd = elm_entry_entry_get(ad->gen_entry_nd);
    
       geofence_h fence = NULL;
       double latitude = 0.0, longitude = 0.0;
       int geofence_id = -1;
       int ret = 0;
    
       if (!strcmp(value, "")) 
       {
          show_toast_popup(ad, "Empty Value");
    
          return;
       }
       if (method == METHOD_GPS) 
       {
          if (!strcmp(value_nd, "")) 
          {
             show_toast_popup(ad, "Empty Value");
    
             return;
          }
       }
    
       switch (method) 
       {
          case METHOD_GPS:
             latitude = atof(value);
             longitude = atof(value_nd);
             ret = geofence_create_geopoint(place_id, latitude, longitude, 200, "Dubai MR", &fence);
             elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_create_geopoint</align></font_size>");
             break;
          case METHOD_WIFI:
             ret = geofence_create_wifi(place_id, value, "Dubai MR", &fence);
             elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_create_wifi</align></font_size>");
             break;
          case METHOD_BT:
             ret = geofence_create_bluetooth(place_id, value, "Dubai MR", &fence);
             elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_create_bluetooth</align></font_size>");
             break;
          default:
             break;
       }
       showError(ad->event_entry, ret);
       elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left></align></font_size>");
    
       ret = geofence_manager_add_fence(ad->geo_manager, fence, &geofence_id);
       showError(ad->event_entry, ret);
    
       evas_object_del(ad->popup);
    }
    
  • Remove the selected fence:

    static void
    remove_fence_cb(void *data, Evas_Object *obj, void *event_info)
    {
       appdata_s *ad = evas_object_data_get(obj, "app_data");
       int fence_id = (int) data;
       int ret = 0;
    
       evas_object_del(ad->popup);
    
       ret = geofence_manager_remove_fence(ad->geo_manager, fence_id);
    
       elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_manager_remove_fence</align></font_size>");
       showError(ad->event_entry, ret);
       elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left></align></font_size>");
    }
    
  • Add a place or rename the selected place:

    static void
    popup_place_name_cb(void *data, Evas_Object *obj, void *event_info)
    {
       appdata_s *ad = evas_object_data_get(obj, "app_data");
       int ret = 0;
       int place_id = (int)data;
       const char *place_name = elm_entry_entry_get(ad->gen_entry);
    
       if (!strcmp(place_name, "")) 
       {
          show_toast_popup(ad, "Empty Value");
    
          return;
       }
    
       if (place_id < 0) 
       {
          ret = geofence_manager_add_place(ad->geo_manager, place_name, &place_id);
          elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_manager_add_place</align></font_size>");
       } 
       else 
       {
          ret = geofence_manager_update_place(ad->geo_manager, place_id, place_name);
          elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_manager_update_place</align></font_size>");
       }
    
       showError(ad->event_entry, ret);
    
       if (place_id > 0 && place_id <= 3)
          elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left>The renaming of default place is impossible</align></font_size>");
       else
          elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left></align></font_size>");
    
       evas_object_del(ad->popup);
    }
    
  • Remove the selected place:

    static void
    remove_place_cb(void *data, Evas_Object *obj, void *event_info)
    {
       appdata_s *ad = evas_object_data_get(obj, "app_data");
       int place_id = (int) data;
       int ret = 0;
    
       evas_object_del(ad->popup);
    
       ret = geofence_manager_remove_place(ad->geo_manager, place_id);
    
       elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_manager_remove_place</align></font_size>");
       showError(ad->event_entry, ret);
       if (place_id <= 3)
          elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left>The deletion of default place is impossible</align></font_size>");
       else
          elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left></align></font_size>");
    }
    
  • Start the selected fence:

    static void
    start_fence_cb(void *data, Evas_Object *obj, void *event_info)
    {
       appdata_s *ad = evas_object_data_get(obj, "app_data");
       int fence_id = (int) data;
       int ret = 0;
    
       evas_object_del(ad->popup);
    
       ret = geofence_manager_start(ad->geo_manager, fence_id);
    
       elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_manager_start</align></font_size>");
       showError(ad->event_entry, ret);
       elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left></align></font_size>");
    }
    
  • Stop the selected fence:

    static void
    stop_fence_cb(void *data, Evas_Object *obj, void *event_info)
    {
       appdata_s *ad = evas_object_data_get(obj, "app_data");
       int fence_id = (int) data;
       int ret = 0;
    
       evas_object_del(ad->popup);
    
       ret = geofence_manager_stop(ad->geo_manager, fence_id);
    
       elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_manager_stop</align></font_size>");
       showError(ad->event_entry, ret);
       elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left></align></font_size>");
    }