Программирование приложений для мобильных устройств под управлением Android. Часть 1 - Евгений Сенько
Шрифт:
Интервал:
Закладка:
Как здесь видно, этот код создает Intent с действием (action) ACTION_SEND. Таким образом, мы хотим послать некоторое электронное письмо. А также добавляет Extras к этому Intent (EXTRA_EMAIL).
Есть несколько различных методов для установки Extras, и форма этих методов будет зависеть от типа данных, которые вы хотите там хранить. Так, например, есть один метод для хранения строковой последовательности, ещё один метод – для хранения массива чисел, и т.д.
Поле флагов (flags). Флаги представляют информацию о том, как Intent должен быть обработан. Некоторые встроенные примеры включают flag_activity_no_history. Что означает, что, когда Activity запущено на основе этого Intent, оно не должно быть помещено в стек.
Другой флаг – FLAG_DEBUG_LOG_RESOLUTION, который говорит Android распечатывать дополнительную информацию о журналировании (log), когда этот Intent обрабатывается, и это – важный инструмент, чтобы его использовать, если ваш Intent не запускает ту Activity, которую вы хотите.
Давайте поговорим о том, как использовать Intent, чтобы запустить Activity. Когда вы используете один из методов startActivity или startActivityForResult, Android должен выяснить, какую конкретно Activity он собирается запустить. И есть два пути, которыми Android это делает.
Первый путь состоит в том, что, если вы явно указали целевую Activity, когда создали Intent (explicit intent), то Android может просто найти и запустить эту определенную Activity.
Второй путь используется, только тогда, когда вы явно не указали целевую Activity, и состоит в том, что Android может неявно определить ее на основе Intent (implicit intent), который использовался, и на основе свойств Activity (или приложений), которые установлены на устройстве.
Давайте рассмотрим приложение, которое явно запускает другую Activity. Это приложение называется «Hello World With Login». Оно состоит из двух Activity. Одна Activity называется LoginActivity, а другая – HelloAndroid. Когда это приложение запущено, первым запускается LoginActivity, оно предоставляет текстовое поле для ввода имени пользователя и поле для ввода пароля. Есть также кнопка Login, которую пользователь нажимает после того как введет имя пользователя и пароль. И затем LoginActivity проверяет введенные данные – пароль и имя пользователя, и если примет их, запустит Activity HelloAndroid, которая выведет на экран слова “HelloAndroid”.
Давайте рассмотрим код, чтобы увидеть как это реализовано. Это класс LoginActivity. Здесь реализован onClickListener («слушатель» кнопки), он присоединен к кнопке Login. Код захватывает имя пользователя и пароль, которое пользователь только что ввел, и затем передает их методу checkPassword. Если checkPassword возвратит true, то код будет выполняться дальше.
Сначала создается Intent (helloAndroidIntent). Вызов конструкторa получает два параметра – контекст и объект класса Activity, которая будет запущена. В этом случае LoginScreen.this используется в качестве контекста.
Контекст (Context) – это интерфейс, который предоставляет доступ к базовым функциям приложения. Так как Activity – это подкласс контекста, то можно использовать .this для этого параметра. Второй параметр – объект класса, в этом случае – HelloAndroid.class. Этот параметр указывает Activity, которая будет запущена вызовом startActivity.
Второй способ запустить Activity – неявная активация. В этой ситуации вы не сообщаете Android, какую Activity запустить, система должна решить это самостоятельно. Android пытается найти соответствие между Intent, который был передан в startActivity или startActivityForResult с возможностями других Activity (или приложений), которые находятся на устройстве. И этот процесс называют intent resolution.
Intent resolution полагается на два вида информации. Во-первых, Activity создает Intent, описывающий действие, которое должно быть выполнено. Во-вторых, у некоторых Activity в Android определены Intent-фильтры (IntentFilters), определяющие виды операций, которые они могут обработать. Эта информация обычно помещается в файл androidmanifest.xml или в приложения, которым эти Activity принадлежат.
Во время выполнения, когда вызван метод startActivity, Android попытается найти соответствие между Intent и известными Intent-фильтрами. Но он будет использовать только часть информации, содержащейся в Intent. В частности он будет смотреть на поле Action (действие), на Data (данные), включая URI и mime-тип и на Категорию (Category).
Рассмотрим то, как приложения определяют Intent-фильтры в своих файлах androidmanifest.xml. Вот отрывок xml, показывающий тег Activity, этот тег содержит в себе тег Intent-фильтра c соответствующим действием, которое он поддерживает. Например, если Activity может набирать номер телефона, то она должна содержать Intent-фильтр со стандартным intent.action.dial.
Если ваша Activity обрабатывает определенный тип данных, она может добавить эту информацию к ее Intent-фильтру, например, Activity может определить mime-тип данных, которые она обрабатывает. Вы можете также определить схему, хост или номер порта данных UI, которые она обрабатывает. В дальнейшем можно будет ограничить формат данных URI, определив путь, шаблон или префикс пути.
Если Activity хочет объявить, что она может, например, показывать карты, тогда она могла бы содержать Intent-фильтр, который говорит Android, что она может обработать данные URI со схемой geo.
Точно так же Activity могут определить категории для Intent, которые они обрабатывают.
Теперь мы можем предположить или представить на основе тех приложений «Map location», которые мы видели прежде, что «Google Maps» может обработать Intent, которые содержат action_view и которые содержат поле данных со схемой geo. Файл androidmanifest.xml для приложения карт Google выглядит примерно следующим образом. Имеется Activity с Intent-фильтром. И этот фильтр перечислен в Action intent.action.view. И у него есть данные со схемой geo. Фактически это то, что приложение «Map location» передали в стартовую Activity Google-карт.
Activity также перечисляет две категории. Одна – category.browsable означает, что Activity может реагировать на ссылки браузера. Другая – cateogry.default. Оказывается, что в большинстве случаев Activity, которые хотят принимать implicit intents, должны включать category.defualt в свои Intent-фильтры.
Наконец, когда больше чем одна Activity может принять определенный Intent, Android должен будет приостановить исполнение для принятия решения. Один вариант – спросить пользователя, какую Activity (или приложение) он хочет использовать. И второй вариант – это использовать возможность того, что Activity могут определить приоритет, который Android примет во внимание при выборе между двумя различными Activity, которые могут обработать данный Intent. Значения приоритета должны быть между минус 1000 и плюс 1000, более высокие значения имеют более высокий приоритет.
Permissions
Android использует Permissions (полномочия, разрешения), чтобы защитить ресурсы, данные и операции. Приложения могут определять и устанавливать свои собственные полномочия, чтобы ограничить доступ к их ресурсам и информации о пользователе. Например, чтобы ограничить, кто может получить доступ к базе данных приложения, платным услугам, ограничить какие компоненты могут вызвать дорогостоящие операции, такие как исходящие сообщения SMS или MMS, ограничить доступ к системным ресурсам, например, чтобы определить какие компоненты могут использовать камеру устройства для съемки фото или записи видео.
В Android полномочия (Permissions) представлены как строковые последовательности. Приложения включают эти строки в файл androidmanifest.xml. Они могут сделать это, чтобы объявить полномочия, которые они используют сами, и полномочия, которые они требуют от других компонентов, которые хотят использовать их.
Сначала, если приложение должно использовать разрешение (permission), оно объявляет это разрешение тегом uses-permission в его файле androidmanifest.xml. И когда это приложение будет устанавливаться на устройство, пользователь должен будет согласиться с этим разрешением, иначе произойдут ошибки или отказы доступа.
Рассмотрим кусок файла androidmanifest.xml для гипотетического приложения.
Как видите, для этого приложения нужны полномочия получить доступ к камере устройства, доступ к Интернету и доступ к информации о точном местоположении с приемника GPS.
Вспомним приложение «Map location from contacts». Это приложение позволяет пользователю выбирать контакт из телефонной книги (приложение Contacts) и затем отображать карту, центрируемую на почтовом адресе этого контакта. Если запустить это приложение, я увижу кнопку, которая позволит мне выбрать контакт. Когда я щелкаю по этой кнопке, приложение контактов показывает мне мои контакты и позволяет мне выбрать один из них. Как только я сделаю это, почтовый адрес и другая информация о контакте передается в «Google Maps», которая выводит на экран карту, центрируемую на почтовом адресе выбранного контакта.
Но мой список контактов – частная информация. Android не позволяет любому приложению на моем устройстве просто иметь доступ к списку контактов. Так как «Map location from contacts» получает доступ к нему? Приложение, должно быть, объявило, что использует надлежащее разрешение (permission). И мы можем увидеть подтверждение этому в файле androidmanifest.xml.