Communication within a Tizen Hybrid app

Introduction

In this tip document, communication within a Tizen hybrid app will be introduced. For simpler description, a Tizen web app and a native service are packaged together to build a sample hybrid app. This hybrid app will show the content of a message from a particular number. To detail out, the web app will request message contents and the native service will retrieve the contents using native API and then will pass onto web app for display. So, the focus is commutation between this web application (which has the UI) and the native service (which act as a background service without any UI).

At first, the steps that are followed to create this Hybrid App:   
• Create a web application project
• Create a native service project
• Package both app and define the reference in the project’s properties
• Define a communication way between the web and service applications
• Build the application
• Install the application

Packaging Method

https://developer.tizen.org/ko/development/training/native-application/application-development-process?langredirect=1#develop

Part 1: Building the Web Application

Prerequisites:

Privilege

Description

http://tizen.org/privilege/appmanager.launch

Allows the application to open other applications using the application ID or application control.

 

This web app uses application control as a “bridge” between the web and service application. Hence, launching the service app is done using the launchAppControl() method. While requesting to launch the service app, this web application sends the following as the parameters of this method:
 
1. A data structure, specific phone number that Native service will use to retrieve message contents.
2. ID of the application which user are requesting to launch.
3. successCallback, the method to call when the requested application launches successfully.
4. errorCallback, the method to invoke when an error occurs.
5. replyCallback, the method to invoke when the application gets back results from the launched application.
The launch app control method can be written as format below:
tizen.application.launchAppControl(obj1,
"Service_App_ID",
function() {console.log("Launch Service succeeded"); },
function(e) {console.log("Launch Service failed : " + e.message);},
appControlReplyCallback);

In this web app, the code snippet for creating the data structure:

var obj = new tizen.ApplicationControlData("47sbr7nUs6.BasicUIsmsText", ["+8801*********"]);
	
var obj1 = new tizen.ApplicationControl("http://tizen.org/appcontrol/operation/service",
				null,
				null,
				null,
				[obj] 
		);

Then, this sample app sends a “Success” message to the service app after its launch. Related code as below:

if(contentText.innerHTML != "Basic")
{
var obj = new tizen.ApplicationControlData("YOUR_UI_APP_ID", ["Success"]);
}
else
{

var obj = new tizen.ApplicationControlData("47sbr7nUs6.BasicUIsmsText", ["+880**********"]);

}

To receive the message content against a specific phone number provided by the requested web app, appControlReplyCallback is used. The code used is given below:

var appControlReplyCallback = {
				// callee sent a reply
				onsuccess: function(data) {

					contentText.innerHTML = data[0].value[0];

				},
				// callee returned failure
				onfailure: function() {
					console.log('The launch application control failed');
				}
		}

 

Part 2: Building the Service Application

Native service application for retrieving message content of a specific number is described here.

Receiving data from the Web UI app and replying back:

At first, the native service receives a phone number from UI app through app_control() function. Then the service sends the message content. Once the UI app receives message content, it sends an acknowledgement to the service.

The app_control() function can be written as below:

void service_app_control(app_control_h app_control, void *data)
{
	appdata_s *ad = (appdata_s *) data;
	char *operation;
	char *app_id;
	app_control_h reply;
	app_control_get_operation(app_control, &operation);

	if (!strcmp(operation, "http://tizen.org/appcontrol/operation/service")) {
		char *phone_number;
		app_control_get_extra_data(app_control, "UI_App_ID", &phone_number);

		app_control_create(&reply);

		app_control_get_app_id(app_control, &app_id);
		if(!strcmp(phone_number, "Success"))
		{
			app_control_add_extra_data(reply, APP_CONTROL_DATA_SELECTED, "Ok");
		}
		else
		{
			message_box_cb(ad, phone_number);
			app_control_add_extra_data(reply, APP_CONTROL_DATA_SELECTED, testmsg);
		}
		app_control_reply_to_launch_request(reply, app_control, APP_CONTROL_RESULT_SUCCEEDED);

		app_control_destroy(reply);
	}
	return;
}

The message_box_cb() function performs the following: opening the message service, getting the intended number for retrieving message and retrieving message. The function can be written as below:

void message_box_cb(void *data, char *phone_no)
{
	appdata_s *ad = (appdata_s *) data;
	int error_code;

	int count = -1;
messages_create_message(MESSAGES_TYPE_SMS, &ad->msg);
	error_code = messages_open_service(&ad->service_handle);

	/* Get the number of SMS messages */
	error_code = messages_get_message_count(
			ad->service_handle,         /* The service handle */
			MESSAGES_MBOX_ALL,          /* Count messages in all message boxes */
			MESSAGES_TYPE_UNKNOWN,          /* Count only SMS messages */
			&count                      /* The result */
	);
	if (count == 0)  return;
	/* Call the search function */
	error_code = messages_foreach_message(
			ad->service_handle,         /* The service handle */
			MESSAGES_MBOX_ALL,          /* Search in all message boxes */
			MESSAGES_TYPE_SMS,          /* Find SMS messages only */
			NULL,                       /* No filtering by keyword */
			phone_no,                       /* No filtering by address */
			0,                          /* Start at the first found message */
			0,                          /* No limit (returns all found messages) */
			messages_search_callback,   /* Callback called for each found message */
			ad                       /* No additional data for the callback */
	);

}

The message_search_callback() is called when a message of the phone number is found. This callback app retrieves the text of the intended message. It can be written using the following code:

bool messages_search_callback(messages_message_h msg, int index, int result_count, int total_count, char *user_data)
{
	char *text = NULL;
	int error_code = MESSAGES_ERROR_NONE;

	/* Extract message type */
	messages_message_type_e mtype = MESSAGES_TYPE_UNKNOWN;
	error_code = messages_get_message_type(msg, &mtype);

	/* Extract message text */
	error_code = messages_get_text(msg, &text);
	testmsg = replace_all(text, "\n", "
");

	return true;
}

Destroying message handle and closing message service:

After the service app completes its task, the app_terminate() function is used to destroy the message handle and closing the message service that is created in the message_box_cb() function:

void service_app_terminate(void *data)
{
	// Todo: add your code here.

	appdata_s *ad = (appdata_s *) data;
	int error_code;

	cleanup_message(&ad->msg);

	error_code = messages_close_service(ad->service_handle);
	if (error_code != MESSAGES_ERROR_NONE)
		dlog_print(DLOG_ERROR, LOG_TAG, "Failed to close messages service, error: %d", error_code);
	return;
}
void cleanup_message(messages_message_h *msg)
{
	if (msg == NULL)
		return;

	if (*msg == NULL)
		return;

	/* Destroy the previous message handle */
	int error_code = messages_destroy_message(*msg);

	*msg = NULL;
}

 

Demo: Please check the attached sample code to understand how this sample app works. In addition, to test this app, make sure to add the phone number in main.js file of UI App.

Figure1: Stored Messages in Tizen Device

Figure 2: Retrieved Message from Device

List
SDK Version Since: 
2.4 mobile/2.3.1 wearable