Главная страница
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей

Программирование под Android. Для профессионалов


Скачать 19.35 Mb.
НазваниеПрограммирование под Android. Для профессионалов
АнкорBrayn_Khardi_Bill_Fillips_-_Programmirovanie_po.
Дата23.05.2017
Размер19.35 Mb.
Формат файлаpdf
Имя файлаBrayn_Khardi_Bill_Fillips_-_Programmirovanie_po.pdf
оригинальный pdf просмотр
ТипДокументы
#21061
страница33 из 55
КаталогОбразовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
1   ...   29   30   31   32   33   34   35   36   ...   55
Глава 21. Неявные интенты
Рис. 21.3. Нижние кнопки частично скрыты в альбомном режиме
Как видно из рис. 21.3, на малых экранах новые кнопки видны лишь частично. Чтобы решить эту проблему, мы разместим весь макет для альбомного режима в
ScrollView
Новый макет представлен на рис. 21.4. Так как корневым элементом теперь является
ScrollView
, не забудьте переместить пространство имен из предыдущего корневого элемента в
ScrollView
Рис. 21.4. Добавление кнопок для выбора контактов и отправки отчетов
(layout_land/fragment_crime.xml)

Форматные строки
357
На этой стадии вы можете проверить макеты в области предварительного просмо- тра или запустить приложение CriminalIntent, чтобы убедиться в правильности расположения новых кнопок.
Добавление имени в уровень модели
Вернитесь к файлу
Crime.java
, добавьте новую константу JSON и поле для хранения имени подозреваемого. Также измените методы JSON для выполнения сериализа- ции/десериализации из кода JSON и добавьте новые методы доступа.
Листинг 21.2. Добавление поля для имени подозреваемого (Crime.java)
public class Crime {
private static final String JSON_PHOTO = "photo";
private static final String JSON_SUSPECT = "suspect";
private Photo mPhoto;
private String mSuspect;
public Crime(JSONObject json) throws JSONException {
mId = UUID.fromString(json.getString(JSON_ID));
if (json.has(JSON_PHOTO))
mPhoto = new Photo(json.getJSONObject(JSON_PHOTO));
if (json.has(JSON_SUSPECT))
mSuspect = json.getString(JSON_SUSPECT);
}
public JSONObject toJSON() throws JSONException {
JSONObject json = new JSONObject();
if (mPhoto != null)
json.put(JSON_PHOTO, mPhoto.toJSON());
json.put(JSON_SUSPECT, mSuspect);
return json;
}
public void setPhoto(Photo p) {
mPhoto = p;
}
public String getSuspect() {
return mSuspect;
}
public void setSuspect(String suspect) {
mSuspect = suspect;
}
}
Форматные строки
Последним подготовительным шагом станет создание шаблона отчета о престу- плении, который заполняется информацией о конкретном преступлении. Так как

358
Глава 21. Неявные интенты подробная информация недоступна до стадии выполнения, необходимо исполь- зовать форматную строку с заполнителями, которые будут заменяться во время выполнения. Форматная строка будет выглядеть так:
%1$s! The crime was discovered on %2$s. %3$s, and %4$s
Поля
%1$s
,
%2$s и т. д. — заполнители для строковых аргументов. В коде вы вы- зываете getString(…)
и передаете форматную строку и еще четыре строки в том порядке, в каком они должны заменять заполнители.
Сначала добавьте в strings.xml строки из листинга 21.3.
Листинг 21.3. Добавление строковых ресурсов (strings.xml)
Choose Suspect
Send Crime Report
%1$s!
The crime was discovered on %2$s. %3$s, and %4$s

The case is solved
The case is not solved
There is no suspect.
The suspect is %s.
CriminalIntent Crime Report
Send crime report via

