Статьи

Android From Scratch: подключение действий и приложений

Android-приложение, состоящее из нескольких простых действий, предлагает гораздо лучший пользовательский интерфейс, чем приложение, в котором все его функции объединены в одно большое и сложное действие. Хорошее эмпирическое правило — стараться ограничить каждое создаваемое вами занятие одной неделимой задачей.

Однако для выполнения таких простых действий вы должны создать связи между действиями и позволить им беспрепятственно обмениваться данными друг с другом. В этом руководстве я покажу вам, как использовать намерения для создания связей между действиями и отправки данных из одного действия в другое.

Тебе легче учиться с видео? Почему бы не проверить наш курс:

  • Android
    Начало работы с Android
    Пол Требилкокс-Руис

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

Intent — это экземпляры класса Intent . Они настолько неотъемлемая часть платформы Android, что они нужны даже самым простым приложениям. Например, рассмотрим приложение Hello World, которое вы создали ранее в этой серии . Он может запускаться, когда вы касаетесь его значка, только потому, что он способен реагировать на намерение, созданное приложением-носителем на вашем устройстве.

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

Намерения могут быть явными или неявными. Намерение называется явным, когда вы инициализируете его, используя литерал класса действия, которое вы хотите запустить. В случае неявных намерений вы указываете только то действие, которое хотите выполнить, и позволяете операционной системе Android определять, какое именно действие следует запустить.

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

Чтобы создать явное намерение, вы можете использовать метод setClass() объекта Intent и передать ему литерал класса действия вместе со ссылкой на текущее действие в качестве контекста. Например, если текущим действием является MainActivity и вы хотите создать намерение запустить действие с именем OtherActivity , вы должны использовать следующий код:

1
2
Intent intent = new Intent();
intent.setClass(MainActivity.this, OtherActivity.class);

Если вы хотите создать явное намерение для действия, которое не принадлежит вашему приложению, вы вместо этого используете метод setComponent() . В качестве аргумента вы должны передать объект ComponentName , который был инициализирован с использованием имени пакета требуемого приложения и полного имени класса требуемой операции.

Например, вот как вы можете создать намерение для действия с именем OtherActivity которое принадлежит приложению с именем пакета com.example.otherapp :

1
2
3
4
5
6
Intent intent = new Intent();
intent.setComponent(
    new ComponentName(«com.example.otherapp»,
                      «com.example.otherapp.OtherActivity»
    )
);

Чтобы создать неявное намерение, вы должны использовать метод setAction() объекта Intent и передать ему строковый объект. Строковый объект указывает имя действия, которое вы намереваетесь выполнить. Android SDK имеет несколько стандартных действий. Для большинства из них вам также необходимо использовать метод setData() чтобы указать данные, с которыми должно работать действие. Данные всегда должны быть в форме объекта Uri .

Одним из наиболее широко используемых стандартных действий является ACTION_VIEW , который можно использовать для запуска различных приложений, таких как браузер по умолчанию, номеронабиратель и приложение контактов. Например, вот как вы создаете неявное намерение набрать номер 123456789 :

1
2
3
4
5
6
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
 
// Generate a valid URI for the telephone number
// using the Uri.parse method and pass it to setData
intent.setData(Uri.parse(«tel:123456789»));

Просто изменив объект Uri вы передаете методу setData() , вы можете изменить приложение ACTION_VIEW . Например, если вы хотите запустить браузер и открыть на нем веб-сайт https://tutsplus.com/ , вызов setData() должен выглядеть следующим образом:

