URL handling on Tizen devices works through application controls.
You'll need to use implicit-launch application controls. Rather than specifiying the exact application ID you wish to call (as in an explicit-launch application control), you need to specify:
"file"
or "data"
)When Tizen tries to match an implicit-launch application control with an app to launch, it looks for apps that declare matching application control handlers. A handler matches a control if it meets the following conditions:
Registering a control handler, implementing a control handler, and launching a control all use different interfaces on web apps and native apps.
To register an app as a handler for a URL scheme, you need to add an application control handler to that app's config.xml file. To handle the grid6.us
scheme in the Grid6 app, we could add the following application control description to config.xml:
<tizen:app-control> <src name="main.html"/> <operation name="http://tizen.org/appcontrol/operation/view"/> <uri name="grid6.us"/> </tizen:app-control>
What are these tags?
src
operation
uri
uri
tag is optional in tizen:app-control
, but must be specified to register a URL scheme.mime
mime
tag is optional in tizen:app-control
, and should not be listed to catch custom URL schemes.When Tizen matches an application control with a web app's app-control description, Tizen launches the src
page given in that description. The page is launched in a web view as normal, but with the app control accessible in its namespace.
For that page to handle the URL input, then, the page must call getRequestedAppControl()
to retrieve the app control; from there, the control's operation ID and URL are accessible:
var rac = getRequestedAppControl(); var operation_id = rac.appControl.operation; var url = rac.appControl.uri; if(typeof url !== "undefined" && url !== null) { var last_segment = url.substr(url.lastIndexOf('/') + 1); if (last_segment != "") { // Handle url ... } }
If defined, url
is a DOM string, and can be manipulated as any other string. So, your app can parse it as a URL, pull out the arguments it needs, and handle those arguments.
To launch an app by its URL scheme, create a new ApplicationControl object, and launch it with launchAppControl
. To launch our Grid6 app with a specific state:
var appControl = new tizen.ApplicationControl( "http://tizen.org/appcontrol/operation/view", "grid6.us:/acaryaaa", null, /* MIME type */ null, /* Category */ [] /* extra args */ ); launchAppControl(appControl,...);
To register a native app as a handler for a specific URL, you need to add an application control handler to the native app's manifest.xml file. For our Grid6 example, the following XML inside our <UIApp>
tag suffices:
<AppControls> <AppControl> <Uri>grid6.us</Uri> <Operation> http://tizen.org/appcontrol/operation/view </Operation> </AppControl> </AppControls>
As above, the <Operation>
tag denotes the Tizen "view" operation, which will be launched to handle URLs, and the <Uri>
tag denotes the URL scheme that this app will catch. The same entry should work, whether it's inside a ServiceApp description or a UIApp description.
If you're working within the Tizen IDE, you can add an AppControl entry by opening your project's manifest.xml
in the IDE. From there, select the "Application Control" tab, add a new application control, and add Operation and Uri attributes through that interface. You can check that the resulting XML looks correct in the "manifest.xml"
tab of the editor.
When Tizen matches an application control with a native app, Tizen attempts to launch the corresponding event handler in the app. So, to handle a URL in a native app, have your top-level app inherit from the IAppControlProviderEventListener interface, and override its OnAppControlRequestReceived()
method. The control's operation and URL are passed as parameters to this method. For the Grid6 example, we could do this as follows:
// In the App's header: // ==================== namespace App = Tizen::App; namespace Base = Tizen::Base; class Grid6App: public App::UIApp, public App::IAppControlProviderEventListener { // Declare override. void OnAppControlRequestReceived( Base::RequestId reqId, const Base::String & operationId, const Base::String * uri, const Base::String * mimeType, const Base::Collection::IMap * extraData ); // [...] } // And then, in the implementation... // =================================== void Grid6App::OnAppControlRequestReceived ( Base::RequestId reqId, const Base::String & operationId, const Base::String * uri, const Base::String * mimeType, const Base::Collection::IMap * extraData ) { if(uri && operationId == "http://tizen.org/appcontrol/operation/view") { // Extract last piece of path from URL. int slash_loc; Base::result err_code = uri.LastIndexOf('/', slash_loc, uri.GetLength()-1); if (err_code == E_SUCCESS) { Base::String path; uri.SubString(slash_loc+1, path); // decode path, set state, display state... // [...] } } }
Tizen's AppControl mechanism provides multiple ways to launch other apps. The simplest is the static AppControl::FindAndStart
method:
unsigned long App::AppControl::FindAndStart ( const Base::String & operationId, const Base::String * pUriPattern, const Base::String * pDataType, const Base::String * pCategory, const Base::Collection::IMap * pExtraData, const App::IAppControlResponseListener * pListener )
Here, operationId
must be provided, but the other arguments are optional. For calling URLs, and ignoring return values, we only care about operationId
and pUriPattern
. Thus, we could open a particular Grid6 pattern with:
res = Tizen::App::AppControl::FindAndStart ( "http://tizen.org/appcontrol/operation/view", "grid6.us:/xyzzy005", NULL, NULL, NULL, NULL );