1page.title=Направление пользователя в другое приложение
2page.tags=объекты Intent
3helpoutsWidget=true
4
5trainingnavtop=true
6
7@jd:body
8
9
10<div id="tb-wrapper">
11  <div id="tb">
12
13<h2>Содержание этого урока</h2>
14<ol>
15  <li><a href="#Build">Создание явного объекта Intent</a></li>
16  <li><a href="#Verify">Проверка наличия приложения для получения объекта Intent</a></li>
17  <li><a href="#StartActivity">Запуск операции с объектом Intent</a></li>
18  <li><a href="#AppChooser">Отображение блока выбора приложения</a></li>
19</ol>
20
21<h2>См. также:</h2>
22<ul>
23    <li><a href="{@docRoot}training/sharing/index.html">Общий доступ к простым данным</a></li>
24</ul>
25
26  </div>
27</div>
28
29<p>Одна из наиболее важных возможностей системы Android – способность приложений направлять пользователя в другое приложение
30в зависимости от желаемого действия. Например, если
31ваше приложение содержит адрес компании, который нужно показать на карте, вам не нужно встраивать в приложение операцию
32вывода карты. Вместо этого можно создать запрос на просмотр адреса
33с помощью {@link android.content.Intent}. В этом случае система Android запускает приложение,
34которое показывает адрес на карте.</p>
35
36<p>Как объяснялось в первом уроке <a href="{@docRoot}training/basics/firstapp/index.html">Создание
37первого приложения</a>, объекты Intent нужно использовать для навигации между операциями в собственном приложении. Обычно
38для этого используются <em>явные объекты Intent</em>, определяющие точное имя класса
39компонента, который вы хотите запустить. Однако если вы хотите, чтобы действие (например
40просмотр карты) выполнялось отдельным приложением, следует использовать <em>неявный объект Intent</em>.</p>
41
42<p>На этом уроке вы узнаете, как создать неявный объект Intent для определенного действия и использовать его
43для запуска операции, выполняющей действие в другом приложении.</p>
44
45
46
47<h2 id="Build">Создание неявного объекта Intent</h2>
48
49<p>Неявные объекты Intent не декларируют имя класса запускаемого компонента, а декларируют
50выполняемое действие. Действие указывает задачу, которую вы хотите выполнить, например <em>просмотр</em>,
51<em>правка</em>,<em> отправка</em> или <em>получение</em> чего-либо. Объекты Intent часто также содержат данные, ассоциируемые
52с действием, например адрес для просмотра или электронное сообщение для отправки.
53В зависимости от того, какой объект Intent вы хотите создать, данные могут относиться к типу {@link android.net.Uri},
54одному из нескольких других типов данных, либо объекту могут вообще не требоваться данные.</p>
55
56<p>Если ваши данные относятся к типу {@link android.net.Uri}, вы можете использовать простой конструктор {@link
57android.content.Intent#Intent(String,Uri) Intent()} для определения действия и
58данных.</p>
59
60<p>Приведем пример создания объекта Intent для запуска телефонного звонка, в котором данные {@link
61android.net.Uri} используются для указания телефонного номера:</p>
62
63<pre>
64Uri number = Uri.parse("tel:5551234");
65Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
66</pre>
67
68<p>Когда ваше приложение активирует этот объект Intent посредством вызова {@link android.app.Activity#startActivity
69startActivity()}, приложение "Телефон" инициирует звонок на указанный номер телефона.</p>
70
71<p>Вот еще несколько объектов Intent в сочетании с действиями и {@link android.net.Uri} парами
72данных:</p>
73
74<ul>
75  <li>Просмотр карты:
76<pre>
77// Map point based on address
78Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
79// Or map point based on latitude/longitude
80// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
81Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
82</pre>
83  </li>
84  <li>Просмотр веб-страницы:
85<pre>
86Uri webpage = Uri.parse("http://www.android.com");
87Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
88</pre>
89  </li>
90</ul>
91
92<p>Другие виды неявных объектов Intent требуют дополнительные данные, предоставляющие разные типы данных,
93например строки. Вы можете добавить один или несколько элементов дополнительных данных с помощью разных методов {@link
94android.content.Intent#putExtra(String,String) putExtra()}.</p>
95
96<p>Система по умолчанию определяет соответствующий тип MIME, который требует объект Intent на базе включенных данных
97{@link android.net.Uri}. Если не включать {@link android.net.Uri} в объект
98Intent, обычно нужно использовать {@link android.content.Intent#setType setType()} для указания типа
99данных, связанного с объектом Intent. Установка типа MIME также определяет, какие виды
100действий должен получать объект Intent.</p>
101
102<p>Вот некоторые объекты Intent, добавляющие дополнительные данные для указания желаемого действия:</p>
103
104<ul>
105  <li>Отправка электронного письма с вложением:
106<pre>
107Intent emailIntent = new Intent(Intent.ACTION_SEND);
108// The intent does not have a URI, so declare the "text/plain" MIME type
109emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
110emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
111emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
112emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
113emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
114// You can also attach multiple items by passing an ArrayList of Uris
115</pre>
116  </li>
117  <li>Создание события в календаре:
118<pre>
119Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
120Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
121Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
122calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
123calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
124calendarIntent.putExtra(Events.TITLE, "Ninja class");
125calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
126</pre>
127<p class="note"><strong>Примечание.</strong> Этот объект Intent для создания события в календаре поддерживается только
128API-интерфейсами уровня 14 и выше.</p>
129  </li>
130</ul>
131
132<p class="note"><strong>Примечание.</strong> Очень важно определять объекты {@link
133android.content.Intent} как можно более конкретно. Например, если вы хотите вывести изображение
134с помощью объекта Intent {@link android.content.Intent#ACTION_VIEW}, вам следует указать тип MIME
135{@code image/*}. Это не даст объекту Intent запускать приложения для просмотра других типов
136данных (например картографические приложения).</p>
137
138
139
140<h2 id="Verify">Проверка наличия приложения для получения объекта Intent</h2>
141
142<p>Хотя платформа Android гарантирует выполнение объектов Intent во
143встроенных приложениях (таких как "Телефон", "Электронная почта" или "Календарь"), перед активацией объекта Intent всегда следует добавлять шаг
144проверки.</p>
145
146<p class="caution"><strong>Внимание!</strong> Если вы активируете объект Intent, а на устройстве не
147будет приложения, способного его обработать, ваше приложение закроется с ошибкой.</p>
148
149<p>Чтобы убедиться в наличии операции, реагирующей на объект Intent, вызовите метод {@link
150android.content.pm.PackageManager#queryIntentActivities queryIntentActivities()} для получения списка
151операций, способных обработать ваш {@link android.content.Intent}. Если полученный в результате список {@link
152java.util.List} не пустой, вы можете безопасно использовать данный объект Intent. Например:</p>
153
154<pre>
155PackageManager packageManager = {@link android.content.Context#getPackageManager()};
156List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
157        PackageManager.MATCH_DEFAULT_ONLY);
158boolean isIntentSafe = activities.size() > 0;
159</pre>
160
161<p>Если<code>isIntentSafe</code> имеет значение <code>true</code>, то хотя бы одно приложение отреагирует на объект
162Intent. Если же он имеет значение <code>false</code>, то на устройстве нет приложений для обработки данного объекта Intent.</p>
163
164<p class="note"><strong>Примечание.</strong> Такую проверку следует выполнять при первом
165запуске операции на случай, если понадобится отключить функцию, обрабатывающую объект Intent, до того, как пользователь попытается использовать
166ее. Если вам известно определенное приложение, которое может обработать данный объект Intent, вы можете указать ссылку,
167по которой пользователь может загрузить приложение (посмотрите, как <a href="{@docRoot}distribute/tools/promote/linking.html">добавить ссылку на свой продукт в Google
168Play</a>).</p>
169
170
171<h2 id="StartActivity">Запуск операции с объектом Intent</h2>
172
173<div class="figure" style="width:200px;margin-top:-10px">
174  <img src="{@docRoot}images/training/basics/intents-choice.png" alt="" />
175  <p class="img-caption"><strong>Рисунок 1.</strong> Пример диалогового окна выбора,
176которое отображается, если объект Intent могут обработать разные приложения.</p>
177</div>
178
179<p>После создания {@link android.content.Intent} и установки дополнительной информации вызовите {@link
180android.app.Activity#startActivity startActivity()} для отправки в систему. Если система
181идентифицирует несколько операций, способных обработать объект Intent, она выводит для пользователя диалоговое окно
182выбора приложения, как показано на рисунке 1. Если объект Intent может быть обработан
183только одной операцией, система сразу же запускает ее.</p>
184
185<pre>
186startActivity(intent);
187</pre>
188
189<p>Вот полный пример, показывающий, как создать объект Intent для просмотра карты, убедиться в наличии
190приложения для его обработки и запустить это приложение:</p>
191
192<pre>
193// Build the intent
194Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
195Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
196
197// Verify it resolves
198PackageManager packageManager = {@link android.content.Context#getPackageManager()};
199List&lt;ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
200boolean isIntentSafe = activities.size() > 0;
201
202// Start an activity if it's safe
203if (isIntentSafe) {
204    startActivity(mapIntent);
205}
206</pre>
207
208
209
210<h2 id="AppChooser">Отображение блока выбора приложения</h2>
211
212<div class="figure" style="width:200px;margin-top:-10px">
213  <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="" />
214  <p class="img-caption"><strong>Рисунок 2</strong>. Диалог выбора.</p>
215</div>
216
217<p>Обратите внимание, что при запуске операции посредством передачи {@link android.content.Intent} в {@link
218android.app.Activity#startActivity startActivity()} и наличии нескольких приложений, реагирующих на
219объект Intent, пользователь может выбрать, какое из этих приложений использовать по умолчанию (для этого нужно установить флажок в нижней
220части диалогового окна; см. рисунок 1). Это удобно при выполнении действия, для которого
221пользователь обычно хочет всегда использовать одно и то же приложение, например при открытии веб-страницы (пользователи
222обычно используют один и тот же браузер) или создании снимка (пользователи обычно предпочитают одно и то же приложение камеры).</p>
223
224<p>Однако бывает так, что выполняемое действие может быть обработано несколькими приложениями, и пользователь
225каждый раз может использовать разные приложения &mdash; например, действие "Поделиться", для которого пользователи могут использовать разные
226приложения, &mdash; и в этом случае ваше приложение должно отображать диалоговое окно выбора приложения,
227как показано на рисунке 2. В диалоговом окне
228выбора приложения пользователь должен при каждом запуске выбирать, какое приложение использовать для действия (пользователь не
229может выбрать приложение по умолчанию).</p>
230
231<p>Чтобы отобразить блок выбора приложения, создайте {@link android.content.Intent} с помощью {@link
232android.content.Intent#createChooser createChooser()} и передайте его {@link
233android.app.Activity#startActivity startActivity()}. Например:</p>
234
235<pre>
236Intent intent = new Intent(Intent.ACTION_SEND);
237...
238
239// Always use string resources for UI text.
240// This says something like "Share this photo with"
241String title = getResources().getString(R.string.chooser_title);
242// Create intent to show chooser
243Intent chooser = Intent.createChooser(intent, title);
244
245// Verify the intent will resolve to at least one activity
246if (intent.resolveActivity(getPackageManager()) != null) {
247    startActivity(chooser);
248}
249</pre>
250
251<p>В результате отобразится диалоговое окно со списком приложений, которые могут отреагировать на объект Intent, переданный методу {@link
252android.content.Intent#createChooser createChooser()} и используют указанный текст в качестве
253заголовка диалога.</p>
254
255
256
257