Account Manager: Managing Account Information on the Device
This tutorial demonstrates how you can create, delete, and update accounts in the account database, and manage account information, such as user name, display name, domain name, and email address.
Warm-up
Become familiar with the Account Manager API basics by learning about:
-
Initializing the Accounts
Initialize the account manager for use.
-
Creating and Managing an Account
Create an account, set its properties, and insert it to the database.
- Information retrieval
-
Getting Account Information
Retrieve information for each existing account and implement a callback function.
-
Retrieving Accounts by Package Name
Retrieve accounts based on a specific package.
-
Retrieving Account Providers by Capability
Retrieve account providers based on a specific capability.
-
Getting Account Information
-
Removing an Account
Remove an account from the database.
-
Destroying the Account Handle
Destroy the account handle.
-
Adding an Application on the Account Screen
Display your application on the Add account screen of a Tizen device.
Follow-up
Once we have learned the basics of the Account Manager API, we can now move on to more advanced tasks, including:
-
Performing Database Queries
Manage accounts and query them based on various attributes.
-
Managing Account Secrecy
Manage account secrecy levels.
-
Updating Accounts
Update account details.
-
Retrieving Account Types
Retrieve account types.
Initializing the Accounts
To initialize the account manager:
-
To use the functions and data types of the Account Manager API (in mobile and wearable applications), include the <account.h> header file in your application:
#include <account.h>
To ensure that an Account Manager function has been executed properly, make sure that the return is equal to ACCOUNT_ERROR_NONE.
-
Declare the necessary global variables:
#include <stdio.h> #include <time.h> #include <dlog.h> // Account handle static account_h account = NULL; static int account_id = 0; int ret = 0;
-
Add the required privileges to the manifest file of your application:
- http://tizen.org/privilege/account.read: to use APIs for reading account data from the account database
- http://tizen.org/privilege/account.write: to use APIs for writing account data to the account database
Creating and Managing an Account
To create an account, set its properties, and add it to the account database:
- Create an account using the account_create() function and the previously defined account handle:
ret = account_create(&account);
- When the account is created, you can set account properties, such as name, display name, domain name, and email address:
char* account_name = "Marcus"; char* display_name = "Marcus_display"; char* domain_name = "Marcus_domain"; char* email_address = "marcus@example.com"; char* image_path = "image_path"; ret = account_set_user_name(account, account_name); ret = account_set_display_name(account, display_name); ret = account_set_domain_name(account, domain_name); ret = account_set_email_address(account, email_address); ret = account_set_icon_path(account, image_path);
- When the account is configured, use the account_insert_to_db() function to insert the account to the account database. Use the account ID as the second parameter (account_id):
ret = account_insert_to_db(account, &account_id);
Getting Account Information
To get account information, such as user name, display name, domain name, and email address:
- Use the account_get_total_count_from_db() function to get the total number of inserted records.
To get individual records, use the account_foreach_account_from_db() function, which iterates through all the records and invokes a callback function for each account.
int total_count = -1; ret = account_get_total_count_from_db(&total_count); ret = account_foreach_account_from_db(on_account_read, NULL);
- Define the callback function for the account_foreach_account_from_db() function to retrieve information for each account.
To get more details, use the account_get_account_id(), account_get_user_name(), account_get_display_name(), and account_get_icon_path() functions:
static bool on_account_read(account_h account, void *user_data) { char *name = NULL; char *display_name = NULL; char *icon_path = NULL; // Get the account ID ret = account_get_account_id(account, &account_id); if (ret != ACCOUNT_ERROR_NONE) { // Error handling return false; } // Get the user name ret = account_get_user_name(account, &name); if (ret != ACCOUNT_ERROR_NONE) { // Error handling return false; } dlog_print(DLOG_INFO, LOG_TAG, "name: %s", name); // Get the display name ret = account_get_display_name(account, &display_name); if (ret != ACCOUNT_ERROR_NONE) { // Error handling return false; } dlog_print(DLOG_INFO, LOG_TAG, "display_name: %s", display_name); // Get the icon path ret = account_get_icon_path(account, &icon_path); if (ret != ACCOUNT_ERROR_NONE) { // Error handling return false; } dlog_print(DLOG_INFO, LOG_TAG, "icon_path: %s", icon_path); free(name); free(display_name); free(icon_path); return true; }
Retrieving Accounts by Package Name
To retrieve accounts by a specific account provider:
- Define the account_cb() callback for getting account data:
static bool account_callback(account_h account, void* user_data) // account_cb() callback { // Called once for each account in the database }
- Retrieve the accounts of a specific account provider using the account_query_account_by_package_name() function, and specifying the callback for getting account data and the package name of the account provider:
int ret = -1; char* package_name = "package_name"; ret = account_query_account_by_package_name(account_callback, package_name, NULL);
Retrieving Account Providers by Capability
To retrieve account providers by a specific capability:
- Define the account_type_cb() callback for getting account providers:
static bool account_type_callback(account_type_h account_type, void* user_data) // account_type_cb() callback { // Called once for each account type in the database }
- Retrieve the account providers of a specific capability by using the account_type_query_by_provider_feature() function, and specifying the callback for getting account providers:
int ret = -1; char* capability = "http://tizen.org/account/capability/contact"; ret = account_type_create(&account_type); account_type_query_by_provider_feature(account_type_callback, capability, NULL);
Removing an Account
To remove an account, use the account_delete_from_db_by_id(), account_delete_from_db_by_user_name(), or account_delete_from_db_by_package_name() function. They all remove a given account record.
Note |
---|
To get the ID needed as a parameter of the account_delete_from_db_by_id() function, use the account_get_account_id() function. |
ret = account_delete_from_db_by_id(account_id);
Destroying the Account Handle
To destroy the account handle, use the account_destroy() function:
ret = account_destroy(account);
Adding an Application on the Account Screen
To add your application on the Add account screen of the device:
- Add the required information in the manifest file:
<account> <account-provider appid="app-id name" providerid="url style string" multiple-accounts-support="true or false"> <icon section="account">application icon name</icon> <icon section="account-small">application small icon name</icon> <label>Application name</label> <label xml:lang="en-gb">Application name</label> <label xml:lang="ko-kr">ߖȃخʼnL݇ Lا</label> <capability>http://tizen.org/account/capability/contact</capability> <capability>http://tizen.org/account/capability/calendar</capability> </account-provider> </account>
The required information includes:
-
appid="app-id name"
Application ID (for example, appid="org.tizen.account").
-
providerid="url style string"
Provider identification string (for example, providerid="http://www.tizen.org").
-
multiple-accounts-support="true or false"
Multiple account support (if your application can manage 2 or more accounts, set to true; otherwise set to false)
-
<icon section="account">application icon name</icon>
Icon displayed on the Add account screen.
The icon size must be 72 x 72 px and the icon file must be in the {app-root}\shared\res\ directory.
-
<icon section="account-small">application small icon name</icon>
Small icon displayed on the Other application screen to represent the account provider.
The small icon file must be in the {app-root}\shared\res\ directory.
-
<label xml:lang="en-gb">Application name</label>
Application name displayed on the Add account screen, according to the selected language.
An account provider must have at least one label tag.
-
<capability>http://tizen.org/account/capability/contact</capability>
For more information, see the Account Manager guide.
-
appid="app-id name"
- Create the sign-in screen UI.
When the user selects your application on the Add account screen, the Account Service launches your application with a specific operation ID (ACCOUNT_OPERATION_SIGNIN) defined in the account-types.h header file, so the sign-in screen must be displayed.
Note |
---|
For more information on operations and events, see the Account Manager guide. |
Performing Database Queries
To perform database queries:
- Prepare sample content.
To perform queries, you need existing content in the database. To access the existing account, obtain it from the database. This can be done using a few functions, depending on the user requirements.
To create new content to the database:
-
The Create_Account() function creates a new account from a given account_h handle and account details (name, display name, domain, email). 3 capabilities are added to the account to demonstrate some of the query functions. The capabilities as well as user custom types can be predefined.
After the account is created, it is added to the database. When no longer needed, destroy the account handle using the account_destroy(account) function.
int id[3]; static account_h account = NULL; Create_Account(&account, "Person", "DiplayPerson", "Person Domain", "someone1@somewho.com"); account_set_capability(account, "Custom", ACCOUNT_CAPABILITY_ENABLED); account_set_capability(account, "Next", ACCOUNT_CAPABILITY_ENABLED); account_set_capability(account, "Another", ACCOUNT_CAPABILITY_DISABLED); account_insert_to_db(account, &id[0]); account_destroy(account);
-
Add 3 more accounts to the database:
Create_Account(&account, "PersonX", "DisplayX", "Other Domain", "someone2@somewho.com"); account_insert_to_db(account, &id[1]); account_destroy(account); Create_Account(&account, "Human", "Humanity", "Everyone", "someone3@somewho.com"); account_insert_to_db(account, &id[2]); account_destroy(account); Create_Account(&account, "LastOne", "LastDisplay", "Last Domain", "someone4@somewho.com"); account_insert_to_db(account, &id[3]); account_destroy(account);
-
Create an account.
static int Create_Account(account_h * account, char * account_name, char * display_name, char * domain_name, char * email_address) { account_create(account); account_set_user_name(*account, account_name); account_set_display_name(*account, display_name); account_set_domain_name(*account, domain_name); account_set_email_address(*account, email_address); }
-
- List the accounts:
-
List all accounts to verify the database insertion:
struct Account_Records { int count; int tab[100]; }; struct Account_Records rec; List_Accounts(&rec);
-
If the account list is not empty (NULL), the List_Accounts() function counts all records in the database. Obtain the records using the account_foreach_account_from_db() function.
static void List_Accounts(struct Account_Records* rec) { if (rec != NULL) { rec->count = 0; } account_foreach_account_from_db(on_account_read, rec); }
-
Call the on_account_read() callback function for each found record. If the second parameter (user_data) is not NULL, the function is counting the existing accounts. String data returned by the account_get_xxx() functions must be released with the free() function. Data prepared with the sprintf() function can, for example, be sent to stdout.
static bool on_account_read(account_h account, void *user_data) { int account_id = 0; char *name = NULL; char *display_name = NULL; struct Account_Records * rec = (struct Account_Records *)user_data; char buf[100]; account_get_account_id(account, &account_id); sprintf(buf, "MyCallback ID: %d\n", account_id); if (user_data != NULL) { rec->tab[rec->count++] = account_id; } account_get_user_name(account, &name); sprintf(buf, "MyCallback Name: %s\n", name); free(name); account_get_display_name(account, &display_name); sprintf(buf, "MyCallback Disp.: %s\n", display_name); free(display_name); return 0; }
-
- Query the account by its ID with the account_query_account_by_account_id() function. This function requires an existing handle to an account as an input parameter.
for (i = 0; i < rec.count; i++) { account_create(&account); account_query_account_by_account_id(rec.tab[i], &account); Show_Account(account); account_destroy(account); }
- Show the account:
static int Show_Account(account_h acc) { int account_id = 0; char *name = NULL; char *display_name = NULL; char buf[100]; account_get_account_id(acc, &account_id); sprintf(buf, "Show_Account ID: %d\n", account_id); account_get_user_name(acc, &name); sprintf(buf, "Show_Account Name: %s\n", name); free(name); account_get_display_name(acc, &display_name); sprintf(buf, "Show_Account Disp.: %s\n", display_name); free(display_name); return 0; }
- Query the account by various attributes:
- Query by user name.
Querying data by user name requires a valid user name and callback function. In this example, the same callback is used as in the account_foreach_account_from_db() function, but it is cast without the third parameter (user data).
account_query_account_by_user_name(on_account_read, "Human", NULL);
- Query by package name.
By default, the accounts created in the application context have a package name set to the application name. Change it using the account_set_package_name() function. To list accounts by package name, the user can provide a name by themselves or obtain it with the account_get_package_name() function.
The account_query_account_by_package_name() function requires a callback function and a package name. In addition, the user data can be passed to the callback function as a third parameter.
The package name has to be released when no longer needed.
char * package_name; account_get_package_name(account, &package_name); account_query_account_by_package_name(on_account_read, package_name, NULL); free(package_name);
- Query by capability.
The following function allows the user to find all accounts with a specified capability on a specified state. Once again, the callback function is required.
account_query_account_by_capability(on_account_read, "Custom", ACCOUNT_CAPABILITY_ENABLED, NULL);
- Query by capability type.
This function is similar to the account_query_account_by_capability() function, but returns all accounts with a specified capability, without checking their state.
account_query_account_by_capability_type(on_account_read, "Next", NULL);
- Query capability by account ID.
The account_query_capability_by_account_id() function is different from the previous functions. It lists all capabilities from an account with a specified ID, and requires a different type of callback. The callback function prepares data to be sent to an output.
account_query_capability_by_account_id(_capability_cb, id[0], NULL); static bool _capability_cb(const char *capability_type, account_capability_state_e capability_state, void *user_data) { char buf[200]; sprintf(buf, "Found capability: %s on state %d\n", capability_type, capability_state); return true; }
- Query by user name.
- Destroy all account handles when they are no longer needed:
account_destroy(account);
Managing Account Secrecy
To manage account secrecy:
- Select the secrecy level using the account_secrecy_state_e enumeration (in mobile and wearable applications):
static account_h account = NULL; account_secrecy_state_e secret; char buf[200]; int ret; int id; // Account 1 Create_Account(&account, "Security 1", "Invalid", "NOBODY", "anony@mous.not"); account_set_secret(account, ACCOUNT_SECRECY_INVALID); account_get_secret(account, &secret); account_insert_to_db(account, &id); sprintf(buf, "Account 1 secret: %d\n", secret); account_destroy(account); // Account 2 Create_Account(&account, "Security 2", "Invisible", " NOBODY", "anony1@mous.not"); account_set_secret(account, ACCOUNT_SECRECY_INVISIBLE); account_get_secret(account, &secret); account_insert_to_db(account, &id); sprintf(buf, "Account 2 secret: %d\n", secret); account_destroy(account); // Account 3 Create_Account(&account, "Secret 3", "Visible", " NOBODY", "anony2@mous.not"); ret = account_set_secret(account, ACCOUNT_SECRECY_VISIBLE); ret = account_get_secret(account, &secret); ret = account_insert_to_db(account, &id); sprintf(buf, "Account 3 secret: %d\n", secret); account_destroy(account); List_Accounts(NULL);
Secrecy is only linked with the visibility on the account settings screen. The account is still visible and can be accessed using a query or a foreach function. For further information on how to add your application to the account screen, see Adding an Application on the Account Screen.
// List_Account() console output MyCallback ID: 12 MyCallback Name: Security 1 MyCallback Disp.: Invalid ------------------- MyCallback ID: 13 MyCallback Name: Security 2 MyCallback Disp.: Invisible ------------------- MyCallback ID: 14 MyCallback Name: Secret 3 MyCallback Disp.: Visible
- Destroy all account handles when they are no longer needed:
account_destroy(account);
Updating Accounts
To update and track account data:
- Subscribe notifications to track account changes. Create an account_subscribe_h instance and register a notification.
account_subscribe_h account_subscribe; account_subscribe_create(&account_subscribe); account_subscribe_notification(account_subscribe, _account_event_cb, NULL);
- Create an account. Accounts are created and then their handles are destroyed. The package name is obtained from the second account.
Create_Account(&account, "Updater", "Updated?", "ToUpdate", "not.up@to.date"); account_insert_to_db(account, &id); Show_Account(account); account_destroy(account); Create_Account(&account, "Another", "Updated?", "ToUpdate", "not.up@to.date"); account_insert_to_db(account, &id); account_get_package_name(account, &package_name); sprintf(buf, "Package_name: %s\n", package_name); Show_Account(account); account_destroy(account);
- Update the account:
-
To update an account by its ID:
- Create a handle to the account.
- Get the account from the database (by ID).
- Make the necessary changes.
- Update the account using the account handle and a valid ID.
- Destroy the account handle.
account_create(&account); account_query_account_by_account_id(id, &account); account_set_display_name(account, "Updated!"); account_update_to_db_by_id(account, id); account_destroy(account);
- To update an account by its user name:
- Create a handle to the account.
- Get the account from the database (by ID).
- Make the necessary changes.
- Update the account using the account handle, a valid user name, and a package name. There can be accounts with the same user names in different packages.
- Destroy the account handle.
account_create(&account); account_query_account_by_account_id(id, &account); account_set_display_name(account, "Updated!"); account_update_to_db_by_user_name(account, "Another", package_name); account_destroy(account);
-
- Create the account event callback. When any action is taking place on any account when a notification is subscribed, a callback function is invoked. The callback function provides in its parameters the event type as a string, the ID of the account associated with the actual change, and, additionally, the user data registered while subscribing the notification.
bool _account_event_cb(const char *event_type, int account_id, void *user_data) { char buf[200]; sprintf(buf, "ACCOUNT EVENT: %s, %d\n", event_type, account_id); return true; }
- Show the accounts to verify the updates:
account_create(&account); account_query_account_by_account_id(id, &account); Show_Account(account); account_destroy(account);
- Unsubscribe the notification when no longer needed:
account_unsubscribe_notification(account_subscribe);
Retrieving Account Types
To retrieve account types:
- Create a handle to operate on the account type:
account_type_h account_type; account_type_create(&account_type);
- Get the type information.
If the account type with a specified ID exists, you can get it from the database with the account_query_by_app_id() function.
It is possible to set, for example:
- ID
- Labels
- Features
- Multiple account support (this is only a flag)
To get the account types by the application ID, use the account_type_query_by_app_id() function:
int multiple_account_support = -1; char *your_app_id = "com.tizen.example"; // App ID for retrieving account types char *app_id = NULL; char *provider_feature = NULL; char *icon_path = NULL; if (account_type_query_app_id_exist(your_app_id)) { account_type_query_by_app_id(your_app_id, &account_type); account_type_get_app_id(account_type, &app_id); account_type_get_multiple_account_support(account_type, &multiple_account_support); account_type_get_icon_path(account_type, &icon_path); account_type_get_provider_feature(account_type, &provider_feature); }
- List the account types or all the labels from a specified type with a proper callback function:
account_type_foreach_account_type_from_db(_account_type_cb, NULL); account_type_query_label_by_app_id(_account_label_cb, type_id, NULL);
While listing the labels, the user has access to the ID of the account type, label and its local value, and the user data passed while casting the query function.
bool _account_label_cb(char *app_id, char *label, char *locale, void *user_data) { char buf[200]; sprintf(buf, "Get Label ID: %s LABEL: %s LOCALE %s\n", app_id, label, locale); return true; }
The account type callback has access to the account type and user data.
bool _account_type_cb(account_type_h account_type, void *user_data) { char * id; int support; char buf[200]; account_type_get_app_id(account_type, &id); account_type_get_multiple_account_support(account_type, &support); sprintf(buf, "Account Type ID: %s Multiple support %d:\n", id, support); return true; }
- Clean up and destroy the allocated handles:
free(app_id); free(provider_feature); free(icon_path); account_type_destroy(account_type);