LXF151:Android: Музыка на марше
|
|
|
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
- Часть 1: В первой из двух статей цикла Джульетта Кемп обращает свой взгляд на MediaPlayer и создает и запускает простой MP3-плейер.
Если вы программист, то, безусловно, оцените одну из лучших возможностей Android – удобный, хорошо задокументированный обширный API: огромное количество классов и интерфейсов, которыми можно воспользоваться с минимумом усилий. И если у вас нет веской причины этого не делать, лучше обойтись им, чем разворачивать собственные классы, отчасти ради экономии времени и усилий, а отчасти потому, что классы и интерфейсы API стабильно работают с устройствами Android.
На двух следующих уроках мы коснемся API для работы со звуком/мультимедиа, который позволяет проигрывать файлы MP3 и других форматов. На этом уроке мы проиграем файлы, расположенные на SD-карте, а в следующем займемся потоковым воспроизведением. Мы предполагаем, что вы хотя бы отдаленно знакомы со средой разработки и развертывания программ для Android, и употребим командную строку вместо Eclipse – но если вы предпочтете Eclipse, он прекрасно подойдет.
Скорая помощь
Помните, что пример кода на DVD не компилируется «как есть»; нужно создать его либо как мы объяснили, либо с помощью Eclipse, чтобы компилятор знал, где найти локальную установку SDK.
Начальные установки: приступаем
Я компилировала в версии 10, и она нужна по меньшей мере одному примененному здесь классу, но все базовые классы должны быть доступны и в более ранних версиях:
android create project --target android-10 --name mp3 \\
--path ~/android/mp3 --activity AndroidMP3 --package com.example.androidmp3
Для первой версии нашего проекта мы просто возьмем список MP3-файлов, имеющихся на SD-карте. Сначала создайте list.xml в res/layout, чтобы настроить представление [View], которое будет использовать программа:
<?xml version=”1.0” encoding=”UTF-8”?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”vertical”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”>
<ListView android:id=”@id/android:list”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:layout_weight=”1”
android:drawSelectorOnTop=”false”/>
<TextView android:id=”@id/android:empty”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:text=”@string/emptylist”/>
</LinearLayout>
Обратите внимание на автоматический компонент android:
empty – он задает текст, отображаемый, если список пуст (текст задайте в res/values/strings.xml). Нам также понадобится файл item.xml, определяющий, как будут отображаться элементы списка:
<?xml version=”1.0” encoding=”utf-8”?>
<TextView android:id=”@+id/title” xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”/>
Вернемся к файлу AndroidMP3.java. Базовый список MP3-файлов должен наследовать ListActivity. Создавая действие, зададим его представление и обновим список доступных MP3-файлов:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
updateMP3List();
}
Мы уже создали R.layout.list; теперь запишем updateMP3List():
private static final String MEDIA_PATH = new String(“/sdcard/”);
private List<String> mp3list = new ArrayList<String>();
[ ... ]
public void updateMP3List() {
File home = new File(MEDIA_PATH);
if ( home.listFiles( new Mp3Filter() ).length > 0 ) {
for ( File file : home.listFiles( new Mp3Filter() ) ) {
mp3list.add(file.getName());
}
ArrayAdapter<String> mp3ListAdapter =
new ArrayAdapter<String>(this, R.layout.item, mp3list);
setListAdapter(mp3ListAdapter);
}
else {
// No files here; ‘empty’ string will be seen
}
}
Строка MEDIA_PATH задается всему классу, а затем применяется для создания нового объекта File. Метод listFiles() возвращает массив файлов в заданный каталог, соответствующий фильтру. Стало быть, нужно также создать Mp3Filter – легко реализовав его как вспомогательный класс внутри главного:
class Mp3Filter implements FilenameFilter {
public boolean accept(File dir, String name) {
return (name.endsWith(“.mp3”));
}
}
Создание ArrayAdapter
Вернемся к updateMP3List(). Оператор if проверяет, есть ли в каталоге на SD-карте MP3-файлы. Если их нет, будет использоваться строка «empty». Хотя блок else пуст, стоит задокументировать, что это сделано сознательно – проще будет сопровождать код потом.
Если файлы есть, мы по очереди проходим их, добавляя в список. Затем мы должны объявить ArrayAdapter, чтобы работать со списком mp3List как с массивом, который Android может отобразить, пользуясь TextView из файла item.xml для каждого элемента. Это еще одна часть стандартного API Android, и мы будем применять ее часто. Она выступает как интерфейс между TextView и массивом объектов любого типа. (Ее можно использовать и как интерфейс для более сложных типов представлений, перегрузив ее метод getView(); здесь нам достаточно TextView.)
Раздобыв список MP3-файлов, нужно позаботиться, чтобы при щелчке пользователя на элементе списка что-то произошло – а именно, воспроизвелся данный MP3-файл. Следующий фрагмент кода использует стандартный метод onListItemClick:
private int currentPosition = 0;
[ ... ]
protected void onListItemClick(ListView list, View view, int position, long id) {
currentPosition = position;
playMp3(MEDIA_PATH + mp3List.get(position));
}
Мы записали текущее положение в currentPosition, чтобы знать, где мы находимся в списке, и вызвали метод playMp3() для воспроизведения нужного файла:
private MediaPlayer mp = new MediaPlayer();
[ ... ]
private void playMp3(String mp3Path) {
try {
mp.reset();
mp.setDataSource(mp3Path);
mp.prepare();
mp.start();
} catch (IOException e) {
Log.v(TAG, e.getMessage());
}
}
В начале класса устанавливается MediaPlayer, а затем почти всю работу выполняет предоставляемый Android API MediaPlayer, благодаря чему метод довольно ясен. Код сбрасывает MediaPlayer на случай, если кто-то еще одновременно проигрывает файл, или, если возникла ошибка, устанавливает источник данных (путь до файла, на котором щелкнул пользователь MP3); подготавливает проигрыватель и начинает воспроизведение MP3-файла. Вот и все, не считая блока catch (в нем мы просто выводим ошибку в файл журнала). Во врезке более подробно рассматриваются цикл жизни MediaPlayer и возможные состояния проигрывателя.
Но что делать проигрывателю, когда песня закончилась? Как насчет того, чтобы сразу перейти к следующей? Добавьте следующий код в конец блока try:
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mplayer) {
nextMp3();
}
});
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Опять же, API делает львиную долю работы, предоставляя метод setOnCompletionListener и класс OnCompletionListener. Нам остается написать метод nextMp3():
private void nextMp3() {
if (++currentPosition >= mp3List.size()) {
// No more songs! Reset currentPosition
currentPosition = 0;
} else {
playMp3(MEDIA_PATH + mp3List.get(currentPosition));
}
}
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Если MP3-файлы кончились, сверьтесь с размером списка и сбросьте currentPosition (и больше ничего не делайте; если вы хотите зациклить воспроизведение, можно перейти к проигрыванию первого MP3-файла). Иначе – вернитесь к методу playMP3 с путем до следующего MP3-файла.
Заметьте, что в операторе if мы употребили предварительный инкремент – это означает, что currentPosition увеличивается на единицу до проверки значения логического выражения. (В конструкции currentPosition++ >= mp3List.size() переменная увеличилась бы после этого, а нам такого не надо: мы проверяем, есть ли в списке следующая песня). Кроме того, когда мы дойдем до блока else, currentPosition уже увеличена на единицу. Важно четко понимать разницу между операторами пре- и постинкремента в Java.
Если на вашей SD-карте есть MP3-файлы, можно быстро проверить наш код – настроить устройство на USB-тестирование и установить программу прямо на него. Программу можно запустить и на эмуляторе, но тогда прежде всего понадобится установить SD-карту. Перейдите в каталог, где хранится карта, и скомандуйте
mksdcard -l 512MCard 512M mysdcard.img
Параметр -l необязателен – он задает метку диска для карты; размер и имя файла (с расширением .img) обязательны. После создания SD-карты запустите Android SDK/AVD Manager (android), выберите подходящее AVD (Android Virtual Device – виртуальное устройство Android) и измените его параметры, указав путь до SD-карты. Затем запустите AVD.
Ну, сейчас на карте нет MP3-файлов, и попробовав запустить программу, вы получите сообщение «На карте нет MP3-файлов [No MP3s on SD card]». Чтобы записать их на карту, воспользуйтесь командой adb push:
adb push getready.mp3 /sdcard/
(Чтобы эта команда сработала, эмулятор должен быть запущен.) Файлы можно добавить и через обозреватель файлов DDMS, но, по-моему, из командной строки это делается быстрее и удобнее.
Еще одно замечание по проверке: выбирайте MP3-файлы, запускаемые легко и быстро, для уверенности в том, что все работает должным образом.
ВРЕЗКА Скорая помощь
Для быстрого изменения стиля вашего приложения воспользуйтесь атрибутом android:theme элемента application в AndroidManifest.xml. Полный список доступных по умолчанию стилей можно найти на странице документации R.style.html.
Создаем несколько кнопок
На данном этапе нельзя понять, которая песня играет в данный момент; нет и кнопок паузы и перемещения между песнями. Давайте создадим три кнопки (воспроизведение/пауза, следующий трек, предыдущий трек) и текстовое поле для отображения песни, проигрываемой в данный момент.
Сейчас для упрощения работы переключим в list.xml представление расположения элементов с LinearLayout на RelativeLayout; прочие элементы оставим без изменений. Просто добавьте три кнопки и TextView:
<Button android:id=”@+id/playpause”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentBottom=”true”
android:text=”@string/playpause_button” />
<Button android:id=”@+id/next”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentBottom=”true”
android:layout_toRightOf=”@id/playpause”
android:text=”@string/next_button” />
<Button android:id=”@+id/prev”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_alignParentBottom=”true”
android:layout_toRightOf=”@id/next”
android:text=”@string/prev_button” />
<TextView android:id=”@+id/currentmp3”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:layout_above=”@id/playpause”
android:text=”” />
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Все кнопки выровнены по нижней части экрана (атрибут layout_alignParentBottom) и расположены одна за другой (атрибут layout_toRightOf). TextView находится над кнопками, но объявлять его нужно последним, иначе будет ошибка из-за ссылки на @id/playpause: ее нужно сперва объявить, а потом уж на нее ссылаться.
Вернемся к коду. Метод onCreate() вызывает метод setupButtons() – так код будет опрятнее. Все три кнопки настраиваются весьма похоже, в методе setupButtons(), и здесь я приведу код только для одной из них (код для других см. на DVD):
playpauseButton = (Button)this.findViewById(R.id.playpause);
playpauseButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mp.isPlaying()) {
pauseMp3();
} else {
playMp3(MEDIA_PATH + mp3List.get(currentPosition));
}
}
});
Опять же, большая часть работы с кнопками выполняется интерфейсом. Мы приостанавливаем или воспроизводим MP3-файл в зависимости от того, проигрывает ли MediaPlayer файл в данный момент или нет. Эту логику можно бы перенести в собственный метод playpause, но лучше разделять методы, особенно если вы захотите вызывать метод приостановки/воспроизведения из других частей кода.
У нас уже есть метод playMp3, но давайте отобразим в нем название песни, проигрываемой в данный момент, добавив следующую строку перед mp.start():
currentmp3.setText(mp3List.get(currentPosition));
Учтите, что она отображает имя файла песни, а не тэг MP3. Как получить метаданные файла, рассказано во врезке вверху справа.
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Метод pauseMp3 до смешного прост:
private void pauseMp3() {
mp.pause();
}
Методы nextMp3() и prevMp3() также довольно просты – это вызовы playMp3() с новым текущим положением. Перекомпилируйте и запустите программу; теперь в ней должно быть текстовое поле с текущей песней (пока вы ничего не запустили, оно будет пустым) и три кнопки для перемещения взад-вперед по списку (а также выбора песни с помощью сенсорного экрана).
Одна из проблем в том, что если нажать паузу, а затем воспроизведение, файл MP3 будет проигрываться с самого начала, а не с места остановки. Это легко исправить, добавив приватную булевскую переменную pause. Измените начало блока try в playMp3() следующим образом:
if (pause == false) {
mp.reset();
mp.setDataSource(mp3Path);
mp.prepare();
currentmp3.setText(mp3List.get(currentPosition));
}
mp.start();
pause = false;
и добавьте строку pause = true в pauseMp3(). Вам также понадобится добавить строку pause = false в prevMp3() и nextMp3(), иначе при нажатии кнопок «предыдущий/следующий трек» в состоянии паузы вместо запуска следующей песни продолжит проигрываться текущая. Вот и все. (При желании можете добавить кнопку «стоп» с методом mp.stop().)
Другая проблема – если выйти из приложения, песня продолжит играть. Если приложение закрыто осознанно, нужно обработать эту ситуацию, применив сервис и передав нужные параметры службе фонового управления процессами. Мы займемся этим через месяц, а пока реализуем onStop(), чтобы корректно освободить ресурсы. Это особенно важно при работе с таким ресурсоемким классом как MediaPlayer, иначе может привести к недостатку памяти и/или ресурсов процессора и «падению» системы. К счастью, API помогает нам прибраться за собой:
protected void onStop() {
mp.release();
mp = null;
super.onStop();
}
Учтите, что без вызова метода суперкласса вы получите ошибку времени выполнения. Этот метод освобождает MediaPlayer, и для перезапуска приложения придется создавать новый, в методе onResume():
protected void onResume() {
mp = new MediaPlayer();
updateMP3List();
super.onResume();
}
Обновлять список MP3-файлов не обязательно, но благодаря этому к списку прибавятся все новые файлы, появившиеся с момента последнего запуска приложения. Вздумав попробовать это сейчас, вы обнаружите, что при каждом перезапуске приложения список удваивается, так как он не очищается перед обновлением. Поэтому добавим строку в начало метода updateMP3List():
mp3List.clear();
Теперь наше приложение умеет проигрывать файлы, приостанавливать воспроизведение и перемещаться между песнями, и корректно освобождает ресурсы при выходе. На следующем уроке мы освоим запуск проигрывателя в качестве сервиса – его можно будет перевести в фоновый режим; мы узнаем, как с помощью MediaStore получить медиа-файлы и информацию о них, как установить листенер для обработки ошибок MediaPlayer и как работать с потоковым воспроизведением.