Намерения
- Это механизм для описания одной операции - выбрать фотографию, отправить письмо, сделать звонок, запустить браузер и перейти по указанному адресу.
- В Android-приложениях многие операции работают через намерения.
- Наиболее распространённый сценарий использования намерения - запуск другой активности в своём приложении.
- Также можно использовать для объявления о запуске активности или сервиса, направленных на выполнение каких-либо действий
- или для передачи уведомлений о том, что произошло некое событие (или действие).
Намерения
- Намерения могут применяться для трансляции сообщений по системе.
- Любое приложение способно зарегистрировать широковещательный приёмник и отслеживать эти намерения с возможностью на них реагировать.
- Это позволяет создавать приложения, использующие событийную модель
- Внутренние, системные или сторонние события, передаваемые внешними программами.
- Например об изменениях в состоянии сетевого подключения или в уровне заряда батареи.
Намерения
Intent intent = new Intent(HelloWorld.this, AboutActivity.class);
startActivity(intent);
- В намерении мы явно указали имя класса активности во втором параметре.
- Данный класс у нас прописан в манифесте, и система, просматривая манифест, запустит нужную активность.
- Первый параметр – это Context. Активность является подклассом Context, поэтому мы можем использовать её как HelloWorld.this, или укороченную запись this.
Передача параметров
// У первой активности
ArrayList<File> fileList = new ArrayList<File>();
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("FILES_LIST", fileList);
startActivity(intent);
// У второй активности
ArrayList<File> filelist =
(ArrayList<File>)getIntent().getSerializableExtra("FILES_LIST");
Передача параметров
- При переходе на другую активность мы можем указать какие-то данные
- принимающая активность должна уметь обработать их.
- Для этих целей существуют методы типа putXXX().
- Например, для передачи списка файлов из одной активности в другую.
- При работе с действиями, возвращающими данные, нельзя использовать метод startActivity(), поскольку он не возвращает результат.
- Если вы хотите вернуть данные, то можете использовать метод startActivityForResult(), приспособленный для работы с обратными вызовами.
Неявные намерения
- Существует также неявный вызов активности.
- В этом случае при создании намерения мы используем не имя класса, а указываем параметры action, data, category с определёнными значениями.
- если указали в параметрах адрес веб-страницы, то скорее всего хотим запустить браузер
- Комбинация значений в параметрах определяют цель, которую мы хотим достичь.
- Это может быть открытие ссылки, отправка письма, набор телефонного номера и т.п.
Неявные намерения
- можем прописать в своей активности в фильтрах намерений (Intent Filter) набор тех же параметров: action, data, category.
- тогда у пользователя может запуститься не только стандартный браузер, но и наша программа
- если параметры намерения совпадают с условиями нашего фильтра, то наше приложение (активность) будет вызвано.
- Система сканирует активности всех установленных приложений, и если находится несколько подходящих активностей, то Android предоставляет пользователю выбор, какой именно программой следует воспользоваться.
- Если найдётся только одна подходящая активность, то, естественно, никакого диалога для выбора не будет, и активность запустится автоматически.
Неявные намерения
- Создавая новое неявное намерение для передачи в метод startActivity(), необходимо назначить действие, которое должно выполниться
- также при желании указать вспомогательный путь URI к тем данным, что нужно обработать.
- Можно передать дополнительные данные в другую активность, используя параметр намерения extras.
- При применении этого намерения для запуска активности система во время работы приложения сама найдёт класс компонента, который лучше всего подходит для заданного действия, учитывая указанный тип данных.
- Это значит, что вы можете создавать проекты, используя возможности других приложений и не зная при этом, как они называются и какую функциональность предоставляют.
Проверка наличия приложения
- следует помнить, что нет никакой гарантии, что приложение, способное обработать ваше намерение, будет установлено и доступно на устройстве.
- Например, если приложение установлено на планшете без телефонного модуля.
- Чтобы узнать, будет ли запущена активность для вашего намерения, можно отправить запрос Менеджеру пакетов при помощи метода resolveActivity().
- Желательно делать такую проверку во всех примерах
Неявные намерения. Пример.
Простой пример создания намерения с предопределённым действием ACTION_VIEW для запуска браузера и перехода на нужный адрес:
Uri address = Uri.parse("https://google.com");
Intent openLinkIntent = new Intent(Intent.ACTION_VIEW, address);
if (openLinkIntent.resolveActivity(getPackageManager()) != null) {
startActivity(openlinkIntent);
} else {
Log.d("Intent", "Не получается обработать намерение!");
}
Объект Intent
- содержит информацию, представляющую интерес для компонента, который получает намерение
- Содержит данные, которые передаются этому компоненту
- содержит информацию, представляющую интерес для системы Android:
- имя компонента, который должен обработать намерение и набор параметров запуска этого компонента
Поля объекта Intent
- Имя компонента - имя, который должен обработать намерение.
- Используется объект ComponentName, который является комбинацией полного имени класса целевого компонента (например, "MainActivity")
- и набора имени пакета в файле манифеста приложения, где компонент постоянно находится (например, "com.samples.yourproject")
- Составляющее имя устанавливается методами setComponent(), setClass() или setClassName() и читается методом getComponent()
Поля объекта Intent
- Действие - определяет действие, которое будет выполнено
- Класс Intent содержит множество констант действия
- Название метода определяет ряд параметров и возвращаемое значение.
- можете также определить собственные действия для активизации активности.
- В этом случае вы должны включать имя пакета приложения в качестве префикса, например com.samples.yourproject.CUSTOM_ACTiON.
- Действие в объекте Intent устанавливается в методе setAction() и читается методом getAction()
Поля объекта Intent
- Данные - это URI данных и тип MIME для этих данных. Разные активности соединены с разными видами спецификаций данных.
- Категория - строка, содержащая дополнительную информацию о виде компонента
- В объект Intent можно поместить любое количество описаний категорий.
- Класс Intent определяет несколько констант CATEGORY, например, CATEGORY_BROWSABLE
Поля объекта Intent
- Дополнения - пары ключ-значения для дополнительной информации, которую нужно поставить компоненту, обращающемуся с намерением.
- Например, действие ACTION_TIMEZONE_CHANGED имеет дополнение time-zone, которое идентифицирует новый часовой пояс
- ACTION_HEADSET_PLUG имеет дополнение state, указывающее, включены ли наушники или отключены
- Объект Intent имеет ряд методов put...() для вставки различных типов дополнительных данных и подобного набора методов get...() для чтения данных.
- Дополнения устанавливаются и читаются как объекты Bundle с использованием методов putExtras() и getExtras()
Поля объекта Intent
- Флаги - указывают системе, как запускать активность
- например, какому заданию должна принадлежать активность
- как обработать это после того, как активность запустили
- например, принадлежит ли она списку недавних активностей
- Все флаги определены в классе Intent.
Константы действия
- ACTION_ANSWER — Открывает активность, которая связана с входящими звонками. Это действие обрабатывается стандартным экраном для приёма звонков;
- ACTION_CALL — инициализирует обращение по телефону;
- ACTION_DELETE — Запускает активность, с помощью которой можно удалить данные, указанные в пути URI внутри намерения;
- ACTION_EDIT — Отображает данные для редактирования пользователем
- ACTION_INSERT — Открывает активность для вставки в Курсор (Cursor) нового элемента, указанного с помощью пути URI. Дочерняя активность, вызванная с этим действием, должна вернуть URI, ссылающийся на вставленный элемент
Константы действия
- ACTION_HEADSET_PLUG - Подключение наушников
- ACTION_MAIN — Запускается как начальная активность задания
- ACTION_SEARCH — Запускает активность для выполнения поиска. Поисковый запрос хранится в виде строки в дополнительном параметре намерения по ключу SearchManager.QUERY
- ACTION_SENDTO — Открывает активность для отправки сообщений контакту, указанному в пути URI, который передаётся через намерение
Константы категорий
- CATEGORY_BROWSABLE — активность может быть безопасно вызвана браузером, чтобы отобразить ссылочные данные, например, изображение или почтовое сообщение
- CATEGORY_HOME — активность отображает Home Screen, первый экран, который пользователь видит после включения устройства и загрузки системы, или когда нажимает клавишу HOME
- CATEGORY_LAUNCHER — активность может быть начальной деятельностью задания из списка приложений в группе Application Launcher устройства
Фильтры намерений и запуск заданий
- Если намерение запрашивает выполнение какого-либо действия с определённым набором данных
- то системе нужно уметь выбрать приложение (или компонент) для обслуживания этого запроса.
- На помощь приходят фильтры намерений, которые используются для регистрации активностей, сервисов и широковещательных приёмников в качестве компонентов, способных выполнять заданные действия с конкретным видом данных.
- С помощью этих фильтров также регистрируются широковещательные приёмники, настроенные на трансляцию намерением заданного действия или события.
- В фильтре намерений декларируется только три составляющих объекта Intent: действие, данные, категория.
- Дополнения и флаги не играют никакой роли в принятии решения, какой компонент получает намерение.
Фильтры намерений и запуск заданий
<activity
android:name=".HelloWorldActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"
<category android:name="android.intent.category.LAUNCHER"
</intent-filter>
</activity>
- в любом приложении есть главная активность, которая устанавливается как точка входа для задания
- Фильтр такого вида в элементе <action> помечает активность, как запускаемую по умолчанию.
- Пользователям предоставляется возможность запускать задание и возвращаться к этому заданию в любое время после того, как оно было запущено
Фильтры намерений и запуск заданий
- action - Использует атрибут android:name, чтобы задать название действия, которое будет обслуживаться. Каждый фильтр намерений должен иметь один (и только один) тег action.
- Действия должны быть представлены в виде уникальных строк, которые сами себя описывают.
- Рекомендуется выбирать названия, основываясь на соглашении об именовании пакетов в Java.
- сategory - Использует атрибут android:name, чтобы указать, при каких обстоятельствах должно обслуживаться действие.
- Каждый тег intent-filter способен содержать несколько тегов category.
- можете задать собственные категории или же брать стандартные значения, предоставляемые системой
Категории
- ALTERNATIVE - Наличие данной категории говорит о том, что действие должно быть доступно в качестве альтернативного тому, которое выполняется по умолчанию для элемента этого типа данных. Например, если действие по умолчанию для контакта — просмотр, то в качестве альтернативы его также можно редактировать
- SELECTED_ALTERNATIVE - То же самое, что и ALTERNATIVE, но вместо одиночного действия с использованием утверждения намерения, которое описано выше, применяется в тех случаях, когда нужен список различных возможностей. Одной из функций фильтра намерений может стать динамическое заполнение контекстного меню с помощью действий.
- BROWSABLE - Говорит о том, что действие доступно из браузера. Когда намерение срабатывает в браузере, оно всегда содержит данную категорию. Если вы хотите, чтобы приложение реагировало на действия, инициированные браузером (такие как перехват ссылок на конкретный сайт), то должны добавить в его манифест категорию BROWSABLE.
Категории
- DEFAULT - Установите эту категорию, чтобы сделать компонент обработчиком по умолчанию для действия, выполняемого с указанным типом данных внутри Фильтра намерений. Это необходимо и для Активностей, которые запускаются с помощью явных Намерений
- GADGET - Наличие этой категории указывает на то, что данная активность может запускаться внутри другой активности.
- HOME - Устанавливая эту категорию и не указывая при этом действия, вы создаете альтернативу для стандартного домашнего экрана.
- LAUNCHER - Используя эту категорию, вы помещаете Активность в окно для запуска приложений.
data фильтра
- data - Этот тег дает возможность указать тип данных, с которым может взаимодействовать ваш компонент.
- При необходимости можно задать несколько тегов data.
- Чтобы указать, какие именно данные поддерживает ваш компонент, используйте сочетание следующих атрибутов
- android:host — задаёт доступное имя удалённого сервера (например, google.com);
- android:path — задает доступные значения для пути URI (например, /transport/boats/);
- android:port — указывает доступные порты для заданного сервера;
Принцип работы фильтров намерений
- При использовании метода startActivity() передаваемое неявное намерение, как правило, доходит лишь до одной активности.
- Если для выполнения заданного действия с указанными данными годятся сразу несколько активностей, пользователю предоставляется список выбора.
- Процесс, когда решается, какую активность лучше запустить, называется Утверждением намерений.
- Его цель — найти наиболее подходящий фильтр намерений.
Принцип работы фильтров намерений
- Android собирает список всех доступных Фильтров намерений из установленных пакетов.
- Фильтры, которые не соответствуют действию или категории Намерения, удаляются из списка.
- Совпадение происходит только в том случае, если Фильтр намерений содержит указанное действие (или если действие для него вовсе не задано).
- Совпадения не произойдёт, только если ни одно из действий Фильтра намерений не будет эквивалентно тому, которое задано в Намерении.
- Для категорий процесс соответствия более строгий.
- Фильтр намерений должен включать в себя все категории, заданные в полученном Намерении.
- Фильтр, для которого категории не указаны, может соответствовать только таким же Намерениям (нет категорий).
Принцип работы фильтров намерений
- Наконец, каждая часть пути URI из Намерения сравнивается с тегом data Фильтра намерений.
- Если в Фильтре указаны схема (протокол), сервер/принадлежность, путь или тип MIME, все эти значения проверяются на соответствие пути URI из Намерения.
- При любом несовпадении Фильтр будет удален из списка.
- Если в Фильтре намерений не указано ни одного параметра data, его действие будет распространяться на любые данные.
- Когда вы неявным образом запускаете Активность и вышеописанный процесс возвращает более одного совпадения, пользователю выводится список со всеми вариантами
ACTION_PICK
- рассмотрим более сложное действие, которое возвращает значение после того, как будет активировано.
- ACTION_PICK - это обобщённое название для таких действий.
- Принцип ACTION_PICK заключается в том, чтобы запустить активность, отображающую список элементов.
- После этого активность должна предоставлять пользователю возможность выбора элемента из этого списка.
- Когда пользователь выберет элемент, активность возвратит URI выбранного элемента вызывающей стороне.
ACTION_PICK
// Показываем все программы для запуска
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("*/*");
startActivityForResult(intent, 1);
- диалоговое окно со списком всех возможных программ, которые могут запустить активность с данными, так как мы не указываем конкретный тип (setType("*/*"))
- Если мы укажем конкретный тип данных, которые нас интересует, то список программ существенно сузится. Например, если указать intent.setType("image/*");
- то можем увидеть только системную программу Галерея для просмотра картинок
ACTION_SEND
- Используйте метод setType(), чтобы указать тип MIME для передаваемых данных.
- Эти данные должны храниться в параметре намерения extras с ключами EXTRA_TEXT или EXTRA_STREAM, в зависимости от типа.
- В случае с электронной почтой стандартное приложение в Android также принимает дополнительные параметры по ключам EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC и EXTRA_SUBJECT.
- Если есть установленное приложение с фильтром, который соответствует ACTION_SEND и MIME-типу text/plain, система Android запустит его
- Если ваша активность хочет обрабатывать подобные намерения, то она должна содержать следующие данные:
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
<data android:mimeType="image/*"/>
</intent-filter>
</activity>
Выбор файла
public class PickFileActivity extends Activity {
TextView textView;
private static final int PICKFILE_RESULT_CODE = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonPick = findViewById(R.id.buttonpick);
textView = findViewById(R.id.textView);
buttonPick.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
startActivityForResult(intent,PICKFILE_RESULT_CODE);
}});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode){
case PICKFILE_RESULT_CODE:
if(resultCode == RESULT_OK){
String FilePath = data.getData().getPath();
textView.setText(FilePath);
}
break;
}
}
}