В файле
CrimeFragment.java добавьте метод, который создает четыре строки, соединяет их и возвращает полный отчет.
Листинг 21.4. Добавление метода getCrimeReport() (CrimeFragment.java)
private String getCrimeReport() {
String solvedString = null;
if (mCrime.isSolved()) {
solvedString = getString(R.string.crime_report_solved);
} else {
solvedString = getString(R.string.crime_report_unsolved);
}
String dateFormat = "EEE, MMM dd";
String dateString = DateFormat.format(dateFormat, mCrime.getDate()).toString();
String suspect = mCrime.getSuspect();
if (suspect == null) {
suspect = getString(R.string.crime_report_no_suspect);
} else {
suspect = getString(R.string.crime_report_suspect, suspect);
}
String report = getString(R.string.crime_report,
mCrime.getTitle(), dateString, solvedString, suspect);
return report;
}
Приготовления завершены, теперь можно непосредственно заняться неявными интентами.

Использование неявных интентов
359
Использование неявных интентов
Объект
Intent описывает для ОС некую операцию, которую вы хотите выполнить.
Для явных интентов, использовавшихся до настоящего момента, разработчик явно указывает активность, которую должна запустить ОС.
Intent i = new Intent(getActivity(), CrimeCameraActivity.class);
startActivity(i);
Для неявных интентов разработчик описывает выполняемую операцию, а ОС за- пускает активность, которая ранее сообщила о том, что она способна выполнять эту операцию. Если ОС находит несколько таких активностей, пользователю пред- лагается выбрать нужную.
Компоненты неявного интента
Ниже перечислены важнейшие составляющие интента, используемые для опреде- ления выполняемой операции.
Выполняемое действие (action) — обычно определяется константами из класса
Intent
. Так, для просмотра URL-адреса используется константа
Intent.ACTION_VIEW
, а для отправки данных — константа
Intent.ACTION_SEND
Местонахождение данных — это может быть как ссылка на данные, находящиеся за пределами устройства (скажем, URL веб-страницы), так и URI файла или URI контента, ссылающийся на запись
ContentProvider
Тип
данных, с которыми работает действие, — тип MIME (например, text/html или audio/mpeg3
). Если в интент включено местонахождение данных, то тип обычно удается определить по этим данным.
Необязательные категории — если действие используется для описания выпол- няемой операции, категория обычно описывает, где, когда или как вы пытаетесь использовать операцию. Android использует категорию android.intent.category.
LAUNCHER
для обозначения активностей, которые должны отображаться в лаунчере приложений верхнего уровня. С другой стороны, категория android.intent.cat- egory.INFO
обозначает активность, которая выдает пользователю информацию о пакете, но не отображается в лаунчере.
Простой неявный интент для просмотра веб-сайта включает действие
Intent.AC-
TION_VIEW
и объект данных
Uri с URL-адресом сайта.
На основании этой информации ОС запускает соответствующую активность со- ответствующего приложения. (Если ОС обнаруживает более одного кандидата, пользователю предлагается принять решение.)
Активность сообщает о себе как об исполнителе для
ACTION_VIEW
при помощи фильтра интентов в манифесте. Например, если вы пишете приложение-браузер, вы включаете следующий фильтр интентов в объявление активности, реагирующей на
ACTION_VIEW
android:label="@string/app_name" >
продолжение


360
Глава 21. Неявные интенты






Категория
DEFAULT
должна явно задаваться в фильтрах интентов. Элемент action в фильтре интентов сообщает ОС, что активность способна выполнять операцию, а категория
DEFAULT
— что она желает рассматриваться среди кандидатов на выпол- нение операции. Категория
DEFAULT
неявно добавляется к почти любому неявному интенту. (Единственное исключение составляет категория
LAUNCHER
, с которой мы будем работать в главе 23.)
Неявные интенты, как и явные, также могут включать дополнения. Однако до- полнения неявного интента не используются ОС для поиска соответствующей активности.
Также следует отметить, что компоненты действия и данных интента могут ис- пользоваться в сочетании с явными интентами. Результат эквивалентен тому, что вы приказываете конкретной активности выполнить конкретную операцию.
Отправка отчета
Чтобы увидеть на практике, как работает эта схема, мы создадим неявный интент для отправки отчета о преступлении в приложении CriminalIntent. Операция, которую нужно выполнить, — отправка простого текста; отчет представляет собой строку. Таким образом, действие неявного интента будет представлено константой
ACTION_SEND
. Интент не содержит ссылок на данные и не имеет категорий, но опре- деляет тип text/plain
В методе
CrimeFragment.onCreateView(…)
получите ссылку на кнопку
Send
Crime
Report и назначьте для нее слушателя. В реализации слушателя создайте неявный интент и передайте его startActivity(Intent)
Листинг 21.5. Отправка отчета о преступлении (CrimeFragment.java)
Button reportButton = (Button)v.findViewById(R.id.crime_reportButton);
reportButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_TEXT, getCrimeReport());
i.putExtra(Intent.EXTRA_SUBJECT,
getString(R.string.crime_report_subject));
startActivity(i);
}
});
return v;
}

