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.
Figure: Geofence main view
In the application main view, you can manage geofences. You can, for example, create a fence, get the fence status, and add and remove fences and places.
Prerequisites
To ensure proper application execution, the following privilege must be set:
- http://tizen.org/privilege/location
Implementation
Application Main View
To create the application main view:
-
In the view_create() function, create the window, conformant, naviframe, and grid:
Eina_Bool view_create(void *user_data) { /* Create the window */ s_info.win = view_create_win(PACKAGE); if (s_info.win == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a window."); return EINA_FALSE; } /* Create the conformant */ s_info.conform = view_create_conformant_without_indicator(s_info.win); if (s_info.conform == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a conformant"); return EINA_FALSE; } /* Create the naviframe */ s_info.nf = view_create_naviframe(s_info.conform); if (s_info.nf == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a naviframe"); return EINA_FALSE; } /* Create the grid and grid content */ Evas_Object *grid = view_create_grid_and_content(s_info.nf, (appdata_s *)user_data); if (grid == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a grid"); return EINA_FALSE; } /* Push an item to the naviframe */ Elm_Object_Item *nf_it = elm_naviframe_item_push(s_info.nf, "Geofence", NULL, NULL, grid, NULL); elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, NULL); /* Show the window after the main view is set up */ evas_object_show(s_info.win); return EINA_TRUE; }
-
The view_create_grid_and_content() function creates a panel for 10 buttons and 3 entries for displaying the result:
static Evas_Object* view_create_grid_and_content(Evas_Object *nf, appdata_s *ad) { /* Create and initialize elm_grid */ Evas_Object *grid = NULL; if (nf == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "naviframe is NULL."); return NULL; } grid = elm_grid_add(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(nf, grid); /* Entry for the API name */ s_info.entry = create_entry(grid); elm_grid_pack(grid, s_info.entry, 0, 5, 90, 10); /* Entry for the API result */ s_info.event_entry = create_entry(grid); elm_grid_pack(grid, s_info.event_entry, 0, 15, 90, 10); /* Entry for the fence state */ s_info.state_entry = create_entry(grid); elm_grid_pack(grid, s_info.state_entry, 0, 25, 90, 10); /* Create the panel */ Evas_Object *panel = create_panel_and_content(grid, ad); elm_grid_pack(grid, panel, 0, 55, 100, 45); return grid; }
-
The create_panel_basic_content() function creates 10 buttons:
static Evas_Object* create_panel_basic_content(Evas_Object *panel, appdata_s *ad) { /* Create and initialize elm_table */ Evas_Object *table; if (panel == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "panel is NULL."); return NULL; } table = elm_table_add(parent); elm_table_padding_set(table, 10, 0); /* Create the buttons */ /* "Create" button */ 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); /* "Fence Status" button */ 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); /* "Add Fence" button */ 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); /* "Add Place" button */ 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); /* "Start" button */ 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); /* "Stop" button */ 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); /* "Remove Fence" button */ 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); /* "Remove Place" button */ 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); /* "Update Place" button */ 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); /* "Destroy" button */ 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 buttons:
static void show_popup_cb(void *data, Evas_Object *obj, void *event_info) { appdata_s *ad = (appdata_s *)data; /* Set a function and parameter for each button */ 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
The application operations are activated by clicking the buttons on the main view.
To create the operations:
-
The Create button creates 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; if (ad == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "Application data is NULL."); return; } /* Create geofence handle */ ret = geofence_manager_create(&(ad->geo_manager)); /* Show the called API */ elm_entry_entry_set(ad->entry, "<font_size=30><align=left>geofence_manager_create</align></font_size>"); /* Show the API result */ showError(ad->event_entry, ret); /* Clear the entry of fence state */ elm_entry_entry_set(ad->status_entry, "<font_size=25><align=left></align></font_size>"); /* Enable the buttons when the geofence handle is created */ 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); /* Set a callback for the geofence event */ geofence_manager_set_geofence_event_cb(ad->geo_manager, show_event_cb, ad); /* Set a callback for the geofence state */ geofence_manager_set_geofence_state_changed_cb(ad->geo_manager, show_state_changed_cb, ad); } }
-
The Fence Status button gets the state of the selected fence:
static void get_state_cb(void *data, Evas_Object *obj, void *event_info) { 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(s_info.popup); /* Create the geofence status handle */ ret = geofence_status_create(geofence_id, &status); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_status_create</align></font_size>"); /* Show the API result */ showError(s_info.event_entry, ret); /* Clear the fence state entry */ elm_entry_entry_set(s_info.state_entry, "<font_size=25><align=left></align></font_size>"); if (ret != GEOFENCE_MANAGER_ERROR_NONE) return; /* Get state */ ret = geofence_status_get_state(status, &state); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_status_get_state</align></font_size>"); /* Show the API result */ showError(s_info.event_entry, ret); /* Clear the fence state entry */ elm_entry_entry_set(s_info.state_entry, "<font_size=25><align=left></align></font_size>"); /* Get the duration */ ret = geofence_status_get_duration(status, &seconds); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_status_get_duration</align></font_size>"); /* Show the API result */ showError(s_info.event_entry, ret); /* Clear the fence state entry */ elm_entry_entry_set(s_info.state_entry, "<font_size=25><align=left></align></font_size>"); if (ret != GEOFENCE_MANAGER_ERROR_NONE) return; /* Destroy the geofence status handle */ ret = geofence_status_destroy(status); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_status_destroy</align></font_size>"); /* Show the API result */ showError(s_info.event_entry, ret); /* Show the fence state */ snprintf(buf, sizeof(buf), "Fence ID: %d, State: %s, Duration: %d", geofence_id, state_str[state], seconds); elm_entry_entry_append(s_info.state_entry, "<font_size=25><align=left>"); elm_entry_entry_append(s_info.state_entry, buf); elm_entry_entry_append(s_info.state_entry, "</align></font_size>"); }
-
The Add Fence button adds 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(s_info.gen_entry); const char *value_nd = elm_entry_entry_get(s_info.gen_entry_nd); if (ad == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "Application data is NULL."); return; } geofence_h fence = NULL; double latitude = 0.0, longitude = 0.0; int geofence_id = -1; int ret = 0; if (!strcmp(value, "")) { show_toast_popup("Empty Value"); return; } if (method == METHOD_GPS) { if (!strcmp(value_nd, "")) { show_toast_popup("Empty Value"); return; } } switch (method) { case METHOD_GPS: latitude = atof(value); longitude = atof(value_nd); /* Create a geopoint fence handle */ ret = geofence_create_geopoint(place_id, latitude, longitude, 200, "Dubai MR", &fence); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left<geofence_create_geopoint</align></font_size>"); break; case METHOD_WIFI: /* Create a Wi-Fi fence handle */ ret = geofence_create_wifi(place_id, value, "Dubai MR", &fence); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_create_wifi</align></font_size>"); break; case METHOD_BT: /* Create a bluetooth fence handle */ ret = geofence_create_bluetooth(place_id, value, "Dubai MR", &fence); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_create_bluetooth</align></font_size>"); break; default: break; } /* Show the API result */ showError(s_info.event_entry, ret); /* Clear the fence state entry */ elm_entry_entry_set(s_info.state_entry, "<font_size=25><align=left></align></font_size>"); /* Add the fence */ ret = geofence_manager_add_fence(ad->geo_manager, fence, &geofence_id); /* Show the API result */ showError(s_info.event_entry, ret); evas_object_del(s_info.popup); }
-
The Remove Fence button removes 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; if (ad == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "Application data is NULL."); return; } evas_object_del(s_info.popup); /* Remove the fence */ ret = geofence_manager_remove_fence(ad->geo_manager, fence_id); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_manager_remove_fence</align></font_size>"); /* Show the API result */ showError(s_info.event_entry, ret); /* Clear the fence state entry */ elm_entry_entry_set(s_info.state_entry, "<font_size=25><align=left></align></font_size>"); }
-
The Add Place button adds a place or renames 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(s_info.gen_entry); if (ad == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "Application data is NULL."); return; } /* Check that a name is inserted */ if (!strcmp(place_name, "")) { show_toast_popup("Empty Value"); return; } if (place_id < 0) { /* Add a place */ ret = geofence_manager_add_place(ad->geo_manager, place_name, &place_id); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_manager_add_place</align></font_size>"); } else { /* Update the place */ ret = geofence_manager_update_place(ad->geo_manager, place_id, place_name); /* show called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_manager_update_place</align></font_size>"); } /* Show the API result */ showError(s_info.event_entry, ret); /* Show or clear the geofence state */ if (place_id > 0 && place_id <= 3) elm_entry_entry_set(s_info.state_entry, "<font_size=25><align=left>The renaming of default place is impossible</align></font_size>"); else elm_entry_entry_set(s_info.state_entry, "<font_size=25><align=left></align></font_size>"); evas_object_del(s_info.popup); }
-
The Remove Place button removes 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; if (ad == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "Application data is NULL."); return; } evas_object_del(s_info.popup); /* Remove the place */ ret = geofence_manager_remove_place(ad->geo_manager, place_id); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_manager_remove_place</align></font_size>"); /* Show the API result */ showError(s_info.event_entry, ret); /* Show or clear the fence state */ if (place_id <= 3) elm_entry_entry_set(s_info.state_entry, "<font_size=25><align=left>The deletion of default place is impossible</align></font_size>"); else elm_entry_entry_set(s_info.state_entry, "<font_size=25><align=left></align></font_size>"); }
-
The Start button starts 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; if (ad == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "Application data is NULL."); return; } evas_object_del(s_info.popup); /* Start the fence */ ret = geofence_manager_start(ad->geo_manager, fence_id); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_manager_start</align></font_size>"); /* Show the API result */ showError(s_info.event_entry, ret); /* Clear the fence state entry */ elm_entry_entry_set(s_info.state_entry, "<font_size=25><align=left></align></font_size>"); }
-
The Stop button stops 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; if (ad == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "Application data is NULL."); return; } evas_object_del(s_info.popup); /* Stop the fence */ ret = geofence_manager_stop(ad->geo_manager, fence_id); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_manager_stop</align></font_size>"); /* Show the API result */ showError(s_info.event_entry, ret); /* Clear the fence state entry */ elm_entry_entry_set(s_info.state_entry, "<font_size=25><align=left></align></font_size<"); }
-
The Destroy button destroys 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; if (ad == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "Application data is NULL."); return; } /* Unset the callback for the geofence event */ geofence_manager_unset_geofence_event_cb(ad->geo_manager); /* Unset the callback for the geofence state */ geofence_manager_unset_geofence_state_changed_cb(ad->geo_manager); /* Destroy geofence handle */ ret = geofence_manager_destroy(ad->geo_manager); /* Show the called API */ elm_entry_entry_set(s_info.entry, "<font_size=30><align=left>geofence_manager_destroy</align></font_size>"); /* Show the API result */ showError(s_info.event_entry, ret); /* Clear the fence state */ elm_entry_entry_set(s_info.state_entry, "<font_size=25><align=left></align></font_size>"); /* Disable the button when the geofence handle is destroyed */ if (ret == GEOFENCE_MANAGER_ERROR_NONE) { elm_object_disabled_set(s_info.create_btn, EINA_FALSE); elm_object_disabled_set(s_info.fence_state_btn, EINA_TRUE); elm_object_disabled_set(s_info.add_fence_btn, EINA_TRUE); elm_object_disabled_set(s_info.add_place_btn, EINA_TRUE); elm_object_disabled_set(s_info.start_btn, EINA_TRUE); elm_object_disabled_set(s_info.stop_btn, EINA_TRUE); elm_object_disabled_set(s_info.remove_fence_btn, EINA_TRUE); elm_object_disabled_set(s_info.remove_place_btn, EINA_TRUE); elm_object_disabled_set(s_info.update_place_btn, EINA_TRUE); elm_object_disabled_set(s_info.destroy_btn, EINA_TRUE); ad->geo_manager = NULL; } }