уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Одной из многочисленных фич операционной системы Android является использование намерений (Intent). По сути Intent представляет собой механизм описания одной операции, которую необходимо выполнить — выбрать изображение, отправить сообщение в Facebook, отправить письмо и т.д. Многие приложения используют Intent для своей работы. Наиболее часто используемой возможностью Intent является запуск в своем приложении другой активности (например, вызвать из своего приложения Dropbox для сохранения файла). Однако на этом возможности Intent не заканчиваются. Так, используя Intent мы можем:

  • выполнить какое-либо действие
  • запустить сервис
  • отправить уведомление о каком-либо событии.

В Delphi XE5 для работы с намерениями нам потребуется интерфейс JIntent о котором я очень кратко (буквально в пару строк кода) рассказывал в предыдущей статье, посвященной разработке для андроид в Delphi. Сегодня я постараюсь более подробно разобраться с работой механизма намерений и разобрать ещё несколько примеров по его использованию.Намерение (Intent) может быть двух видов — явным и неявным.Если говорить кратко, то в явном намерении мы однозначно (явно) указываем какую активность нам необходимо вызвать для чего указываем намерению необходимый класс. Например, мы можем создать намерение на запуск приложения Twitter (если, конечно. оно установлено на устройстве). Вместе с указанием класса мы также можем указать и необходимый набор данных, которые будут переданы в принимающую активность (например, текст сообщения для Twitter). В случае же использования неявных намерений система Андроид сама определяет перечень активностей, которые могут обработать передаваемые данные. Например, ниже представлен скриншот, на котором показано какие приложения Android выбрал для отправки простого текста:

Screenshot_2014-01-27-20-22-12

На первый взгляд может показаться странным, что Android вдруг выбрал для работы с обычной строкой текста SkyDrive (а выше по списку и Dropbox), но на деле эта строка текста будет сохранена в текстовый файл и отправлена в облако…Но мы сегодня немного не об этом.

Как Android «понимает» какие из доступных нам активностей можно использовать для работы с передаваемыми данными? Ответ заключается в трех возможных параметрах, используемых в намерениях: действие (action), данные (data) и категория (category). Используя только три этих параметра Android и «угадывает», что мы от него хотим. Ну, например, вернемся к рассмотренному ранее примеру — открытие ссылки в браузере:

var
  Intent: JIntent;
begin
  Intent := TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
  Intent.setData(StrToJURI('http://www.google.com'));
  SharedActivity.startActivity(Intent);
end;

Что мы здесь сделали:

  1. Создали новое намерение (Intent)
  2. Указали действие — ACTION_VIEW (показать данные пользователю)
  3. Определили данные — указали URI: http://www.google.com
  4. Выполнили запуск активности

В данных мы указали URI, который описывается следующими атрибутами:

<scheme>://<host>:<port>/<path>

Так как мы указали в URI схему — «http://» , то Android правильно предположил, что мы хотим просмотреть данные ни где-либо, а в браузере. При этом, обратите внимание, браузеров на устройстве может быть сколько угодно много и Android просто даст нам выбрать нужный из списка. Вот так:

Screenshot_2014-01-27-20-47-47

 

Что касается различных действий (action), то вот только некоторые из них:

  1. ACTION_VIEW — просмотр данных
  2. ACTION_SEND — отправка данных
  3. ACTION_SENDTO — отправка сообщений определенному контакту, указанному в URI
  4. ACTION_CALL — инициализировать обращение по телефону
  5. ACTION_WEB_SEARCH — открыть активность для поиска в интернете, основываясь на тексте, переданном с помощью пути URI

Рассмотрим пару примеров по использованию действий.

Пример №1. Позвонить по определенному номеру

var  Intent: JIntent;
  URI: Jnet_Uri;
begin
  Intent:=TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_CALL);
  URI:=TJnet_Uri.JavaClass.parse(StringToJString('tel:+1234567890'));
  Intent.setData(URI);
  SharedActivity.startActivity(Intent);
end;

Здесь мы определяем действие ACTION_CALL и передаем в данных URI, содержащий схему tel: и номер телефона на который необходимо выполнить звонок.

Пример №2. Набрать номер

var  Intent: JIntent;
  URI: Jnet_Uri;
begin
  Intent:=TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_DIAL);
  URI:=TJnet_Uri.JavaClass.parse(StringToJString('tel:+1234567890'));
  Intent.setData(URI);
  SharedActivity.startActivity(Intent);
