API Comparison
The following table shows where to find information related to the 2.2.1 and 2.3 version APIs.
This feature is supported in mobile applications only.
API | Version 2.2.1 | Version 2.3 |
---|---|---|
Content: Managing Content | Documentation: | Content Tutorials |
Locales: Internationalization and Localization | Documentation: | i18n Tutorial |
Locations: Using Location Information and Services | Documentation: | Location Tutorials |
Media: Handling Audio, Video, Camera, and Images | Documentation: | Multimedia Tutorials |
Messaging: SMS, MMS, Email, and Push | Documentation: | Messaging Tutorials |
Net: Managing Network Connections and Communication | Documentation: | Network Tutorials |
Security: Handling Certificates and Cryptographic Primitives | Documentation: | Security Tutorials |
Shell: Managing Tizen Shell | Documentation: | Application Framework Tutorials |
Social: Managing Personal Data | Documentation: | Social Tutorials |
System: Getting System Information and Using Alarms | Documentation: | System Tutorials |
Telephony: Handling Phone Call, SIM card, and Network Information | Documentation: | Telephony Tutorials |
Text: Encoding and Decoding Characters | Documentation: | i18n Tutorial |
UI: Creating the Application UI | Documentation: | |
Uix: Interaction for Advanced UX | Documentation: | UIX Tutorials |
Web: Managing Web Pages and Web Content | Documentation: | Web Tutorials |
Content
The Content API has the same functionality as earlier, providing features to manage the local device content. However, the API model has changed.
Creating Content
The process of content instance creation in the 2.2.1 version is presented in the 2.2.1 Content Tutorial. According to that tutorial, the content can be created in the following ways:
- Using a File Path
- Using a File Path with Content Information
- Using a ByteBuffer
- Using a ByteBuffer with Content Information
In version 2.3, to create a content instance, insert the media file into the media database. To do this, you can use 2 different functions:
- media_info_insert_to_db() takes the path to the file as an input parameter and returns the media_info_h handle as the second output parameter.
- media_content_scan_file() scans the database for the file. If the file is not found, it is added to the database.
Use the Inserting Media in the Database instructions in the 2.3 Media Information Tutorial:
media_info_h media_file = NULL; media_content_connect(); // Required to establish the connection with the Content Service media_info_insert_to_db(your_media_file_path, &media_file); // OR media_content_scan_file(your_media_file_path);
Note that the media_content_scan_file() function does not return the media_info_h handle. To obtain it, perform a search on the database.
Updating Content
You can update the content in 2 different ways in the 2.3 API model:
- The media_content_scan_file() function updates the media file information if the file is already stored in the database. Otherwise, it inserts the information to the database or, when the file does not exist in the system anymore, it removes the information about it from the database.
- To update content information, search through the database for the media information that you want to change. After retrieving the handle to the required media information, change the information by calling the media_info_set_*(<name of the property to be changed>) function. When the updating is finished, call the media_info_update_to_db() function to apply the update to the database:
filter_h filter = NULL; // Handle for the filter used for searching media_filter_create(&filter); // Creation of the filter media_filter_set_condition(filter, ..., ...); // Setting the condition to the filter media_info_foreach_media_from_db(filter, gallery_media_item_cb, NULL);
The gallery_media_item_cb() callback is called for each media info in the media database that match the given filter conditions. Inside the callback, edit the obtained media info and update the database with the following code:
bool gallery_media_item_cb(media_info_h media, void *user_data) { media_info_set_longitude(media, ...); media_info_set_latitude(media, ...); media_info_set_favorite(media, ...); media_info_update_to_db(media); }
Removing Content
To remove content information in the 2.2.1 version, see the Deleting Content section of the Content Tutorial. Now, the media_info_delete_from_db() function performs this action. It takes the media ID property as its parameter. To obtain the media ID for the given media information, use the media_info_get_media_id() function:
char *media_id; media_info_get_media_id(media, &media_id); // Getting the media ID of the given media record media_info_delete_from_db(media_id); // Removing the media from the Content database
Tracking Content Changes
The Retrieving Database Notifications use case from the 2.2.1 version is fully covered by the Receiving Update Notifications use case in the 2.3 Media Content Tutorial. The main difference is that instead of setting a listener with the AddContentUpdateEventListener interface to listen for database updates, the media_content_set_db_updated_cb() function must be used to set the callback that is called when the data in the database changes:
media_content_set_db_updated_cb(_database_updated_cb, NULL); _database_updated_cb(media_content_error_e error, int pid, media_content_db_update_item_type_e update_item, media_content_db_update_type_e update_type, media_content_type_e media_type, char *uuid, char *path, char *mime_type, void *user_data) { if (MEDIA_CONTENT_ERROR_NONE == error) { // Database was successfully updated if (path) dlog_print(DLOG_INFO, LOG_TAG, "path : %s", path); if (uuid) dlog_print(DLOG_INFO, LOG_TAG, "uuid : %s", uuid); if (mime_type) dlog_print(DLOG_INFO, LOG_TAG, "mime_type : %s", mime_type); } }
Searching Content
The Content Search section of the Content tutorial for the 2.2.1 version describes how to search for content. The Searching Content and Retrieving an Audio Genre List use cases from the 2.2.1 tutorial are covered by the Media Content Tutorial in the new 2.3 tutorial. This section describes how to search through the content database using different filters. With the old API, you called the SearchN() function with some filtering parameters. Now, you create and set the filtering conditions to the filter instance, and then use this filter as a parameter of the media_info_foreach_media_from_db() function to search for matching content:
#define BUFLEN 200 filter_h filter = NULL; char buf[BUFLEN] = { '\0' }; media_filter_create(&filter); snprintf(buf, BUFLEN, "%s = 'Samsung'", MEDIA_ARTIST); // Search for albums with the artist name "Samsung" media_filter_set_condition(filter, buf, MEDIA_CONTENT_COLLATE_NOCASE); // Set the case insensitive condition // Set the order of results by the artist name, ascending, case sensitive media_filter_set_order(filter, MEDIA_CONTENT_ORDER_ASC, MEDIA_ARTIST, MEDIA_CONTENT_COLLATE_DEFAULT); media_info_foreach_media_from_db(filter, media_cb, NULL);
Downloading Content
The Downloading the Content section is named the Download Tutorial for version 2.3. The difference between them is that there is no Download Manager anymore. All download operations are based on the download ID (in the 2.2.1 version the requestId). This ID is obtained by using the download_create() function. Instead of the SetDownloadListener() function, use the download_set_state_changed_cb() function to invoke the callback function when the download status changes. The download_set_url() function replaces the 2.2.1 DownloadRequest constructor. To start the download, call the download_start() function the same way as Start() in the 2.2.1 API. For more information, see the content of these tutorials.
int download_id; download_create(&download_id); download_set_state_changed_cb(download_id, _state_changed_cb, NULL); download_set_url(download_id, "http://tizen.org"); download_start(download_id); _state_changed_cb(int download_id, download_state_e state, void *user_data) { // The state of the downloading process can be checked here }
Managing Playlists
The last section of the 2.2.1 Content Tutorial is about playlist management. A matching tutorial in the 2.3 version is the Media Content Tutorial. It describes managing playlists in detail. In the 2.2.1 API, the playlist was created with the Construct() function as a new independent instance of a playlist. In the 2.3 model, the playlist is created as an item of the media playlist database using the media_playlist_insert_to_db() function:
media_playlist_h playlist = NULL; media_playlist_insert_to_db("Put your playlist name here", &playlist);
To manage the playlists:
-
To add the media item to the playlist, the media_id is needed, so the media must already be placed in the media database. When the media_id is available, use the media_playlist_add_media() function to attach the media to the playlist:
media_playlist_add_media(playlist, media_id);
-
To retrieve the playlist from the database, use one of the following ways:
- Use the media_playlist_get_playlist_from_db(), which is similar to the GetPlayListN() function. The difference is that the playlist ID is required as a parameter instead of the playlist name.
media_playlist_get_playlist_from_db(playlist_id);
-
Search for the playlist by using the media_playlist_foreach_playlist_from_db() function and a proper filter as a parameter. This function invokes the callback for every playlist in the database that matches the given filtering conditions.
media_playlist_foreach_playlist_from_db(filter, _playlist_list_cb, NULL); static bool _playlist_list_cb(media_playlist_h playlist, void* user_data) { int playlist_id; char *name = NULL; // Manage the retrieved playlist here media_playlist_get_name(playlist, &name); media_playlist_get_playlist_id(playlist, &playlist_id); media_playlist_set_name(playlist, "Put new playlist name here."); }
- Use the media_playlist_get_playlist_from_db(), which is similar to the GetPlayListN() function. The difference is that the playlist ID is required as a parameter instead of the playlist name.
The SetPlayListName() function is covered by media_playlist_set_name().
-
To remove the playlist, use the following code instead of a single RemovePlayList() method on an existing object:
int playlist_id; media_playlist_get_playlist_id(playlist, &playlist_id); media_playlist_delete_from_db(playlist_id); // Remove the playlist from the database media_playlist_destroy(playlist); // Release the memory allocated for the playlist
Locales
The calendar creation and use (described in the Creating a Calendar and Changing the Date use case for the 2.2.1 version) is described in the new tutorial under the Managing Dates and Calendar use case.
Note that in addition to functions described in this section, time-related functions are also provided by the following libraries:
- Eglibc, a variant of glibc (http://www.eglibc.org/home)
- GLib (https://developer.gnome.org/glib/2.38/)
Previously, you created the calendar instance with this method:
Calendar* pCalendar = Calendar::CreateInstanceN(CALENDAR_GREGORIAN);
Now, to create the calendar instance, do the following:
i18n_uchar timezone[16]; i18n_ustring_copy_ua_n(timezone, "America/New_York", 16); i18n_ucalendar_h ucalendar; i18n_ucalendar_create(timezone, -1, I18N_ULOCALE_US, I18N_UCALENDAR_DEFAULT, &ucalendar);
In the 2.3 version, use the i18n_ucalendar_create() function to create the calendar instance. The function takes 5 parameters instead of the 1 in the 2.2.1 API. The CALENDAR_GREGORIAN parameter passed in the 2.2.1 API is now the fourth parameter, and its type is i18n_ucalendar_type_e. To create the Gregorian calendar, use the I18N_UCALENDAR_GREGORIAN type. The other parameters are:
- Desired time zone ID (for example, "America/New_York").
- Length of the time zone ID input string. The value -1 can be used when the zone ID is null-terminated.
- Desired locale, such as I18N_ULOCALE_US.
- Last parameter is an out-type parameter. It is a pointer to an i18n_calendar instance which is created.
The SetTime() function for setting the current time of the calendar is replaced with the i18n_ucalendar_set_date_time() function. Now it takes a detailed date as its parameters, and the hour, minute, and seconds can also be specified. You also have to pass the pointer to the calendar instance as a parameter.
// The parameters are: calendar instance, year, month, day, hour, minute, and second i18n_ucalendar_set_date_time(ucalendar, 2014, I18N_UCALENDAR_JULY, 1, 9, 0, 0);
The AddTimeField() function is now covered by the i18n_ucalendar_add() function. It works almost as in the 2.2.1 version; for more information, see the documentation.
i18n_ucalendar_add(ucalendar, I18N_UCALENDAR_HOUR, 3);
The Formatting Time and Date section is also now a part of the Managing Dates and Calendar use case in the 2.3 tutorial.
The GetCurrentTime() function has been replaced with the i18n_ucalendar_get_now() function. It gets an actual current date from the system, and it is represented as milliseconds from the epoch.
i18n_udate now; i18n_ucalendar_get_now(&now);
The date formatter functionality provided in the 2.3 API is similar to the 2.2.1 version. The CreateDateFormatterN() function is replaced with the i18n_udate_create() function. The difference is that during the creation of the formatter you already pass the date pattern created with the i18n_udatepg_create() and i18n_udatepg_get_best_pattern() functions (in 2.2.1, the pattern was applied to the formatter after it was created, by using the ApplyPattern() function). The main functionality provided earlier by the Format() function is now covered by the i18n_udate_format_date() function. To see the exact usage of the mentioned functions, see the tutorials.
i18n_udatepg_h udatepg; i18n_udatepg_create(I18N_ULOCALE_UK, &udatepg); // Create the pattern generator i18n_uchar format[64]; // Create a draft format for the date (E - day of the week, M - month, y - year, d - day of the month, and D - day of the year) i18n_ustring_copy_ua_n(format, "EEEdMMMyyyyHHmmssz", 64); int pattern_len; i18n_uchar best_pattern[64]; // Generate the best pattern using pattern generator i18n_udatepg_get_best_pattern(udatepg, format, 64, best_pattern, 64, &pattern_len); i18n_udate_format_h date_format; i18n_ustring_copy_ua_n(timezone, "Asia/Seoul", 16); // Create a date format i18n_udate_create(I18N_UDATE_FULL, I18N_UDATE_FULL, I18N_ULOCALE_UK, timezone, -1, best_pattern, -1, &date_format); i18n_uchar date_result[64]; int date_len; // Format the date i18n_udate_format_date(date_format, now, date_result, 64, NULL, &date_len);
The 2.2.1 API provides time zone-related functionality. Getting the time zone identifier was possible with the TimeZone::GetId() function. In the 2.3 API, use the i18n_ucalendar_get_timezone_displayname() function with the display format type as the second parameter.
i18n_ucalendar_get_timezone_displayname(ucalendar, I18N_UCALENDAR_STANDARD, ...);
Getting the time zone offset from UTC/GMT (in minutes) was possible using the TimeZone::GetRawOffset() function. In the 2.3 API, this functionality is covered by the i18n_ucalendar_get() function with the I18N_UCALENDAR_ZONE_OFFSET as its second parameter.
int offset; i18n_ucalendar_get(ucalendar, I18N_UCALENDAR_ZONE_OFFSET, &offset); // Value is given in milliseconds
In 2.2.1, it was possible to find the daylight savings time (in minutes) with the TimeZone::GetDstSavings() function. In 2.3, it can be done for a particular date using the i18n_ucalendar_get() function with the I18N_UCALENDAR_DST_OFFSET as its second parameter.
int offset; i18n_ucalendar_get(ucalendar, I18N_UCALENDAR_DST_OFFSET, &offset); // Value is given in milliseconds
It is also possible to check whether a date is in daylight savings time with the i18n_ucalendar_is_in_daylight_time() function:
bool is_in_dst; i18n_ucalendar_is_in_daylight_time(ucalendar, &is_in_dst);
In case of the Getting the System Locale use case, you can find helpful 2.3 API information in the Runtime information Tutorial. Getting the system locale is now done by using the i18n_ulocale_get_default() function (GetSystemLocale() in the 2.2.1 version). To get the full name of the specified locale, the i18n_ulocale_get_display_name() function is used. To get the language for the given locale, call the i18n_ulocale_get_language() function.
The Formatting Numbers use case is now the Managing Numbers use case. The functions in these use cases match like this:
- CreateNumberFormatter() -> i18n_unumber_create()
- Format() -> i18n_unumber_get_symbol()
For more information, see the tutorials.
Locations
To work with the location functionality, the 2.3 API model requires creating and starting the Location Manager instance. It is an equivalent to the LocationProvider class from the 2.2.1 API.
location_manager_h manager; // Use LOCATIONS_METHOD_HYBRID to support both GPS and WPS location_manager_create(LOCATIONS_METHOD_GPS, &manager); location_manager_start(manager); // Start the location manager location_manager_stop(manager); // Stop the location manager // Destroy the location manager to release the allocated memory location_manager_destroy(manager);
The first part of the old tutorial is Getting the Last Known Location. The same section appears in the new tutorials. The difference in the new API is that the function used to get the last location (location_manager_get_last_location()) takes pointers to parameters of the location and fulfills them with data. It also returns the error code, instead of returning the Location structure like it did with the GetLastKnownLocation() function in the 2.2.1 API. As long as you have all the parameters fulfilled by the function and you have the pointers to the obtained values, you already have the timestamp and coordinates values, so there is no need to call the GetTimestamp() and GetCoordinates() functions, like in the 2.2.1 tutorial.
double altitude, latitude, longitude, climb, direction, speed; double horizontal, vertical; location_accuracy_level_e level; time_t timestamp; int error_code = location_manager_get_last_location(manager, &altitude, &latitude, &longitude, &climb, &direction, &speed, &level, &horizontal, &vertical, ×tamp);
The next part about Getting Location Updates also has its equivalent in the new 2.3 tutorials. Now, it is much simpler to handle the location update events. The only thing you have to do to get the location updates is to register the proper callback by using the location_manager_set_position_updated_cb() function. As well as in the 2.2.1 API, it is possible to set the interval for callback calls:
location_manager_set_position_updated_cb(manager, position_updated, 2, NULL); // Interval is set to 2 seconds
When the callback is called, it already has all the position information stored in its parameters, so there is no need to call any function, like GetCoordinates(), inside the callback:
static void position_updated(double latitude, double longitude, double altitude, time_t timestamp, void *user_data) { // You can manipulate the obtained location information here, for example: dlog_print(DLOG_INFO, LOG_TAG, "The latitude value is: %d", latitude); }
For more information, see the Getting Location Updates use case in the 2.3 Location Manager Tutorial.
The last section of the 2.2.1 Location Tutorial, Monitoring Regions, is not covered by the new 2.3 tutorial, but the functionality described there can be found in the Location Manager documentation in 2.3 API. Now, it is easier to track the region changes. There is no need to create the class for a proper Listener or do other actions described in the 2.2.1 tutorial. You only have to set the proper callback that is called when the specified boundary area is entered or exited. To do this, use the location_bounds_set_state_changed_cb() function. For more information, see the Location Manager module documentation.
int poly_size = 3; location_coords_s coord_list[poly_size]; coord_list[0].latitude = 10; coord_list[0].longitude = 10; coord_list[1].latitude = 20; coord_list[1].longitude = 20; coord_list[2].latitude = 30; coord_list[2].longitude = 10; location_bounds_h bounds_poly; location_bounds_create_polygon(coord_list, poly_size, &bounds_poly); // Create a triangle shaped polygon location_bounds_set_state_changed_cb(bounds_poly, bounds_state_changed_cb, NULL); // Set the callback static void bounds_state_changed_cb(location_boundary_state_e state, void *user_data) { if (LOCATIONS_BOUNDARY_IN == state) { dlog_print(DLOG_INFO, LOG_TAG, "The boundary was entered"); } else { dlog_print(DLOG_INFO, LOG_TAG, "The boundary was exited"); } }
Media
PLAYING AUDIO -> PLAYING AN AUDIO FILE (PLAYER TUTORIAL)
The OpenFile() functionality from the 2.2.1 version is now handled by the player_set_uri() function. It specifies which file is played. To start the playback, use the player_start() function. It is like the Play() function from the 2.2.1 API. One important difference between 2.2.1 and 2.3 APIs is that, before the playback can be started, the player_set_uri() and player_prepare() functions have to be called. The player_set_uri() function sets the file path to the file that is played. It is important to call this function before calling the player_prepare() function, because otherwise an error occurs. The player_prepare() function prepares the media player for playback. In the 2.2.1 API, no such function had to be used before playing the file. The rest of the functionalities described in the 2.2.1 tutorial are covered in the 2.3 API by the following functions: player_stop() to stop the playback, player_pause() to pause the playback, and player_get_play_position() to get the current playback position in milliseconds.
player_h player; char file_path[1024]; strcpy(file_path, app_get_shared_data_path()); strcat(file_path, "audio.mp3"); player_create(&player); player_set_uri(player, file_path); player_prepare(player); player_start(player);
To read and set playing position, use:
- Player::GetPosition() -> player_get_play_position()
-
Player::SeekTo() -> player_set_play_position()
The player_set_play_position() function is asynchronous (like its 2.2.1 counterpart) and signals seeking completion through a callback.
To check the rest of the player functionalities, see the Player API Reference.
PLAYING VIDEO -> PLAYING A VIDEO FILE (PLAYER TUTORIAL)
Playing the video file is very similar to playing the audio file. The difference is that you have to set the display where the video is presented. There was no such functionality mentioned in the 2.2.1 tutorial, but it can be found in the 2.3 tutorial.
player_set_display(player, PLAYER_DISPLAY_TYPE_EVAS, GET_DISPLAY(evas_obj));
HANDLING PLAYER CONTROLLERS -> PLAYER DOCUMENTATION
To handle the events of opening the player and reaching the end of a played file, you can use the player_prepared_cb() callback with the player_prepare_async() function and register the player_completed_cb() callback using the player_set_completed_cb() function. The first one is related to the situation when the player is prepared. The second one is invoked when the player reaches the end of the stream.
player_prepare_async(player, _prepared_cb, NULL);
This function asynchronously prepares the player. After its work is finished, the _prepared_cb() is invoked.
static void _prepared_cb(void *data) { // This callback is invoked when the player is prepared dlog_print(DLOG_INFO, LOG_TAG, "The player is ready to start the playback"); }
This code presents the example usage of the player_set_completed_cb() function.
player_set_completed_cb(player, _player_completed_cb, NULL); static void _player_completed_cb(void *data) { dlog_print(DLOG_INFO, LOG_TAG, "The playback ended."); }
For more information, see the Player API Reference.
CAPTURING AND RECORDING MEDIA -> CAMERA TUTORIAL
The overall models of capturing and recording functionalities are pretty much the same in both API versions. The corresponding functions are:
- Construct() and PowerOn() -> camera_create()
- StartPreview() -> camera_start_preview()
- StopPreview() -> camera_stop_preview()
- OnCameraPreviewed() -> camera_set_preview_cb()
The main difference is connected with setting the display surface for the camera preview. To set the place for displaying the preview image, use the camera_set_display() function. An Evas_object can be used for showing the preview, instead dealing with, for example, an OverlayRegion or rectangles.
camera_h camera; camera_create(CAMERA_DEVICE_CAMERA0, camera); camera_set_display(camera, CAMERA_DISPLAY_TYPE_EVAS, put_your_evas_object_here); camera_set_preview_resolution(camera, width_resolution, height_resolution); camera_start_preview(camera); camera_stop_preview(camera);
The next little difference is about getting the supported preview resolutions. In the 2.2.1 API, it was possible by using the GetSupportedPreviewResolutionListN() function. Now, in 2.3 API model, the camera_foreach_supported_preview_resolution() function must be used. It iterates through all the supported preview resolutions and calls the callback, passed as one of the parameters, for each of them. The camera_set_preview_resolution() function is a replacement for the SetPreviewResolution() from the 2.2.1 API. The same applies with setting the capture resolution. Use the camera_foreach_supported_capture_resolution() and camera_set_capture_resolution() functions for this purpose.
int resolution[2]; // Find resolution that is supported by the device camera_foreach_supported_preview_resolution(camera, _preview_resolution_cb, resolution); // Set supported resolution for camera preview camera_set_preview_resolution(camera, resolution[0], resolution[1]); static bool _preview_resolution_cb(int width, int height, void *user_data) { int *resolution = (int*)user_data; resolution[0] = width; resolution[1] = height; return false; // Stop the iteration after finding first supported resolution }
Setting the capture and preview format follows the same scheme as setting the resolution. As you can see, the main difference in this matter is that instead of getting the list of supported resolutions and formats, you have functions to iterate through all of them and invoke callbacks for each one to handle it (camera_foreach_supported_capture_format() and camera_foreach_supported_preview_format()).
RECORDING AUDIO -> AUDIO RECORDER TUTORIAL
The old Construct() function is now covered by the recorder_create_audiorecorder() function. It creates the handle to the audio recorder instance.
recorder_h recorder; recorder_create_audiorecorder(&recorder);
Before the recording can be started, the file for the recording has to be specified. The 2.2.1 API provided the CreateAudioFile() function. In 2.3, there are 2 functions responsible for this:
- recorder_set_file_format() defines in what kind of file format the recording is stored.
- recorder_set_filename() sets the name of the file in which the recording is stored.
recorder_set_file_format(recorder, RECORDER_FILE_FORMAT_3GP); recorder_set_filename(recorder, your_audio_file_path);
The SetMaxRecordingSize() and SetMaxRecordingTime() functions are now covered by the recorder_attr_set_size_limit() and recorder_attr_set_time_limit() functions.
// Set max file size to 1024 [kB] recorder_attr_set_size_limit(recorder, 1024); // Set max recording time to 2 minutes [120 seconds] recorder_attr_set_time_limit(recorder, 120);
Getting the supported file formats and codecs is again implemented with the usage of a set of foreach functions. These functions work the same way as it was described in previous sections.
In the 2.2.1 API, it was possible to set the quality of the recording, by simply using the SetQuality() function. Now, the quality can be controlled by the different functions from the Recorder Attributes submodule.
Starting, pausing, and stopping the record process are managed by similar functions like in the 2.2.1 API. The Record(), Pause(), Stop(), and Close() functions are now covered by the recorder_prepare(), recorder_start(), recorder_pause(), recorder_cancel(), and recorder_commit() functions.
The scheme of recording a video file is similar to the process of recording an audio file. The difference is that the display for the camera has to be specified. The recorder has to be created with the recorder_create_videorecorder() function, instead of using the recorder_create_audiorecorder() function. For more information, see the tutorials.
DECODING IMAGES -> DECODING FROM A FILE OR MEMORY (IMAGE UTIL TUTORIAL)
The DecodeN() function has been replaced with the image_util_decode_jpeg() and image_util_decode_jpeg_from_memory() functions.
Note that the Tizen::Media::Image::DecodeN() function supports the JPEG, GIF, PNG, BMP, TIFF, and WBMP formats, while the image_util_* functions support only the JPEG format.
ENCODING AN IMAGE TO A FILE -> ENCODING TO A FILE OR MEMORY (IMAGE UTIL TUTORIAL)
The EncodeToFile() function has been replaced with the image_util_encode_jpeg() function.
Note that the Tizen::Media::Image::EncodeToFile() function supports the JPEG, BMP, and PNG formats, while the image_util_* functions support only the JPEG format.
ENCODING AN IMAGE TO A BUFFER AND WRITING TO A FILE -> IMAGE UTIL TUTORIAL
The EncodeToBufferN() function has been replaced with the image_util_encode_jpeg_to_memory() and fwrite() functions to save the buffer into the file.
Note that the Tizen::Media::Image::EncodeToBufferN() function supports the JPEG, BMP, and PNG formats, while the image_util_* functions support only the JPEG format.
Messaging
Sending messages is still done asynchronously, and this is why the callback which notifies about the status of sending the message is needed. In the 2.2.1 API, there was the OnSmsMessageSent() listener. In the 2.3 API, the function responsible for sending messages takes as a parameter the callback function that is called after sending the message is finished and informs about the status of this operation. Creating a message and setting its attributes is similar to the 2.2.1 scenario. The difference is that when you want to create the MMS message, you do not need to create different listeners. The only thing you need to do is to use MESSAGES_TYPE_MMS as a parameter of the messages_create_message() function.
messages_message_h message = NULL; messages_service_h message_service = NULL; // The connection with the message service must be established messages_open_service(&message_service); // To create the MMS, use MESSAGES_TYPE_MMS instead messages_create_message(MESSAGES_TYPE_SMS, &message); messages_add_address(message, "Put the recipient number here", MESSAGES_RECIPIENT_TO); messages_set_text(message, "Put the text of the message here"); // Part for MMS messages only messages_mms_set_subject(message, "Put the MMS subject here"); messages_mms_add_attachment(message, MESSAGES_MEDIA_IMAGE, your_image_file_path); // The third parameter ("true") defines whether to save the message to the sentbox messages_send_message(message_service, message, true, sent_msg_cb, NULL); // Close the connection with the message service, when no longer needed messages_close_service(message_service);
The sent_msg_cb() function is called when the process of sending the message to all recipients is finished:
static void sent_msg_cb(messages_sending_result_e result, void *user_data) { if (MESSAGES_SENDING_SUCCEEDED == result) { dlog_print(DLOG_INFO, LOG_TAG, "Message sending succeeded"); } else { dlog_print(DLOG_INFO, LOG_TAG, "Message sending failed"); } }
To listen for incoming messages in the 2.2.1 API, the OnSmsMessageReceived() listener had to be overridden and the AddSmsMessageEventListener() function used to add the listener to the SMS manager. In the 2.3 API, use the messages_set_message_incoming_cb() function. It registers a callback for the given messages service, invoked when an incoming message is received.
messages_set_message_incoming_cb(message_service, _messages_incoming_cb, NULL); static void _messages_incoming_cb(messages_message_h incoming_message, void *user_data) { // Manage the received message here }
In the 2.3 API, there are 2 ways of searching messages. One way is to use the messages_search_message() function. It works similarly to the SearchMessageBoxN() function from the 2.2.1 API. It returns the list of messages that match the given searching conditions.
messages_message_h *message_array; int array_length; int total_matching; messages_search_message(message_service, MESSAGES_MBOX_ALL, MESSAGES_TYPE_UNKNOWN, "keyword searched in the text and subject", "recipient address", 0, 0, &message_array, &array_length, &total_matching);
The second way is to use the messages_foreach_message() function. In this case, instead of obtaining the list of all the queried messages, the search function iterates through messages and launches a callback for those that match the query.
messages_foreach_message(message_service, MESSAGES_MBOX_ALL, MESSAGES_TYPE_UNKNOWN, "keyword searched in the text and subject", "recipient address", 0, 0, _search_messages_cb, NULL); static void _search_messages_cb(messages_message_h message, int index, int result_count, int total_count, void *user_data) { // Manage the found matching message here return true; // To continue the iteration, return true; otherwise, return false }
Sending an email follows the same pattern as sending an MMS message in both 2.3 and 2.2.1 versions of the API. The difference is that the callback that notifies you about the operation status, after sending is finished, is not passed to the send function, but it is set by an independent email_set_message_sent_cb() function.
email_h email; email_create_message(&email); email_add_recipient(email, EMAIL_RECIPIENT_TYPE_TO, "example@mail.com"); email_add_attach(email, your_attachment_file_path); email_set_message_sent_cb(email, email_send_status, NULL); // The second parameter ("false") defines whether to save the email in the sentbox email_send_message(email, false); static void email_send_status(email_h email, email_sending_e result, void *user_data) { if (EMAIL_SENDING_SUCCEEDED == result) { dlog_print(DLOG_INFO, LOG_TAG, "Email was sent successfully"); } }
PUSH
In the 2.3 API, to work with the push messaging service, you have to fulfill the following requirements:
- Your device must be connected to the internet and be able to contact to any IP addresses with the port 5223.
- Remember that the Tizen push server identifies your applications using the package ID. It is the ID randomly generated or entered by yourself, when you create your project in the Tizen SDK.
- Your application needs to have permission to the Tizen push servers. You can request it by sending an email to the Tizen push service team (push.tizen@samsung.com). You can find the list of required information that you have to put in that email in the 2.3 Push Tutorial. When the team approves your request, you receive a push app ID corresponding to your package ID. You have to keep this push app ID confidential, otherwise your push notifications can be hijacked by malicious applications.
Before you can send messages and register a request for push messaging like in the 2.2.1 API using the RegisterPushService() function, you have to establish the connection with the push daemon using the push_service_connect() function. The first parameter of this function is the push app ID, received from the Tizen push server team. There are also 2 callbacks described below. The next one is dedicated for some user data that is passed to the callback function and the last one is the handle to the push_connection_s structure, which is fulfilled by the function.
push_service_connection_h push_connection; push_service_connect("Push app ID received from the Tizen push server team", _state_cb, _noti_cb, NULL, &push_connection);
The _state_cb parameter is a callback function invoked when the state of the push service changes. It arrives with the current state of the service as its parameter. You can use it to handle the different states of the push service.
static void _state_cb(push_service_state_e state, const char *error, void *user_data) { switch (state) { case PUSH_SERVICE_STATE_UNREGISTERED: dlog_print(DLOG_INFO, LOG_TAG, "The push service is currently unregistered."); break; case PUSH_SERVICE_STATE_REGISTERED: dlog_print(DLOG_INFO, LOG_TAG, "The push service is registered."); break; case PUSH_SERVICE_STATE_ERROR: dlog_print(DLOG_INFO, LOG_TAG, "An error occurred."); break; default: dlog_print(DLOG_INFO, LOG_TAG, "Unknown state."); } }
The _noti_cb parameter is a callback function invoked when a notification arrives from the server through the push daemon.
static void _noti_cb(push_service_notification_h notification, void *user_data) { char *data = NULL; char *message = NULL; long long int time_stamp; // Retrieve the application data stored in the notification push_service_get_notification_data(notification, &data); // Retrieve the message carried by the notification push_service_get_notification_message(notification, &message); // Retrieve the time of the notification creation push_service_get_notification_time(noti, &time_stamp); }
Remember that the push_service_get_notification_data() and push_service_get_notification_message() functions allocate the memory for the data they return, so this memory needs to be released with the free() function when it is no longer needed. However, do not free the notification structure. It is released automatically after the callback function execution.
When the connection with the push daemon is established, you can proceed with the registration process of your application. The push_service_register() function is an equivalent for the RegisterPushService() function. However, it no longer takes the request ID. It takes the daemon connection handle and the result callback function instead. The callback is called at the end of the registration process. That callback carries the result of the registration as its first parameter. The application does not have to deliver the registration ID anymore. It is assigned by the push server and can be obtained with the push_service_get_registration_id() function.
push_service_register(push_connection, _result_cb, NULL); static void _result_cb(push_service_result_e result, const char *msg, void *user_data) { if (PUSH_SERVICE_RESULT_SUCCESS == result) { dlog_print(DLOG_INFO, LOG_TAG, "Your application has been successfully registered to the push server."); } }
The UnregisterPushService() function from the 2.2.1 API also has its equivalent - the push_service_deregister() function. It takes the same parameters as the registration function.
push_service_deregister(push_connection, _deregistration_result_cb, NULL); static void _deregistration_result_cb(push_service_result_e result, const char *msg, void *user_data) { if (PUSH_SERVICE_RESULT_SUCCESS == result) { dlog_print(DLOG_INFO, LOG_TAG, "Your application has been successfully deregistered from the push server."); } }
The 2.3 API supports handling the push messages in 2 different ways as it was in the 2.2.1 model. If the application is running (connected to the push daemon) and the message is received, the notification callback set during establishing the connection with the push daemon is called. It is like the IPushEventListener::OnPushMessageReceived() event handler from the 2.2.1 API. In the second situation, when the application is not running, there are 2 possible solutions. One is like in 2.2.1 and involves saving the notification in a database and reading it later, when the application is launched. This functionality can be handled by using the push_service_get_unread_notification() function like the GetUnreadMessagesN() function from the 2.2.1 API.
push_service_notification_h notification; push_service_get_unread_notification(push_connection, ¬ification);
The second one differs from the one from 2.2.1. The push message can be send from your application server with an option 'action=LAUNCH', which forcibly launches the application and delivers the notification as a bundle. To handle this situation, the app_control_get_operation() function from the App Control module is required. This function gets the operation that must be performed based on the app_control_h handle passed to the app_control() callback that is invoked when your application is launched by another application or process.
static void app_control(app_control_h app_control, void *data) { char *operation = NULL; char *notification_data = NULL; app_control_get_operation(app_control, &operation); // Retrieve notification data notification_data = push_service_app_control_to_noti_data(app_control, operation); from the bundle. }
Remember to release the memory allocated for the operation and notification_data to avoid memory leaks.
Net
The initialization of the Bluetooth connection does not require the creation of the Bluetooth class. In the 2.3 API, the bt_initialize() function must be called without any parameters.
bt_initialize();
The Bluetooth adapter can be launched by calling the example application offered in the Bluetooth tutorial. Getting the name and address of the local device is done in the same way as in the 2.2.1 API. The difference is in getting the list of paired devices. The bt_adapter_foreach_bonded_device() function iterates through all the bonded devices instead of returning the list of paired devices like the GetPairedDeviceListN() function from the 2.2.1 API. The specified callback is called for every paired device. The callback carries the information about a particular bonded device as its first parameter, so it is possible to check the device name by looking at the passed bt_device_info_s structure.
The documentation for the Bluetooth OPP (Object Push Profile) client provides functions to initialize the OPP client (bt_opp_client_initialize()), add files to be pushed (bt_opp_client_add_file()), and push them to the OPP server (bt_opp_client_push_files()).
char remote_address[18] = "The address of the remote device"; bt_opp_client_initialize(); bt_opp_client_add_file(your_file_path); bt_opp_client_push_files(remote_address, _bt_opp_client_push_responded_cb, _bt_opp_client_push_progress_cb, _bt_opp_client_push_finished_cb, NULL); void _bt_opp_client_push_responded_cb(int result, const char *remote_address, void *user_data) { // Called when OPP server responds to the push request } void _bt_opp_client_push_progress_cb(const char *file, long long size, int percent, void *user_data) { // Called when each file is being transferred } void _bt_opp_client_push_finished_cb(int result, const char *remote_address, void *user_data) { // Called when the push request is finished }
For more details, see the Exchanging Data Using Object Push Profile (OPP) use case of the Bluetooth Tutorial and the Bluetooth OPP Client API Reference.
The OPP server in the 2.3 API works similarly to the 2.2.1 model. The bt_opp_server_initialize_by_connection_request() function replaces the StartService() function. It defines that the specified callback is called to handle the incoming OPP connection request. There are also functions for setting the destination, accepting the push request, and stopping the push service. For more information, see the Bluetooth OPP Server tutorial.
bt_opp_server_initialize_by_connection_request(your_destination_path, connection_requested_cb_for_opp_server, NULL); void connection_requested_cb_for_opp_server(const char *remote_address, void *user_data) { // Called when an OPP connection is requested // Call bt_opp_server_accept_connection() if you want to accept // Otherwise, call bt_opp_server_reject_connection() }
For the Bluetooth SPP module, see the Serial Port Profile (SPP) use case of the Bluetooth Tutorial for 2.3 API.
The 2.3 API supports the Bluetooth Health Device Profile (HDP) connections. Connecting to the source is similar, just the name of the function has changed a little. The connection is being established asynchronously, so still some kind of listener or callback is needed. This time (in the 2.3 API), the callbacks for connected and disconnected states are set by using the bt_hdp_set_connection_state_changed_cb() function. The rest of the functionality is pretty much the same, so check the new function names in the documentation.
The Discovering Bluetooth Devices use case works similarly in both 2.2.1 and 2.3 APIs. For more information, see the Finding Other Devices use case in the Bluetooth Tutorial for the 2.3 API.
Pairing 2 Bluetooth devices is called bonding devices in the 2.3 API. The bt_device_create_bond() function works like the Pair() function in the 2.2.1 API. The IBluetoothDeviceEventListener::OnBluetoothPaired() event handler is now covered by the functionality of the bt_device_set_bond_created_cb() function, which sets the callback invoked when the pairing process is finished.
All the functionality connected with the HTTP protocol is now covered by the libcurl library. All the sockets are now provided with glibc library.
The process of Activating and Deactivating a Wi-Fi Device is very similar in both 2.2.1 and 2.3 tutorials. The wifi_activate() and wifi_deactivate() functions work like Activate() and Deactivate() in 2.2.1. Instead of creating a Wi-Fi manager, the 2.3 API requires you to call the wifi_initialize() function before starting the work with Wi-Fi.
wifi_initialize(); wifi_deinitialize();
Security
Most of the security features from the 2.2.1 API are provided now by the OpenSSL library. However, there is also a Key Manager module in the 2.3 API, which enables some of the 2.2.1 Security module functionalities.
In 2.2.1, the GenerateKeyPairN() function was used to generate a pair of keys. Then the EncryptN() method of the RsaCipher class was used to apply the RSA cipher to the generated keys. In the 2.3 API, to generate key pairs (RSA or ECDSA), use the ckmc_create_key_pair_rsa() or ckmc_create_key_pair_ecdsa() function.
size_t size = 2048; // Key Manager supports 1024, 2048, and 4096 const char *private_key_alias = "PRV_RSA1"; const char *public_key_alias = "PUB_RSA1"; ckmc_policy_s policy_private_key; ckmc_policy_s policy_public_key; // This private key is encrypted with a password additionally policy_private_key.password = (char *)"pri_password"; // This key cannot be extracted from the key manager policy_private_key.extractable = false; policy_public_key.password = NULL; policy_public_key.extractable = true; ckmc_create_key_pair_rsa(size, private_key_alias, public_key_alias, policy_private_key, policy_public_key);
The generation of the pseudo-random numbers is now provided by the OpenSSL rand generator.
All the cryptographic algorithms presented in the 2.2.1 tutorials, such as AES, Hash, HMAC and RSA, are provided by the OpenSLL library as well, so if you need them in your application, study the OpenSLL documentation and examples.
Shell
The Creating Notifications use case can now be found in the Application Framework module instead of the 2.2.1 Shell module. The notification is created with the notification_create() function, which takes the notification type (Regular or Ongoing) as its parameter. This allowed the reduction of all the different Notify() functions from the 2.2.1 API to 1 notification_post() function.
notification_h notification; // The NOTIFICATION_TYPE_ONGOING can also be used here notification = notification_create(NOTIFICATION_TYPE_NOTI); notification_set_text(notification, NOTIFICATION_TEXT_TYPE_TITLE, "I'm Title", "IDS_APP_BODY_IM_TITLE", NOTIFICATION_VARIABLE_TYPE_NONE); notification_post(notification);
Social
ACCOUNT MANAGEMENT
In the 2.3 API, there is no account manager instance. The connection with the accounts database has to be established instead. The constructor for the account is replaced with the account_create() function. The AddAccount() function from the 2.2.1 API is covered by the account_insert_to_db() function. Differently from the old function, the new one takes an additional parameter, the pointer to the account ID. This parameter is filled with the ID associated with the account inside the database.
account_h account = NULL; int account_id = 0; account_connect(); // Establish the connection with the account database account_create(&account); account_insert_to_db(account, &account_id);
The SetExtendedData() function is replaced with the account_set_custom() function and some other functions provided to set each of the account additional information (for example: account_set_user_name()).
account_set_user_name(account, "account user name"); account_set_display_name(account, "account display name"); account_set_domain_name(account, "account domain name"); account_set_email_address(account, "account email address"); account_set_custom(account, "key1", "value1");
Instead of a single UpdateAccount() function, the 2.3 API has account_update_to_db_by_id(), account_update_to_db_by_id_ex(), and account_update_to_db_by_user_name() functions to update the account information.
account_update_to_db_by_id(account, account_id); // OR // Updates the account without checking provider's permission account_update_to_db_by_id_ex(account, account_id); // OR account_update_to_db_by_user_name(account, "account user name", "package name for the user name");
The removal of the account is now covered by the account_delete_from_db_by_id(), account_delete_from_db_by_package_name(), and account_delete_from_db_by_user_name() functions, instead of the RemoveAccount() function.
account_delete_from_db_by_id(account_id); // OR account_delete_from_db_by_package_name("package name for the user name") // OR account_delete_from_db_by_user_name("account user name", "package name for the user name");
The GetAccountsByAccountProviderN() functionality is now described in the Retrieving Accounts by Account Provider use case in the 2.3 Account Tutorial. Mainly, the account_query_account_by_package_name() function is responsible for that. Instead of returning the list of accounts, it invokes a callback, specified as its first parameter, for every account that matches given package name.
account_query_account_by_package_name(account_callback, "The package name of the account provider", NULL); static bool account_callback(account_h account, void* user_data) { // Called once for each account in the database matching the given package name }
The GetAccountProvidersByCapabilityN() method is covered by the account_type_query_by_provider_feature() function. It does not return the list of account providers, but it invokes the callback specified as the first parameter for each account type that supports the mentioned capability. It takes the capability type as its second parameter. For example, the "http://tizen.org/account/capability/contact" or ACCOUNT_SUPPORTS_CAPABILITY_CONTACT can be used.
account_type_query_by_provider_feature(account_type_callback, "http://tizen.org/account/capability/contact", NULL); static bool account_type_callback(account_type_h account_type, void* user_data) { // Called once for each account type in the database matching given provider capability }
ADDRESS BOOK
The Contact module in the 2.3 API has a similar mechanism as the Account Manager module. Again, like it was with accounts, there is no addressbook manager instance. The connection with the contacts database has to be established instead. Use the contacts_connect() function for this purpose.
contacts_connect(); contacts_disconnect();
When the work with contacts is finished, the connection with the database must be closed with the contacts_disconnect() function.
RETRIEVING PERSON INFORMATION
The GetAllPersonsN() functionality is now covered by the contacts_db_get_all_records() function. It can be used to retrieve all types of records stored in the contacts database. To obtain the list of all persons, the _contacts_person._uri value must be used as its first parameter.
contacts_list_h list = NULL; contacts_db_get_all_records(_contacts_person._uri, 0, 0, &list);
Note that the first "0" defines the offset - the starting index for getting results. The second one defines the limit for the number of obtained results. In case of the "0" value, all the records are obtained.
To move through the retrieved list, use the Contacts' List submodule API. It is very similar to the matching functionality from the 2.2.1 API. In the 2.3 API, the MoveNext() function is covered by the contacts_list_next() function. The GetCurrent() functionality is provided by the contacts_list_get_current_record_p() function. No enumerator is required. All the actions are called directly for the list, so the handle to that list is always passed as the first parameter for every function from the List submodule.
int list_count, counter; contacts_record_h record; char *display_name; char *image_thumbnail_path; contacts_list_get_count(list, &list_count); for (counter = 0; counter < list_count; counter++) { contacts_list_get_current_record_p(list, &record); contacts_record_get_str(record, _contacts_person.display_name, &display_name); contacts_record_get_str(record, _contacts_person.image_thumbnail_path, &image_thumbnail_path); // Manage the display name and thumbnail path for the currently obtained contact here contacts_list_next(list); }
There is no GetFavoritePersonsN() function anymore. To retrieve the list of all favorite contacts, a query filter must be used. The filter is created with the contacts_filter_create() function. To query for favorite contacts, the following condition must be added to the filter:
contacts_filter_h filter = NULL; contacts_filter_create(_contacts_person._uri, &filter); contacts_filter_add_bool(filter, _contacts_person.is_favorite, true);
The filter is the handle to the filter instance. The _contacts_person.is_favorite parameter defines which field the filter operates on. If you want to find only favorite contacts, you define the is_favorite field and set it to true (the third parameter). The whole process of searching the contacts is described below, under the SEARCHING PERSONS USING COMPLEX CONDITIONS use case.
MANAGING FAVORITES
The SetPersonAsFavorite() function is replaced with the contacts_record_set_bool() function. This new function can be used to set the Boolean property by using the property ID and the desired Boolean value. It can be done during the creation of the contact record or applied to the contact that already is placed in the database. In the second case, the contacts_db_update_record() function has to be called after changing the value, to update this value in the database record.
contacts_record_h contact = NULL; contacts_record_create(_contacts_contact._uri, &contact); contacts_record_set_bool(contact, _contacts_contact.is_favorite, true);
To remove a contact from the favorite contacts, the same function must be used, with false as its third parameter. After this operation, the contact record has to be updated in the database with the contacts_db_update_record() function.
contacts_record_set_bool(contact, _contacts_contact.is_favorite, false); contacts_db_update_record(contact);
MANAGING PRIMARY PHONE NUMBER
Retrieving the default phone number of some person or a single contact is now a little different. In the 2.2.1 API, the first step was to obtain the list of all the person's contacts with the GetContactsByPersonN() function. Then, the specified contact instance was retrieved from the list with the GetAt() function. The next step was to invoke the Contact method called GetValuesN() with the CONTACT_MPROPERTY_ID_PHONE_NUMBERS enumeration value as its parameter, to get the list of all phone numbers attached to that particular contact. The primary phone number of that contact was stored as the first one on the list, so it was obtained with the GetAt(0) method called on the phone number list. In the 2.3 API, to get the default phone number for the person's particular contact, use the querying functionality. First of all, query for the contacts linked to the given person. When the list with those contacts is obtained, use the ID of the chosen contact. For the query, use the contacts_record_get_child_record_at_p() function. It returns the child record of the given parent record. If there are multiple child records entities, the index specifies which record is obtained.
int person_id, contact_id; contacts_record_h contact, contact_default_number; contacts_query_h query, query2; contacts_filter_h filter, filter2; contacts_list_h associated_contacts, default_numbers; // Getting the ID of the managed person contacts_record_get_int(person, _contacts_person.id, &person_id); contacts_query_create(_contacts_contact._uri, &query); contacts_filter_create(_contacts_contact._uri, &filter); contacts_filter_add_int(filter, _contacts_contact.person_id, CONTACTS_MATCH_EQUAL, person_id); contacts_query_set_filter(query, filter); // Obtain the list of contacts associated with the managed person contacts_db_get_records_with_query(query, 0, 0, &associated_contacts); contacts_list_next(associated_contacts); // Move to the second contact of the person (like in 2.2.1) // Get the contact record to search for its default phone number contacts_list_get_current_record_p(associated_contacts, &contact); // Getting the ID of the managed person contacts_record_get_int(contact, _contacts_contact.id, &contact_id); contacts_query_create(_contacts_contact_number._uri, &query2); contacts_filter_create(_contacts_contact_number._uri, &filter2); contacts_filter_add_bool(filter2, _contacts_contact_number.is_primary_default, true); contacts_query_set_filter(query2, filter2); contacts_db_get_records_with_query(query2, 0, 0, &default_numbers); contacts_list_get_current_record_p(default_numbers, &contact_default_number); // Release unnecessary resources contacts_list_destroy(associated_contacts, true); contacts_list_destroy(default_numbers, true); contacts_filter_destroy(filter); contacts_filter_destroy(filter2); contacts_query_destroy(query); contacts_query_destroy(query2);
It is also possible to get person's default number by using the contacts_person_get_default_property() function with CONTACTS_PERSON_PROPERTY_NUMBER as a first parameter. It returns the ID of the number record that is currently set to be the default number for the given person.
int person_default_number_id; contacts_record_h person_default_number = NULL; contacts_person_get_default_property(CONTACTS_PERSON_PROPERTY_NUMBER, person_id, &person_default_number_id); contacts_db_get_record(_contacts_person_number._uri, person_default_number_id, &person_default_number);
The SetAsPrimaryPhoneNumber() function is replaced with the contacts_person_set_default_property(). You have to pass the ID of the contact and the ID of the number record that must be set as default.
contacts_person_set_default_property(CONTACTS_PERSON_PROPERTY_NUMBER, person_id, person_default_number_id);
SEARCHING PERSONS USING COMPLEX CONDITIONS
To search for the contacts matching some complex conditions, use filters as in the 2.2.1 API. It is still possible to add different conditions to the filter with the proper API functions and connect them by using operators between them. The SearchN() function is replaced with the contacts_db_get_records_with_query() function. Familiarize yourself with the new filter syntax by reading the documentation and tutorials.
contacts_list_h list = NULL; contacts_query_h query = NULL; contacts_filter_h filter = NULL; contacts_query_create(_contacts_person._uri, &query); contacts_filter_create(_contacts_person._uri, &filter); contacts_filter_add_str(filter, _contacts_person.display_name, CONTACTS_MATCH_CONTAINS, "John"); contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND); contacts_filter_add_bool(filter, _contacts_person.is_favorite, true); contacts_query_set_filter(query, filter); contacts_db_get_records_with_query(query, 0, 0, &list);
The iteration through each person on the list was described in the RETRIEVING PERSON INFORMATION use case above.
CREATING AND MANAGING CATEGORIES AND CONTACTS
In the 2.3 API, the categories are called groups. There is one function to create both contact and group - contacts_record_create(). The first parameter of this function defines whether it is a group or contact. After the record is created, different values can be set by using specified API functions. When the record is ready, insert it to the database with the contacts_db_insert_record() function. The AddMemberToCategory() function is replaced with the contacts_group_add_contact() function. As in the 2.2.1 API, this function also takes the group ID and contact ID as its parameters.
contacts_record_h group = NULL; contacts_record_h contact = NULL; int added_group_id = -1; int contact_id = -1; // Create and add new group contacts_record_create(_contacts_group._uri, &group); contacts_record_set_str(group, _contacts_group.image_path, your_group_image_path); contacts_record_set_str(group, _contacts_group.ringtone_path, your_ringtone_path); contacts_db_insert_record(group, &added_group_id); // Create and add new contact contacts_record_create(_contacts_contact._uri, &contact); contacts_record_set_str(contact, _contacts_contact.display_name, your_contact_display_name); contacts_record_set_str(contact, _contacts_contact.ringtone_path, your_ringtone_path); contacts_db_insert_record(contact, &contact_id); // Add the contact to the group contacts_group_add_contact(group, contact_id);
DISPLAYING ALL CATEGORIES AND THEIR MEMBERS
In the 2.3 API, the GetAllCategoriesN() function has been replaced with the contacts_db_get_all_records() function. This function enables you to get all the records of a specified type. To retrieve the list of all groups, the _contacts_group._uri must be used as its parameter. To move through the list, use the contacts_list_next() or contacts_list_prev() function. The GetCurrent() function is called contacts_list_get_current_record_p() in the 2.3 API. After getting the record, it is possible to get its properties using 2.3 API functions, for example, contacts_record_get_str_p(record, _contacts_group.name, &name) to obtain the name of the group. The function is similar to the GetValue() function in the 2.2.1 API.
contacts_list_h groups_list = NULL; contacts_record_h single_group = NULL; int groups_count, groups_counter, group_id; contacts_query_h query = NULL; contacts_filter_h filter = NULL; contacts_list_h group_members = NULL; int group_members_count, group_members_counter, member_id; contacts_record_h member = NULL; char *member_display_name, group_name; contacts_db_get_all_records(_contacts_group._uri, 0, 0, &groups_list); contacts_list_get_count(groups_list, &groups_count); for (groups_counter = 0; groups_counter < groups_count, groups_counter++) { contacts_list_get_current_record_p(groups_list, single_group); contacts_record_get_str_p(single_group, _contacts_group.id, &group_id); contacts_record_get_str_p(single_group, _contacts_group.name, &group_name); dlog_print(DLOG_INFO, LOG_TAG, "Group name: %s", group_name); contacts_query_create(_contacts_person_group_assigned._uri, &query); contacts_filter_create(_contacts_person_group_assigned._uri, &filter); contacts_filter_add_int(filter, _contacts_person_group_assigned.group_id, CONTACTS_MATCH_EQUAL, group_id); contacts_query_set_filter(query, filter); contacts_db_get_records_with_query(query, 0, 0, &group_members); contacts_list_get_count(group_members, &group_members_count); for (group_members_counter = 0; group_members_counter < group_members_count; group_members_counter++) { contacts_list_get_current_record_p(group_members, member); contacts_record_get_int(member, _contacts_person_group_assigned.person_id, &member_id); dlog_print(DLOG_INFO, LOG_TAG, "Member id: %d", member_id); contacts_record_get_str_p(member, _contacts_person_group_assigned.display_name, &member_display_name); dlog_print(DLOG_INFO, LOG_TAG, "Member display name: %s", member_display_name); contacts_list_next(group_members); } contacts_list_next(groups_list); }
RETRIEVING CONTACTS AND CATEGORIES STORED ON THE DEVICE
The CreateAddressbookN() function is now covered by the contacts_record_create() function. To create the address book, the _contacts_address_book._uri must be used as a parameter for this function. Add this record to the database by using the contacts_db_insert_record() function. After creating the address book, you already have the handle to it. If you want to get this address book later, query for it. The DeleteAddressbook() function is replaced with the contacts_db_delete_record(). It removes the address book from the device by deleting it from the database.
To get all the address books stored on the device, use the contacts_db_get_all_records() again, instead of the GetAllAddressbooksN() function. The parameter is _contacts_address_book._uri. This returns the list of all the address book records stored on the device. The navigation through the list is done the same way as it was in case of group list and contact list.
SEARCHING CONTACTS BY NAME
The SearchContactsByName() function is covered by the functionality of the filters and queries in the 2.3 API. It is described in the Getting Contacts use case of the 2.3 Contacts Tutorial. The filter for the query has to be created and the condition for _contacts_person.display_name must be added to this filter. Then it is possible to query all the contacts stored on the device to look for the given display name. The list of matching contacts is returned. All the operations on the retrieved list have been described above.
GETTING ADDRESS BOOK CHANGE NOTIFICATIONS
The 2.2.1 API provided listeners to get notifications about contacts and groups changes. The 2.3 API delivers the contacts_db_add_changed_cb() function. Using this function, it is possible to register callbacks for record changes. It can be done for each type of records, including contacts and groups. You can check the code example in the Monitoring Person Changes use case of the Contacts Tutorial for the 2.3 API.
CALENDAR BOOK
The 2.3 Calendar API model is similar to the 2.3 Contacts model.
ADDING CALENDARS
Instead of using the constructor and AddCalendar() function to create a new calendar on the device, the calendar_record_create() function with _calendar_book._uri must be used to create the calendar and the calendar_db_insert_record() function to add it to the device database. There is no more AddEvent() function. In the 2.3 API, you can create an event as a separate calendar database record and then set its calendar_book_id field to point to the calendar that you want it to be correlated with.
calendar_record_h calendar_book = NULL; int book_id = -1; calendar_connect(); calendar_record_create(_calendar_book._uri, &calendar_book); calendar_db_insert_record(calendar_book, &book_id);
ADDING CALENDAR EVENTS
The event is created with the calendar_record_create() function. After this operation, all the properties of the events can be set similarly like in the 2.2.1 API. The summary (subject in 2.2.1) can be set with the calendar_record_set_str() function, like other string type values. Other 2.2.1 and 2.3 function mappings in case of the calendar event are as follows:
- SetStartAndEndTime() -> calendar_record_set_caltime()
- SetFrequency() -> calendar_record_set_int(..., _calendar_event.freq, ...)
- SetUntil() -> calendar_record_set_int(..., _calendar_event. until_time, ...)
- SetInterval() -> calendar_record_set_int(..., _calendar_event.interval, ...)
- SetDayOfWeek() -> calendar_record_set_str(..., _calendar_event.byday, ...)
ADDING CALENDAR TASKS
The creation of tasks is possible with the calendar_record_create() function. The parameter is _calendar_todo._uri. Setting all the properties of a task does not require a different function for each parameter anymore. The 2.3 API provides a few functions to set properties depending on their types:
- calendar_record_set_str() to set all the string values
- calendar_record_set_int() to set all the integer values
- calendar_record_set_caltime() to set all the calendar_time_s values
The rest of such functions and the list of properties of a task can be found in the documentation for the 2.3 API.
REMOVING CALENDAR EVENTS
The RemoveEvent() function is now covered by the calendar_db_delete_record() function. It takes the ID of an event as its parameter and also requires the type of the record, in this case the _calendar_event._uri type.
UPDATING CALENDAR TASKS
The process of updating calendar tasks using the 2.3 API is the same as updating an event, which is described in the Updating an Event section of the Calendar Tutorial for the 2.3 API. The UpdateTodo() function is now covered by the calendar_db_update_record() function. As can be seen, the function does not specify what kind of a record is actually being updated. The only parameter it takes is the record handle. The function recognizes what kind of a record ii is dealing with internally and updates it in the database. Before using the updating function, the calendar_db_get_record() function with _calendar_todo._uri parameter must be used to obtain the record that you want to update. Then some properties of the record can be changed with the set of functions mentioned above. Finally, when the record is updated, the calendar_db_update_record() is used to store the changes in the database.
SEARCHING EVENT INSTANCES
The process of filtering and querying for the calendar records is pretty much the same as this process for the contacts database. Basically, also the query and the filter have to be created. Filtering conditions are added by using the calendar_filter_add_str() functions and the calendar_filter_add_operator() function to connect different conditions. The SearchN() functionality is covered by the calendar_db_get_records_with_query() function.
GETTING CALENDAR CHANGE NOTIFICATIONS
Similarly, like in the previous section about contacts, several callbacks can be set to monitor the calendar changes. The matching functionality of the OnCalendarEventsChanged() and OnCalendarTodosChanged() listeners from the 2.2.1 API is now provided by the calendar_db_add_changed_cb() function. It enables you to set callbacks invoked when some changes in calendar events or tasks (todos) are made.
System
CREATING A DAILY ALARM
The daily alarm creation functionality is now under Application Framework -> Application -> Alarm submodule. The tutorial for the 2.3 API Alarm module can be found here.
Instead of creating a class with the implementation of the Tizen::System::IAlarmEventListener interface in it, the 2.3 API simply provides some functions to set the alarm. To set the alarm to be launched at the specified time, use the alarm_schedule_at_date() function.
POWER MANAGER
The 2.3 tutorial for this feature can be found in the Controlling the Power State use case of the Attached Device Tutorial.
The KeepScreenOnState() function matches 2 functions in the 2.3 API:
- device_power_wakeup() function sets the current power state to normal or dim state, depending on the given parameter.
- device_power_request_lock() function allows you to lock the current state for the specified time.
The Controlling the Display use case describes how to get and set the brightness like it was done using the GetScreenBrightness() and SetScreenBrightness() functions in the 2.2.1 API. There are similar functions in the 2.3 API: device_display_get_brightness() and device_display_set_brightness().
The Getting the Battery Level process is described under Retrieving Battery Information in the Device Tutorial for the 2.3 API. The functions map as follows:
- GetCurrentLevelInPercentage() -> device_battery_get_percent()
- IsCharging() -> device_battery_is_charging()
GETTING SETTING INFORMATION
This process is almost the same in both 2.2.1 and 2.3 APIs. The 2.3 tutorial for this is named System Setting Tutorial.
The GetValue() function has been replaced with multiple system_settings_get_value_* functions depending on the type of value to be obtained. For example, to obtain a string value, use the system_settings_get_value_string() function.
GETTING SYSTEM INFORMATION
The 2.3 tutorial for this section is under Device-specific System Information Tutorial.
The GetValue() function for obtaining the system information has also been replaced with various functions like in the System Setting model. For example, to obtain the string value for some System Information, use the system_info_get_platform_string() function.
GETTING THE SYSTEM TIME
Instead of SystemTime::GetCurrentTime, you can use:- i18n_ucalendar_get_now() from the i18n module
- g_date_time_new_now() from GLib
- Functions from Eglibc (a variant of glibc)
VIBRATING THE DEVICE
This section is covered by the Controlling Haptic Devices use case of the Device Tutorial for the 2.3 API.
The Start() function is now called device_haptic_vibrate(). To stop the vibrations, use the device_haptic_stop() function.
haptic_device_h device; device_haptic_open(0, &device); int duration = 1000; int feedback = 20; // [0-100], vibration intensity haptic_effect_h effect; device_haptic_vibrate(device, duration, feedback, &effect); // Also obtains the played effect handle // Use the effect handle to stop the effect device_haptic_stop(device, effect);
Telephony
GETTING CURRENT CALL INFORMATION
The GetCurrentCallStatus() function is now covered by the telephony_call_get_voice_call_state() function.
GETTING NETWORK INFORMATION
The old and new functions match as follows:
- IsCallServiceAvailable() -> telephony_network_get_type()
- IsDataServiceAvailable() -> telephony_network_get_type()
- IsRoaming() -> telephony_network_get_roaming_status()
- GetMnc() -> telephony_network_get_mnc()
- GetMcc() -> telephony_network_get_mcc()
- GetCellId() -> telephony_network_get_cell_id()
- GetLac() -> telephony_network_get_lac()
- GetOperatorName() -> telephony_network_get_network_name()
- GetRssi() -> telephony_network_get_rssi()
GETTING NOTIFICATIONS OF CALL STATUS CHANGES
Listening for call status changes is similar in both 2.2.1 and 2.3 APIs. The 2.2.1 API provided the OnTelephonyCallStatusChangedN() event handler to listen for those changes. In the 2.3 API, a callback function can be registered with the telephony_set_noti_cb() function, to be triggered when the state of the call changes. The second parameter has to be TELEPHONY_NOTI_VOICE_CALL_STATE to define that the callback is registered for call status changes.
GETTING NOTIFICATIONS OF NETWORK STATUS CHANGES
This case is almost the same as the previous one. The OnTelephonyNetworkStatusChanged() listener is replaced with a callback registered using the telephony_set_noti_cb() function with TELEPHONY_NOTI_NETWORK_SERVICE_STATE as its second parameter.
GETTING SIM CARD INFORMATION
The SIM card is determined by the telephony_h handle, which is obtained from the telephony_init() function. Information stored on the SIM card can be retrieved by using the following functions:
- IsAvailable() -> telephony_sim_get_state()
- GetMnc() -> telephony_sim_get_operator()
- GetMcc() -> telephony_sim_get_operator()
- GetSpn() -> telephony_sim_get_spn()
- GetIccId() -> telephony_sim_get_icc_id()
Text
In the 2.3 API, the conversion between Unicode and UTF-8 formats is covered by the EFL functionality. The Eina library provides:
- eina_unicode_utf8_to_unicode()
- eina_unicode_unicode_to_utf8()
- Other eina_unicode_* utility functions
UIX
GETTING DATA FROM DEVICE SENSORS
The old and new functions match as follows:
IsAvailable() -> sensor_is_supported()
GetMinInterval() -> sensor_get_min_interval()
AddSensorListener() -> sensor_create_listener(), sensor_listener_set_event_cb(), and sensor_listener_start() (receive events in the callback, check sensor type in the event handler, and use the sensor_event_s data)
RemoveSensorListener() -> sensor_listener_unset_event_cb(), sensor_listener_stop(), and sensor_destroy_listener()
DETECTING DOUBLE-TAPS
In the 2.2.1 API:
- Tizen::Uix::Sensor::Motion* pMotion
- pMotion->SetEnabled(MOTION_TYPE_DOUBLETAP)
In the 2.3 API:
- gesture_h gesture;
- gesture_create()
- gesture_start_recognition(gesture, GESTURE_DOUBLE_TAP, ...)
For more information, see the Gesture Recognition API Reference.
Web
JSON
In the 2.2.1 API, the Tizen::Web::Json namespace was used.
In the 2.3 API, the Json-glib library is used.
WEB CONTROLS
In the 2.2.1 API, the Tizen::Web::Controls::Web namespace was used.
In the 2.3 API, the WebView module provides those functionalities.
INITIALIZING THE WEB CONTROL INSTANCE
In 2.2.1 API, it was done this way:
- Create the Tizen::Web::Controls::Web *__pWeb object.
- Set the shape with the __pWeb->Construct() function.
- Add the control to a window with the form->AddControl(__pWeb) function.
Initializing in 2.3 is vastly different. A very brief outline is below. For more information, see the tutorial.
- Basic structure (example):
typedef struct _Browser_Window { Evas_Object *elm_window; Evas_Object *ewk_view; } Browser_Window Browser_Window *window;
- Create the window with the elm_win_add() function.
- Create a new EFL WebKit view object:
Evas *evas = evas_object_evas_get(window->elm_window); window->ewk_view = ewk_view_add(evas);
LOADING A WEB PAGE
The 2.2.1 API used the __pWeb->LoadUrl(url) function, while the 2.3 API uses the ewk_view_url_set() function.