1
intent.setData(Uri.parse(«https://tutsplus.com»));

Некоторые намерения должны содержать дополнительные данные для их правильной работы. Эти дополнительные данные называются экстра. Дополнительным является не что иное, как пара ключ-значение, которая принадлежит объекту Bundle . Использование Bundle похоже на использование HashMap с двумя ограничениями:

  • ключи всегда должны быть объектами String
  • значения всегда должны быть примитивами или объектами Parcelable

Дополнения могут использоваться как с неявными, так и с явными намерениями. Чтобы добавить дополнительный объект Intent , вы можете использовать метод putExtra() . Например, вот как вы можете добавить дополнительный с ключевым сообщением и значением Hello :

1
intent.putExtra(«message», «Hello»);

Теперь, когда вы понимаете, как создать намерение и добавить к нему данные и дополнительные элементы, давайте перейдем к фактическому использованию объектов Intent для запуска действий. Самый простой способ начать действие с использованием объекта Intent — передать его в качестве аргумента startActivity() .

1
startActivity(intent);

Метод startActivity() обычно используется только тогда, когда вы хотите переключиться с одного действия на другое. Другими словами, startActivity() помогает вам startActivity() пользователя с одного экрана вашего приложения на другой.

Если вы хотите запустить действие для выполнения конкретной задачи и получить результат задачи обратно, вы должны вместо этого использовать метод startActivityForResult() . Этот метод, кроме объекта Intent , также ожидает целое число, которое вы используете для определения результата действия. Целое число называется кодом запроса .

Кроме того, чтобы иметь возможность получить результат действия, начатого с помощью startActivityForResult() , ваша активность должна переопределить метод onActivityResult() . Например, в следующем фрагменте кода показано, как создать неявное намерение сделать снимок, используя приложение камеры по умолчанию на устройстве, и в результате получить миниатюру снятого снимка:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// An integer to identify the result of the
// camera app’s activity
final static int CAMERA_RESULT_REQUEST_CODE = 1;
 
private void takePhoto() {
    Intent intent = new Intent();
 
    // Use ACTION_IMAGE_CAPTURE to refer to the
    // default camera app’s activity
    intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
 
    // Launch the activity, and specify that
    // you expect a result whose request
    // code is equal to CAMERA_RESULT_REQUEST_CODE
    startActivityForResult(intent, CAMERA_RESULT_REQUEST_CODE);
}
 
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent result) {
 
    // Check if requestCode matches the request
    // code passed to the startActivityForResult method.
 
    // Also check if the result is valid using the
    // resultCode parameter
 
    if(requestCode == CAMERA_RESULT_REQUEST_CODE && resultCode == RESULT_OK) {
        Bitmap thumbnail =
            (Bitmap)result.getExtras().get(«data»);
    }
}

Обратите внимание, что результатом действия также является объект Intent . В приведенном выше фрагменте кода я сначала использовал метод getExtras() для извлечения Bundle содержащего дополнительные getExtras() которые принадлежат результату. Затем я использовал метод get() для извлечения эскиза в качестве объекта Bitmap .

На предыдущих шагах вы видели, как использовать неявные намерения для запуска действий, которые принадлежат другим приложениям, установленным на устройстве пользователя. Теперь вам может быть интересно, могут ли другие приложения запускать действие, которое принадлежит вашему приложению, используя ту же процедуру. Ответ на этот вопрос «нет, если вы не хотите, чтобы они». По умолчанию из соображений безопасности действие не может быть запущено действиями, которые принадлежат другим приложениям.

Чтобы представить действие другим приложениям, вы должны создать для него фильтр намерений. Для этого необходимо добавить для него тег intent-filter в файле проекта AndroidManifest.xml .

Например, если вы хотите, чтобы действие с именем MyCustomActivity реагировало на пользовательское действие с именем my.custom.action , его запись в манифесте должна выглядеть следующим образом:

1
2
3
4
5
6
<activity android:name=».MyCustomActivity»>
    <intent-filter>
        <action android:name=»my.custom.action»/>
        <category android:name=»android.intent.category.DEFAULT» />
    </intent-filter>
</activity>

Обратите внимание, что наряду с тегом action определяющим имя действия, тег intent-filter должен также содержать тег category , атрибут name которого установлен в android.intent.category.DEFAULT . Без тега category ваша деятельность не сможет отвечать на неявные намерения.

С помощью только что созданного фильтра намерений любое приложение может запустить MyCustomActivity с помощью следующего кода:

1
2
3
4
5
6
7
8
Intent intent = new Intent();
 
// The string passed to the setAction method
// must match the action name mentioned in the
// intent filter
intent.setAction(«my.custom.action»);
 
startActivity(intent);

Если вы предпочитаете не использовать фильтры намерений, но по-прежнему хотите предоставлять действие другим приложениям, вы можете добавить exported атрибут в определение действия в манифесте, установив для него значение true .

1
<activity android:name=».MyCustomActivity» android:exported=»true»/>

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

Теперь вы знаете, как соединить любые два действия, присутствующие на устройстве пользователя, используя неявные и явные намерения. Обладая этими знаниями, вы можете начать создавать сложные приложения с несколькими экранами. Вы также можете легко использовать функции, уже имеющиеся в других приложениях, установленных на устройстве пользователя.

Чтобы узнать больше о намерениях, вы можете обратиться к официальной документации .