end;

Если в первом случае мы сразу выполнили звонок на определенный номер, то во втором случае, используя действие ACTION_DIAL мы только набрали этот номер и вывели на экран окно вызова абонента.

Помните, что для выполнения звонком ваше приложение должно обладать следующими разрешением Call Phone, которое можно указать в свойствах проекта «Options -> User Permissions»

Пример №3. Отправить SMS

var  Intent: JIntent;
     URI: Jnet_Uri;
begin
  Intent:=TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
  Intent.setData(StrToJURI('sms:+15105550101,+15105550102?body=hello%20there'));
  SharedActivity.startActivity(Intent);
end;

Здесь мы пробуем вызвать окно отправки сообщения двум адресатам. При этом Android может попросить выбрать вас необходимую активность, например так:

Screenshot_2014-01-27-22-05-11

 

Как можно видеть их представленных выше трех примеров Android фильтрует список возможных для использования активностей в зависимости от двух параметров — действия (action) и данных (дата). Но на этом использование механизма намерений не заканчивается. Следующий момент — это работа с явными намерениями.

Например, как нам вызвать приложение Twitter и передать ему сообщение, которое необходимо отправить? Как минимум нам необходимо выполнить три шага:

  1. Определить, что Twitter установлен
  2. Создать подходящее намерение (Intent)
  3. Запустить активность

Здесь уже становится немного по-сложнее. Для предложенного выше примера (отправка сообщения через Twitter) можно предложить следующий код (исключительно та часть кода, которая непосредственно реализует отправку твита):

const cTwitterPackage = 'com.twitter.android';
var
  Manager: JPackageManager;
  Info: JActivityInfo;
  List: JList;
  I: Integer;
  ResolveInfo: JResolveInfo;
  NativeCompName:JComponentName;
  Intent: JIntent;
begin
  Intent:=TJIntent.Create;
  Intent.setAction(TJIntent.JavaClass.ACTION_SEND);
  Intent.setType(StringToJString('text/plain'));
  Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString('это текст твита для http://webdelphi.ru'));
  Manager :=SharedActivity.getPackageManager;
  List:=Manager.queryIntentActivities(Intent,0);
  for I := 0 to List.size-1 do
    begin
     ResolveInfo:=TJResolveInfo.Wrap((List.get(i)as ILocalObject).GetObjectID);
     Info:=TJActivityInfo.Wrap((ResolveInfo.activityInfo as ILocalObject).GetObjectID);
     if SameText(JStringToString(Info.packageName),cTwitterPackage) then
       begin
         NativeCompName:=TJComponentName.JavaClass.init(ResolveInfo.activityInfo.applicationInfo.packageName,ResolveInfo.activityInfo.name);
         Intent.addCategory(TJIntent.JavaClass.CATEGORY_LAUNCHER);
         Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK or TJIntent.JavaClass.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
         Intent.setComponent(NativeCompName);
         SharedActivity.startActivity(Intent);
       end;
    end;
end;

Здесь мы выполнили следующие действия:

1. Создали новое намерение и указали действие для отправки данных ACTION_SEND
2. Указали Mime-тип данных:

Intent.setType(StringToJString('text/plain'));

3. Указали дополнительные данные для намерения — текст твита:

Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString('это текст твита для http://webdelphi.ru'));

4. Получили менеджер установленных пакетов:

Manager :=SharedActivity.getPackageManager;

Этот менеджер предсталяет нам различную информацию по установленным пакетам, в том числе и имена пакетов.
5. Запросили у менеджера пакетов те список тех активностей, которые могут использоваться для работы с созданным нами намерением:

 List:=Manager.queryIntentActivities(Intent,0);

6. Прошлись по списку в поисках пакета Twitter’а — он имеет названием com.twitter.android.
7. Если пакет был найден, то можно воспользоваться активностью для дальнейшей работы:
7.1. Получили интерфейс ComponentName для Twitter

 NativeCompName:=TJComponentName.JavaClass.init(ResolveInfo.activityInfo.applicationInfo.packageName,ResolveInfo.activityInfo.name);

7.2. Указали категорию намерения:

Intent.addCategory(TJIntent.JavaClass.CATEGORY_LAUNCHER);

