У цьому уроці ми розглянемо менеджер додатків і побачимо, яку інформацію про додаток можна отримати з його допомогою. Також покажемо, як змінити ваш додаток, замінивши використання менеджера пакетів на менеджер додатків.
Менеджер додатків надає інформацію про встановлені і запущені додатки. Він включає в себе набір функцій для отримання таких даних, як: ім’я додатку, абсолютний шлях до загальнодоступної папки додатку і т. д. Для використання функцій і типів даних менеджера додатків, необхідно включити наступні заголовні файли в додаток:
#include <app_manager.h>
Потрібно розрізняти менеджер додатків і менеджер пакетів. Різниця полягає в тому, що декілька додатків може знаходитись в одному пакеті. Тобто пакет – це більша сутність чим додаток. Ви можете створити 3 додатки: ui-додаток, віджет-додаток і сервіс, а потім об’єднати їх в один пакет, який буде завантажуватись в магазин додатків.
Якщо необхідно використовувати функції для отримання інформації про запущені додатки, не використовуючи функції менеджеру додатків, то потрібно включити в проект наступний заголовний файл:
#include <app_context.h>
Найчастіше використовується функція для отримання всіх запущених додатків на пристрої:
int app_manager_foreach_app_context(app_manager_app_context_cb callback, void *user_data);
Перший параметр – це вказівник на обробник вибірки додатків, другий параметр – це вказівник на дані користувача. У разі успішного виконання функція повертає код 0, а в разі помилки – негативне число.
Давайте розглянемо оголошення обробника вибірки додатку.
typedef bool (*app_manager_app_context_cb) (app_context_h app_context, void *user_data);
Перший параметр – це об’єкт для отримання інформації про контекст додатку, другий параметр – це вказівник на дані користувача. Функція повертає логічну змінну: true - продовжити перечислення запущених програм, false – зупинка ітерації. Отримавши вказівник на контекст додатку, розглянемо функції, які використовуються найчастіше для отримання інформації.
Для отримання ідентифікатора додатку. Використовується наступна функція:
int app_context_get_app_id(app_context_h app_context, char **app_id);
Перший параметр – це об’єкт, що містить контекст запущеного додатку, другий параметр – це подвійний вказівник на ідентифікатор додатку, який буде заповнено всередині функції. У разі успішного виконання функція повертає код 0, а в разі помилки – негативне число.
Варто відзначити, що після виклику функції і завершення роботи з рядком, що містить ідентифікатор додатку, необхідно звільняти виділену під неї пам'ять.
Розглянемо цікаву функцію для отримання ідентифікатора процесу додатку.
int app_context_get_pid(app_context_h app_context, pid_t *pid);
Перший параметр - це об’єкт, що містить контекст запущеного додатку, другий параметр – це вказівник на ідентифікатор процесу, який буде заповнено в середині функції. У разі успішного виконання функція повертає код 0, а в разі помилки – негативне число.
Приведемо перелік ще декількох функцій для отримання інформації про запущені додатки.
Щоб отримати інформацію про пакет, якому належить запущений додаток, необхідно викликати наступну функцію:
int app_context_get_package(app_context_h app_context, char **package);
Перший параметр – це об’єкт, що містить контекст запущеного додатку, другий параметр – це подвійний вказівник на ідентифікатор пакету, який буде заповнено всередині функції. У разі успішного виконання функція повертає 0, а в разі помилки – негативне число. Також після завершення роботи з рядком, необхідно звільнити виділену під неї пам'ять
Наступна функція використовується, якщо вам необхідно перевірити чи додаток закінчив свою роботу.
int app_context_is_terminated(app_context_h app_context, bool *terminated);
Перший параметр – це об’єкт, який містить контекст додатку, другий параметр – це вказівник на логічну ознаку завершення роботи додатку, який буде заповнено всередині функції. У разі успішного виконання функція повертає код 0, а вразі посилки – негативне число.
Варто відзначити, що оскільки дана функція використовується протягом роботи додатку, і якщо вказівник на контекст отриманий в обробнику вибірки, то необхідно клонувати його, викликавши наступну функцію:
int app_context_clone(app_context_h *clone, app_context_h app_context);
Перший параметр – це вказівник на об’єкт, у який буде скопійовано контекст запушеного додатку, другий параметр – це об’єкт, який буде скопійовано. Функція повертає 0 у разі успішного виконання і від’ємне число у разі помилки.
Для того аби в запущеному додатку видалити скопійований об’єкт контексту, використайте наступну функцію:
int app_context_destroy(app_context_h app_context);
Функція приймає єдиний параметр – об’єкт, який потрібно видалити. Функція повертає нуль у разі успішного виконання і від’ємне число – у разі помилки.
Аби використовувати функції для отримання інформації про встановлені додатки, не використовуючи при цьому функціонал менеджеру пакетів, потрібно включити в проект наступний заголовний файл:
#include <app_info.h>
Кількість функцій для отримання інформації про встановлені додатки, трохи більша ніж кількість функцій для запущених додатків. Давайте розглянемо основні з цих функцій.
Для вибірки всіх встановлених додатків, використовується наступна функція:
int app_manager_foreach_app_info(app_manager_app_info_cb callback, void *user_data);
Перший параметр – це вказівник на обробник вибірки додатків, другий параметр – вказівник на дані користувача. Розглянемо оголошення обробника вибірки:
typedef bool (*app_manager_app_info_cb) (app_info_h app_info, void *user_data);
Перший параметр – це об’єкт, необхідний для отримання інформації про додаток, другий параметр – це вказівник на дані користувача, які були задані при реєстрації обробника. Функція повертає логічну ознаку: продовжити чи зупинити обробку встановлених додатків.
Тепер наведемо перелік найбільш корисних функцій для отримання інформації про додаток. Оскільки набір параметрів у цих функціях однаковий, то опис параметрів приведемо нижче, після перерахування всіх функцій.
Функція для отримання ідентифікатора додатку:
int app_info_get_app_id(app_info_h app_info, char **app_id);
Функція для отримання назви додатку:
int app_info_get_label(app_info_h app_info, char **label);
Функція для отримання абсолютного шляху до іконки додатку:
int app_info_get_icon(app_info_h app_info, char **path);
Функція для отримання назви пакета, в якому знаходиться додаток:
int app_info_get_package(app_info_h app_info, char **package);
Функція для отримання типу додатку (нативного чи веб):
int app_info_get_type(app_info_h app_info, char **type);
Перший параметр перерахованих функцій – це об’єкт для отримання інформації про додаток, другий параметр – це подвійний вказівник на рядок, який буде заповнено всередині функції. Потрібно не забувати видаляти виділені рядки.
Тепер перерахуємо функції, які носять логічний характер інформації про додаток.
Функція для перевірки чи має додаток графічний інтерфейс:
int app_info_is_nodisplay(app_info_h app_info, bool *nodisplay);
Функція для перевірки чи є додаток попередньо встановленим:
int app_info_is_preload(app_info_h app_info, bool *preload);
Перший параметр перерахованих функцій – це вказівник на структуру про додаток, другий параметр – це вказівник на логічну змінну.
Перейдемо до практики. Додайте вищеперераховані функції у ваш додаток і результат їх роботи виведіть у вікно логування.
Додайте в проект заголовний файл для використання функцій і типів даних менеджеру додатків.
#include <app_manager.h>
Замість створеної у минулому уроку package_manager_foreach_package_info(), додайте функцію для реєстрації обробника вибірки запущених додатків.
static bool
_app_create_cb(void *data)
{
...
app_manager_foreach_app_context(_app_manager_app_context_cb, NULL);
...
}
Реалізуйте сам обробник вибірки запущених додатків. Всередині нього викличте функції для отримання індикатора додатку і індикатора процесу.
static bool
_app_manager_app_context_cb(app_context_h app_context, void *user_data)
{
char *app_id = NULL;
pid_t pid;
app_context_get_app_id(app_context, &app_id);
app_context_get_pid(app_context, &pid);
dlog_print(DLOG_INFO, "lesson26", "ID додатку: %s", app_id);
dlog_print(DLOG_INFO, "lesson26", "ID процесу: %d", pid);
free(app_id);
return true;
}
Запустіть додаток і відкрийте вікно логування. Там ви можете побачити список ідентифікаторів запущених додатків та ідентифікатори процесу.
Тепер додайте у ваш проект, розглянуті вище функції для отримання інформації про додатки.
Видаліть всі пов’язані з менеджером пакетів функції і обробники, що було додано в минулому уроку, а також функції пов’язані з запущеним додатком, які було вказано вище. Тепер додайте інформацію лише про встановлені додатки.
Змініть назву вашої структури, яка містить інформацію про додаток і додайте в неї поле, що містить ідентифікатор додатку. Цей ідентифікатор вам знадобиться в наступному уроку.
Також в цій структурі необхідно видалити поле: char *version, яке містить версію пакету, а також у функції _app_terminate_cb() видаліть звільнення пам’яті для даного поля, оскільки воно більше не існує.
typedef struct _Application_Info {
char *label;
char *path_icon;
char *app_id;
} Application_Info;
Аби додаток компілювався без проблем, необхідно у всьому проекті замінити назву структури Install_Package_Info на Application_Info.
Тепер замість функції вибірки запущений додатків, викличте функцію для реєстрації вибірки встановлених додатків.
static bool
_app_create_cb(void *data)
{
...
app_manager_foreach_app_info(_app_manager_app_info_cb, ui);
...
}
Аби уникнути попередження від компілятора, що є функції, які не використовуються, видаліть попередній обробник _app_manager_app_context_cb().
Тепер реалізуємо обробник вибірки додатків. Всередині обробника виведіть у логування: ім’я та індикатор додатку, абсолютний шлях до іконки та ідентифікатор пакету. Але при цьому, додайте у ваш список лише ті додатки, у яких є графічний інтерфейс користувача (ui-додатки).
static bool
_app_manager_app_info_cb(app_info_h app_info, void *user_data)
{
UIData *ui = user_data;
Application_Info *application_info = calloc(1, sizeof(Application_Info));
if (!application_info) return false;
memset(application_info, 0x0, sizeof(Application_Info));
app_info_get_app_id(app_info, &(application_info->app_id));
app_info_get_label(app_info, &(application_info->label));
app_info_get_icon(app_info, &(application_info->path_icon));
bool is_nodisplay = false;
app_info_is_nodisplay(app_info, &is_nodisplay);
if (!is_nodisplay)
ui->list_package = eina_list_append(ui->list_package, application_info);
char *str_app_info = NULL;
app_info_get_type(app_info, &str_app_info);
dlog_print(DLOG_INFO, "lesson26", "Тип додатку: %s", str_app_info);
free(str_app_info);
str_app_info = NULL;
app_info_get_package(app_info, &str_app_info);
dlog_print(DLOG_INFO, "lesson26", "ID пакету: %s", str_app_info);
free(str_app_info);
dlog_print(DLOG_INFO, "lesson26", "Назва: %s", application_info->label);
dlog_print(DLOG_INFO, "lesson26", "Шлях до іконки: %s", application_info->path_icon);
dlog_print(DLOG_INFO, "lesson26", "ID додатку: %s", application_info->app_id);
return true;
}
І останнє, що вам необхідно зробити для успішного запуску додатку – у функції створення rotary selector, видалити виклик функції для встановлення рядку, що встановлений в елемент як додатковий текст, який містить версію додатку. Видаліть наступний виклик:
eext_rotary_selector_item_part_text_set(item,
"selector,sub_text",
install_package_info->version);
Запустіть додаток. На пристрої Samsung Gear
Як ви можете бачити, в якості елементів віджету відображаються встановлені додатки, що мають графічний інтерфейс, а якщо ви відкриєте вікно логування, то побачите великий список всіх встановлених додатків і інформації про них. Розглянемо перелік найбільш корисних функцій менеджера додатків, на які варто звернути увагу. Наступна функція необхідна для отримання ідентифікатора додатку, використовуючи ідентифікатор запущеного процесу: Перший параметр – це ідентифікатор процесу (може бути отриманий двома шляхами: або з допомогою функції з використанням контексту запущеного додатку, або з використанням виклику системної функції), другий параметр – це подвійний вказівник на рядок, який містить ідентифікатор додатку, який потрібно не забувати видаляти. У разі успішного виконання функція повертає нуль, а в разі помилки – негативне число. Для отримання абсолютного шляху до піддиректорій загальнодоступної директорії додатку, розглянемо декілька функцій. Функція для отримання абсолютного шляху до загальнодоступної директорії з даними (shared/data) вашого проекту: Функція для отримання абсолютного шляху до загальнодоступної директорії з ресурсами (shared/res) вашого проекту: Функція для отримання абсолютного шляху до загальнодоступної довіреної директорії (shared/trusted) вашого проекту: Перший параметр – це вказівник на рядок, що містить ідентифікатор додатку, другий параметр – це подвійний вказівник на абсолютний шлях до запитуваної директорії, тому необхідно буде звільнити пам'ять, що була виділена на цей рядок. У разі успішного виконання функція повертає нуль, а в разі помилки – негативне число. Для того аби перевірити чи цей додаток запущений, маючи його ідентифікатор, необхідно викликати наступну функцію: Перший параметр – це вказівник на ідентифікатор додатку, другий – це вказівник на логічну змінну, що містить статус додатку. У разі успішного виконання функція повертає нуль, у разі помилки – негативне число. Нижче наведені інші важливі функції. Функція відновлення додатку: Вхідний параметр цієї функції – це об’єкт, що містить контекст запущеного додатку. У разі успішного виконання функція повертає нуль, а в разі помилки – негативне число. Функція для відкриття додатку по вказаному індикатору: Вхідний параметр – це вказівник на рядок, який містить унікальний ідентифікатор додатку. У разі вдалого виконання функція повертає нуль, а вразі помилки – негативне число. Повний початковий код уроку ви можете скачати тут WearLesson026.int app_manager_get_app_id(pid_t pid, char **app_id);
int app_manager_get_shared_data_path(const char *app_id, char **path);
int app_manager_get_shared_resource_path(const char *app_id, char **path);
int app_manager_get_shared_trusted_path(const char *app_id, char **path);
int app_manager_is_running(const char *app_id, bool *running);
int app_manager_resume_app(app_context_h app_context);
int app_manager_open_app(const char *app_id);