Использование неявных интентов
361
Здесь мы используем конструктор
Intent
, ко- торый получает строку с константой, описы- вающей действие. Также существуют другие конструкторы, которые могут использоваться в зависимости от вида создаваемого неявно- го интента. Информацию о них можно найти в справочной документации
Intent
. Конструк- тора, получающего тип, не существует, поэтому мы задаем его явно.
Текст отчета и строка темы включаются в до- полнения. Обратите внимание на использование в них констант, определенных в классе
Intent
Любая активность, реагирующая на интент, знает эти константы и то, что следует делать с ассоци- ированными значениями.
Запустите приложение CriminalIntent и нажми- те кнопку
Send
Crime
Report
. Так как этот интент с большой вероятностью совпадет со многими активностями на устройстве, скорее всего, на экране появится список активностей:
Если на экране появился список, выберите нуж- ный вариант. Вы увидите, что отчет о преступле- нии загружается в выбранном вами приложении.
Вам остается лишь ввести адрес и отправить его.
Если список не появился, это может означать одно из двух: либо вы уже на- значили приложение по умолчанию для идентичного неявного интента, либо на вашем устройстве имеется всего одна активность, способная реагировать на этот интент.
Часто лучшим вариантом оказывается использование приложения по умолчанию, выбранного пользователем для данного действия. Впрочем, в приложении Crim- inalIntent лучше всегда предоставлять пользователю выбор: сегодня пользователь предпочтет не поднимать шума и отправит отчет по электронной почте, а завтра выставит нарушителя на общественный позор в Твиттере.
Вы можете создать список, который будет отображаться каждый раз при использо- вании неявного интента для запуска активности. После создания неявного интента способом, показанным ранее, вы вызываете следующий метод
Intent и передаете ему неявный интент и строку с заголовком:
public static Intent createChooser(Intent target, String title)
Затем интент, возвращенный createChooser(…)
, передается startActivity(…)
В файле
CrimeFragment.java создайте список выбора для отображения активностей, реагирующих на неявный интент.
Рис. 21.5. Активности, заявившие о своей готовности выполнить отправку отчета

362
Глава 21. Неявные интенты
Листинг 21.6. Использование списка выбора (CrimeFragment.java)
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_TEXT, getCrimeReport());
i.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.crime_report_subject));
i = Intent.createChooser(i, getString(R.string.send_report));
startActivity(i);
}
Запустите приложение CriminalIntent и нажмите кнопку
Send
Crime
Report
. Если в системе имеется несколько активностей, способных обработать ваш интент, на экране появляется список для выбора.
Рис. 21.6. Отправка текста с выбором активности
Запрос контакта у Android
Теперь мы создадим другой неявный интент, который предлагает пользователю вы- брать подозреваемого из списка контактов. Для этого неявного интента будет опре- делено действие и местонахождение соответствующих данных. Действие задается константой
Intent.ACTION_PICK
, а местонахождение данных —
ContactsContract.