которая означает, что активность может быть начальной деятельностью задания из списка приложений в группе Application Launcher устройства.
7.3. Указали необходимые флаги для намерения:

Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK or TJIntent.JavaClass.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

FLAG_ACTIVITY_NEW_TASK — указывает на то, что деятельность станет началом новой задачи
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED — указывает на то, что если активность уже была запущена, то наша задача станет перовой в списке.
7.4. Указали какой компонент активности необходимо использовать

Intent.setComponent(NativeCompName);

7.5. Запустили активность

SharedActivity.startActivity(Intent);

При работе с намерениями стоит помнить о том, что необходимой нам активности может вообще не быть. Например, на устройстве может отсутствовать Twitter, если это планшет, то может отсутствовать модуль для выполнения звонков и т.д. Помочь определить есть ли на устройстве необходимая нам активность может менеджер пакетов, который мы использовали выше. Документацию по менеджеру можно найти на developers.android.com

Как используются намерения в FM Platform

Так как я сразу начал статью с рассмотрения механизма намерений вообще, то у тех, кто не работал с Delphi XE5 могло возникнуть ощущение того, что в FM Platform нет ничего для работы с намерениями и нам придётся всё писать самим с нуля. Это не совсем так. Конечно, реализовать абсолютно все сценарии работы с намерениями практически невозможно, но, тем не менее, в FM Platform в компоненте TActionList уже предусмотрены наиболее часто используемые действия с намерениями, которые могут вам пригодиться:

ShareSheet

 

В качестве отправной точки по изучению работы FM Platform с намерениями в Android можно посоветовать один из готовых примеров,  который вы можете найти в директории

C:\Users\Public\Public Documents\RAD Studio\n.n\Samples\MobileCodeSnippets\ShareSheet

Книжная полка

Описание Подробно рассматривается библиотека FM, позволяющая создавать полнофункциональное программное обеспечение для операционных систем Windows и OS X, а также для смартфонов и планшетных компьютеров, работающих под управлением Android и iOS
купить книгу delphi на ЛитРес
Описание: Рассмотрены практические вопросы по разработке клиент-серверных приложений в среде Delphi 7 и Delphi 2005 с использованием СУБД MS SQL Server 2000, InterBase и Firebird. Приведена информация о теории построения реляционных баз данных и языке SQL. Освещены вопросы эксплуатации и администрирования СУБД.
купить книгу delphi на ЛитРес

 

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
12 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Неъматжон
Неъматжон
28/01/2014 01:18

Спасибо за статью!
Только не понял, чем отличается пример №1 от №2 ? Они похоже до букв….
Или копипасти не правильно работал?

Неъматжон
Неъматжон
28/01/2014 01:31
Ответить на  Vlad

Упс! :) Эт у меня автокоррекция слов сработал. Я ТРИЖДЫ сличал ПО БУКВАМ! Я удивлен этим вывертом мозга.
Спасибо!

LenaIlicheva
LenaIlicheva
28/01/2014 03:24

Замечательно! Спасибо.

anonim
anonim
02/02/2014 18:38

Отличная статья. Очень помогла.
Скажите, а планируется ли статья о том как создавать сервисы?

Satellite
Satellite
15/02/2014 09:52

А как обстоят дела с картинкой? Не подкинете примерчик с намерением intent? :)

Владимир
Владимир
15/03/2014 23:41

Пытаюсь разобраться с написаниям программ под андроид, первое что пришло в голову это программа с заранее заготовленымм текстом и отправка на выбраный номер, не пойму как отправить. На форме есть Button (отправка смс), Edit (для номера) и Memo (для ввода текста которого например нет), после нажатия Button открывается открывается стандартная отправка смс с забитым текстом и номером, а отправка не происходит, как исправить?

Егор
Егор
28/03/2014 20:58

В общем попробовал написать я клиент сайта под андроид на делфе, все отлично получается парсятся ссылки все, что нужно ,но столкнулся с такой проблемой, не получается воспроизвести видео из VK и ему подобных сервисов, вот и с чего у меня вопрос как реализовать воспроизведение видео?=))

trackback

[…] Delphi XE5: использование Intent (намерения) в Android […]

кирилл норкин
02/03/2018 16:16

Скажите пожалуйста, как вызвать стандартный будильник, обыскал все, но натыкаюсь только на инструкции по созданию собственного будильника, но мне хватило бы стандартного с заданным временем