Android для начинающих: подключение действий и приложений
Russian (Pусский) translation by Masha Kolesnikova (you can also view the original English article)
Приложение Android, состоящее из нескольких простых действий, имеет тенденцию предлагать гораздо лучший пользовательский интерфейс, чем тот, который переполняет все его функциональные возможности одним, большим и сложным видом деятельности. Хорошее эмпирическое правило - попытаться ограничить каждое действие, которое вы создаете, на одну неделимую задачу.
Однако, чтобы добиться успеха в таких простых действиях, вы должны создавать связи между действиями и позволять им беспрепятственно обмениваться данными друг с другом. В этом уроке я покажу вам, как использовать намерения для создания соединений между действиями и отправки данных из одной активности в другую.
1. Что такое намерение?
В реальном мире, прежде чем вы начнете выполнять какое-либо действие, вы обычно собираетесь его выполнять. То же самое верно в мире приложений для Android. Чтобы начать работу с Android, у вас должно быть намерение.
Намерения - это экземпляры класса Intent
. Они являются такой неотъемлемой частью платформы Android, что даже самые простые приложения нуждаются в них. Например, рассмотрим приложение Hello World, которое вы создали ранее в этой серии. Оно может запускаться, когда вы касаетесь его значка только потому, что оно способно реагировать на намерение, созданное приложением запуска на вашем устройстве.
Наряду с подробностями о деятельности, намерение может содержать дополнительные данные, точно называемые extra data, для отправки аргументов или возврата результатов от одного действия другому.
2. Виды намерений
Намерения могут быть явными или неявными. Предполагается, что намерение является явным, когда вы инициализируете его, используя литерал класса, который вы хотите запустить. В случае неявных намерений вы укажете только действие, которое вы хотите выполнить, и пусть операционная система Android определит точные действия, которые необходимо запустить.
Обычно явные намерения используются для запуска действий, принадлежащих вашему собственному приложению, тогда как подразумеваемые намерения предназначены для действий, которые принадлежат другим приложениям, установленным на устройстве пользователя.
3. Создание явного намерения
Чтобы создать явное намерение, вы можете использовать метод setClass()
объекта Intent
и передать ему литерал класса для него, а также ссылку на вашу текущую деятельность в качестве контекста. Например, если ваша текущая деятельность MainActivity
и вы хотите создать намерение начать действие под названием OtherActivity
, вы должны использовать следующий код:
1 |
Intent intent = new Intent(); |
2 |
intent.setClass(MainActivity.this, OtherActivity.class); |
Если вы хотите создать явное намерение для деятельности, которая не принадлежит вашему приложению, вместо этого вы используете метод setComponent()
. В качестве аргумента вы должны передать объект ComponentName
, который был инициализирован с использованием имени пакета требуемого приложения и полного имени класса требуемой активности.
Например, вот как вы создадите намерение для действия под названием OtherActivity
, которое принадлежит к приложению, чье имя пакета com.example.otherapp:
1 |
Intent intent = new Intent(); |
2 |
intent.setComponent( |
3 |
new ComponentName("com.example.otherapp", |
4 |
"com.example.otherapp.OtherActivity"
|
5 |
)
|
6 |
);
|
4. Создание неявного намерения
Чтобы создать неявное намерение, вы должны использовать метод setAction()
объекта Intent
и передать ему строковый объект. Строковый объект указывает имя действия, которое вы собираетесь выполнить. Android SDK имеет несколько стандартных действий. Для большинства из них вам также необходимо использовать метод setData()
для указания данных, с которыми должно работать действие. Данные всегда должны быть в форме объекта Uri
.
Одним из наиболее широко используемых стандартных действий является ACTION_VIEW
, который можно использовать для запуска различных приложений, таких как браузер по умолчанию, дозвонщик и приложение для контактов. Например, вот как вы создаете неявное намерение набрать номер 123456789:
1 |
Intent intent = new Intent(); |
2 |
intent.setAction(Intent.ACTION_VIEW); |
3 |
|
4 |
// Generate a valid URI for the telephone number
|
5 |
// using the Uri.parse method and pass it to setData
|
6 |
intent.setData(Uri.parse("tel:123456789")); |
Просто изменив объект Uri
, который вы передаете методу setData()
, вы можете изменить открытие приложения ACTION_VIEW
. Например, если вы хотите запустить браузер и открыть сайт https://tutsplus.com/, вызов setData()
должен выглядеть следующим образом:
1 |
intent.setData(Uri.parse("https://tutsplus.com")); |
5. Добавление дополнений к намерению
Некоторые намерения для правильной работы должны содержать дополнительные данные. Эти дополнительные данные называются extra. Дополнительным является не что иное, как пары ключ-значение, принадлежащая объекту Bundle
. Использование Bundle
похоже на использование HashMap
с двумя ограничениями:
- ключи всегда должны быть объектами
String
- значения всегда должны быть примитивными или объектами
Parcelable
Экстра может использоваться как с явным, так и с явным намерением. Чтобы добавить дополнительный объект Intent
, вы можете использовать метод putExtra()
. Например, вот как вы можете добавить дополнительный ключ message со значением Hello:
1 |
intent.putExtra("message", "Hello"); |
6. Использование намерения
Теперь, когда вы понимаете, как создать намерение и добавить к нему данные и дополнения, давайте перейдем к использованию объектов Intent
для запуска действий. Самый простой способ начать работу с использованием объекта Intent
- передать его в качестве аргумента методу startActivity()
.
1 |
startActivity(intent); |
Метод startActivity()
обычно используется только тогда, когда вы хотите переключиться с одного действия на другое. Другими словами, startActivity()
помогает вам переносить пользователя с одного экрана вашего приложения на другое.
Если вы хотите запустить операцию для выполнения конкретной задачи и вернуть результат задачи, вместо этого вы должны использовать метод startActivityForResult()
. Этот метод, помимо объекта Intent
, также ожидает целое число, которое вы используете для идентификации результата активности. Целое число называется кодом запроса.
Кроме того, чтобы иметь возможность получить результат активности, запущенной с использованием метода startActivityForResult()
, ваша активность должна переопределить метод onActivityResult()
. Например, следующий фрагмент кода показывает вам, как создать неявное намерение сделать снимок с помощью приложения камеры по умолчанию и получить захваченный снимок в результате:
1 |
// An integer to identify the result of the
|
2 |
// camera app's activity
|
3 |
final static int CAMERA_RESULT_REQUEST_CODE = 1; |
4 |
|
5 |
private void takePhoto() { |
6 |
Intent intent = new Intent(); |
7 |
|
8 |
// Use ACTION_IMAGE_CAPTURE to refer to the
|
9 |
// default camera app's activity
|
10 |
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); |
11 |
|
12 |
// Launch the activity, and specify that
|
13 |
// you expect a result whose request
|
14 |
// code is equal to CAMERA_RESULT_REQUEST_CODE
|
15 |
startActivityForResult(intent, CAMERA_RESULT_REQUEST_CODE); |
16 |
}
|
17 |
|
18 |
@Override
|
19 |
protected void onActivityResult(int requestCode, int resultCode, Intent result) { |
20 |
|
21 |
// Check if requestCode matches the request
|
22 |
// code passed to the startActivityForResult method.
|
23 |
|
24 |
// Also check if the result is valid using the
|
25 |
// resultCode parameter
|
26 |
|
27 |
if(requestCode == CAMERA_RESULT_REQUEST_CODE && resultCode == RESULT_OK) { |
28 |
Bitmap thumbnail = |
29 |
(Bitmap)result.getExtras().get("data"); |
30 |
}
|
31 |
}
|
Обратите внимание, что результатом активности является также объект Intent
. В приведенном выше фрагменте кода я сначала использовал метод getExtras()
для извлечения Bundle
, содержащего дополнительные компоненты, которые относятся к результату. Затем я использовал метод get()
для извлечения миниатюры в качестве объекта Bitmap
.
7. Использование фильтров намерений
На предыдущих шагах вы видели, как использовать неявные намерения для запуска действий, которые принадлежат другим приложениям, установленным на устройстве пользователя. Теперь вам может быть интересно, могут ли другие приложения запускать активность, принадлежащую вашему приложению, с использованием той же процедуры. Ответ на этот вопрос «нет, если вы этого не хотите». По умолчанию по соображениям безопасности действие не может быть запущено с помощью действий, относящихся к другим приложениям.
Чтобы открыть действие для других приложений, вы должны создать для него фильтр намерений. Для этого вы должны добавить в файл проекта AndroidManifest.xml тэг intent-filter
.
Например, если вы хотите, чтобы действие, называемое MyCustomActivity
, отвечало на пользовательское действие с именем my.custom.action, его запись в манифесте должна выглядеть так:
1 |
<activity android:name=".MyCustomActivity"> |
2 |
<intent-filter>
|
3 |
<action android:name="my.custom.action"/> |
4 |
<category android:name="android.intent.category.DEFAULT" /> |
5 |
</intent-filter>
|
6 |
</activity>
|
Обратите внимание, что вместе с тегом action
, определяющим имя действия, тег intent-filter
должен также содержать тег category
, атрибут name
которого установлен в android.intent.category.DEFAULT. Без тега category
ваша деятельность не сможет реагировать на неявные намерения.
С фильтром намерения, который мы только что создали, любое приложение может запустить MyCustomActivity
, используя следующий код:
1 |
Intent intent = new Intent(); |
2 |
|
3 |
// The string passed to the setAction method
|
4 |
// must match the action name mentioned in the
|
5 |
// intent filter
|
6 |
intent.setAction("my.custom.action"); |
7 |
|
8 |
startActivity(intent); |
Если вы предпочитаете не использовать фильтры намерений, но все же хотите показывать действие другим приложениям, вы можете добавить атрибут exported
в определение активности в манифесте, установив для него значение true
.
1 |
<activity android:name=".MyCustomActivity" android:exported="true"/> |
В этом случае у других приложений нет другого выбора, кроме как использовать явные намерения для запуска активности.
Заключение
Теперь вы знаете, как подключать любые два действия, присутствующие на устройстве пользователя, с использованием неявных и явных намерений. С помощью этих знаний вы можете приступить к созданию сложных приложений с несколькими экранами. Вы также можете легко повторно использовать функциональные возможности, уже присутствующие в других приложениях, установленных на устройстве пользователя.
Чтобы узнать больше о намерениях, вы можете обратиться к официальной документации.