Использование неявных интентов
363
Contacts.CONTENT_URI
. Короче говоря, вы просите Android помочь с выбором записи из базы данных контактов.
Запущенная активность должна вернуть результат, поэтому мы передаем интент через startActivityForResult(…)
вместе с кодом запроса. Добавьте в файл
CrimeFrag- ment.java константу для кода запроса и поле для кнопки.
Листинг 21.7. Добавление поля для кнопки подозреваемого (CrimeFragment.java)
private static final int REQUEST_PHOTO = 1;
private static final int REQUEST_CONTACT = 2;
private ImageButton mPhotoButton;
private Button mSuspectButton;
В конце onCreateView(…)
получите ссылку на кнопку и назначьте ей слушателя.
В реализации слушателя создайте неявный интент и передайте его startActivity-
ForResult(…)
. Также выведите на кнопке имя подозреваемого (если оно содержится в
Crime
).
Листинг 21.8. Отправка неявного интента (CrimeFragment.java)
mSuspectButton = (Button)v.findViewById(R.id.crime_suspectButton);
mSuspectButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_PICK,
ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(i, REQUEST_CONTACT);
}
});
if (mCrime.getSuspect() != null) {
mSuspectButton.setText(mCrime.getSuspect());
}
return v;
}
Запустите приложение CriminalIntent и нажмите кнопку
Choose
Suspect
. На экране появляется список контактов.
Если у вас установлено другое контактное приложение, экран будет выглядеть иначе. Это еще одно преимущество неявных интентов: вам не нужно знать на- звание контактного приложения, чтобы использовать его из своего приложения.
Соответственно пользователь может установить то приложение, которое считает нужным, а ОС найдет и запустит его.

364
Глава 21. Неявные интенты
Рис. 21.7. Список подозреваемых
Получение данных из списка контактов
Теперь необходимо получить результат от контактного приложения. Контактная информация совместно используется многими приложениями, поэтому Android предоставляет расширенный API для работы с контактными данными через
ContentProvider
. Экземпляры этого класса инкапсулируют базы данных и предо- ставляют доступ к ним другим приложениям. Обращение к
ContentProvider осу- ществляется через
ContentResolver
Так как активность запускалась с возвращением результата с использованием
ACTION_PICK
, вы можете получить интент вызовом onActivityResult(…)
. Интент включает URI данных — ссылку на конкретный контакт, выбранный пользователем.
В файле
CrimeFragment.java добавьте следующий код в реализацию onActivityRe- sult(…)
из
CrimeFragment
Листинг 21.9. Получение имени контакта (CrimeFragment.java)
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) return;
if (requestCode == REQUEST_DATE) {
} else if (requestCode == REQUEST_PHOTO) {

Использование неявных интентов
365
} else if (requestCode == REQUEST_CONTACT) {
Uri contactUri = data.getData();
// Определение полей, значения которых должны быть
// возвращены запросом.
String[] queryFields = new String[] {
ContactsContract.Contacts.DISPLAY_NAME
};
// Выполнение запроса - contactUri здесь выполняет функции
// условия "where"
Cursor c = getActivity().getContentResolver()
.query(contactUri, queryFields, null, null, null);
// Проверка получения результатов
if (c.getCount() == 0) {
c.close();
return;
}
// Извлечение первого столбца данных - имени подозреваемого.
c.moveToFirst();
String suspect = c.getString(0);
mCrime.setSuspect(suspect);
mSuspectButton.setText(suspect);
c.close();
}
}
В листинге 21.9 создается запрос, который запрашивает все отображаемые имена контактов из возвращаемых данных. Затем мы выдаем запрос к базе данных кон- тактов и получаем объект
Cursor для работы с ней. Так как мы знаем, что курсор содержит всего один элемент, мы переходим к первому элементу и используем его как строку. Эта строка содержит имя подозреваемого, которое мы используем для задания подозреваемого в
Crime и текста кнопки
Choose
Suspect
(База данных контактов сама по себе является достаточно обширной темой. Здесь она не рассматривается. Если вам захочется узнать больше, обратитесь к руковод- ству по Contacts Provider API: https://developer.android.com/guide/topics/providers/
contacts-provider.html
.)
Разрешения контактов
Как получить разрешение на чтение из базы данных контактов? Контактное при- ложение распространяет свои разрешения на вас. Оно обладает полными разре- шениями на обращение к базе данных. Когда контактное приложение возвращает родительской активности URI данных в интенте, оно также добавляет флаг
Intent.
FLAG_GRANT_READ_URI_PERMISSION
. Этот флаг сообщает Android, что родительской активности в CriminalIntent следует разрешить однократное использование этих данных. Такой подход работает хорошо, потому что фактически нам нужен доступ не ко всей базе данных контактов, а к одному контакту в этой базе.

366
1   ...   29   30   31   32   33   34   35   36   ...   55

перейти в каталог файлов
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей