Платформа Android предоставляет ресурсы для обработки воспроизведения мультимедиа, которые ваши приложения могут использовать для создания интерфейса между пользователем и его музыкальными файлами. В этом уроке мы создадим приложение для основного музыкального плеера для Android. Приложение представит список песен на пользовательском устройстве, чтобы пользователь мог выбирать песни для воспроизведения. Приложение также представит элементы управления для взаимодействия с воспроизведением и продолжит воспроизведение, когда пользователь отходит от приложения, с уведомлением, отображаемым по истечении воспроизведения.
Ищете быстрое решение?
Если вы ищете быстрое решение, на Envato Market есть отличная коллекция шаблонов приложений для Android .
В частности, этот шаблон приложения для Android Music Player — отличный способ начать создавать собственное приложение. «Lite Music» — это шаблон приложения премиум-плеера в Android с простым и элегантным интерфейсом.
Вступление
Создание музыкального проигрывателя будет включать использование класса ContentResolver
для извлечения треков на устройстве, класса MediaPlayer
для воспроизведения звука и класса MediaController
для управления воспроизведением. Мы также будем использовать экземпляр Service
для воспроизведения звука, когда пользователь не взаимодействует напрямую с приложением. Вы должны быть в состоянии завершить эту серию, если вы являетесь средним разработчиком Android, поэтому, если вы уже создали несколько приложений, то эта серия не должна быть проблемой для вас. Вот предварительный просмотр финального приложения:
В этом уроке мы создадим приложение и ContentResolver
на аудиоустройстве пользовательское устройство, используя ContentResolver
и Cursor
. В следующей части мы будем использовать экземпляр Adapter
для представления песен в виде списка, начиная воспроизведение, когда пользователь нажимает на элемент из списка. В последней части этой серии мы будем использовать класс MediaController
чтобы предоставить пользователю контроль над воспроизведением, реализовать функции для перехода вперед и назад и включить функцию перемешивания. После этой серии мы рассмотрим другие аспекты воспроизведения мультимедиа, которые могут улучшить приложение, такие как обработка аудиофокуса, представление мультимедийных файлов различными способами и воспроизведение потокового мультимедиа.
1. Создайте и настройте новый проект
Шаг 1
Создайте новый проект Android. Если вы используете Eclipse, позвольте IDE (Integrated Development Environment) создать для вас основной класс Activity
и файл макета. Для некоторого кода, который мы используем в этой серии, вам потребуется минимальный уровень API 16, поэтому вам потребуется предпринять дополнительные шаги для поддержки более старых версий. Как только ваш проект создан, откройте файл Manifest проекта. Внутри элемента manifest
добавьте следующее разрешение:
1
|
<uses-permission android:name=»android.permission.WAKE_LOCK» />
|
Мы будем использовать это разрешение для продолжения воспроизведения музыки, когда устройство пользователя будет бездействовать. Ваш манифест уже должен содержать элемент для вашего основного класса Activity
. Добавьте следующие атрибуты к элементу screenOrientation
чтобы установить screenOrientation
и launchMode
:
1
2
3
4
5
|
<activity
android:name=»com.example.musicplayer.MainActivity»
android:label=»@string/app_name»
android:launchMode=»singleTop»
android:screenOrientation=»portrait» >
|
Мы будем придерживаться портретной ориентации для простоты. Режим launchMode
поможет процессу возврата к приложению после ухода от него. Мы отобразим уведомление, указывающее, какая песня воспроизводится в данный момент, и, нажав на уведомление, пользователь вернется в приложение. Мы также собираемся использовать класс Service
для воспроизведения музыки. Добавьте следующую строку в манифест проекта внутри элемента application
и после элемента activity
:
1
|
<service android:name=»com.example.musicplayer.MusicService» />
|
Измените имя пакета в соответствии со своим собственным и измените имя класса, если хотите.
Шаг 2
Откройте основной файл макета проекта и замените его содержимое следующим макетом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
<LinearLayout xmlns:android=»https://schemas.android.com/apk/res/android»
xmlns:tools=»http://schemas.android.com/tools»
android:layout_width=»fill_parent»
android:layout_height=»fill_parent»
android:orientation=»vertical»
android:background=»#FF330000″
tools:context=».MainActivity» >
<ListView
android:id=»@+id/song_list»
android:layout_width=»fill_parent»
android:layout_height=»wrap_content» >
</ListView>
</LinearLayout>
|
Обязательно измените атрибут tools: context, если ваш основной класс Activity
назван по-другому. Макет включает в себя ListView
в котором мы представим список песен.
Мы собираемся включить два пункта меню для переключения функции перемешивания и для выхода из приложения. Откройте файл главного меню ( res / menu / main.xml ) и замените его содержимое следующим:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
<menu xmlns:android=»http://schemas.android.com/apk/res/android» >
<item
android:id=»@+id/action_shuffle»
android:icon=»@drawable/rand»
android:orderInCategory=»1″
android:showAsAction=»always»
android:title=»Shuffle»/>
<item
android:id=»@+id/action_end»
android:icon=»@drawable/end»
android:orderInCategory=»2″
android:showAsAction=»always»
android:title=»End»/>
</menu>
|
При желании вы можете сохранить строки заголовка в файле res / values / strings.xml . Два элемента относятся к чертежным файлам. Создайте свой собственный или используйте эти два изображения для начала:
Мы также будем использовать значок для отображения в уведомлении о воспроизведении. Создайте его сейчас или используйте тот, что ниже:
Код будет ссылаться на изображения, используя имена rand , end и play, поэтому убедитесь, что вы используете одинаковые имена файлов. Скопируйте изображения в папку (и) drawables вашего проекта. Мы осуществим действия позже.
2. Запрос устройства для песен
Шаг 1
Давайте запросим на устройстве пользователя аудиофайлы. Сначала добавьте новый класс в ваш проект, назвав его Song
. Мы будем использовать этот класс для моделирования данных для одного аудиофайла. Внутри объявления класса добавьте три переменные экземпляра для данных, которые мы хотим сохранить для каждой дорожки:
1
2
3
|
private long id;
private String title;
private String artist;
|
Затем добавьте метод конструктора, в котором мы создаем экземпляры переменных экземпляра:
1
2
3
4
5
|
public Song(long songID, String songTitle, String songArtist) {
id=songID;
title=songTitle;
artist=songArtist;
}
|
Наконец, добавьте методы get для переменных экземпляра:
1
2
3
|
public long getID(){return id;}
public String getTitle(){return title;}
public String getArtist(){return artist;}
|
Если вы планируете использовать больше информации о треке, вы можете добавить дополнительные переменные экземпляра в класс.
Шаг 2
Откройте основной класс Activity
и добавьте следующий импорт:
1
2
3
4
5
6
7
|
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import android.net.Uri;
import android.content.ContentResolver;
import android.database.Cursor;
import android.widget.ListView;
|
Объявите следующие переменные экземпляра перед методом onCreate
:
1
2
|
private ArrayList<Song> songList;
private ListView songView;
|
Мы будем хранить песни в списке и отображать их в экземпляре ListView
в основном макете. В onCreate
после настройки представления содержимого onCreate
экземпляр ListView
используя идентификатор, который мы дали ему в основном макете:
1
|
songView = (ListView)findViewById(R.id.song_list);
|
Создайте список, как показано ниже:
1
|
songList = new ArrayList<Song>();
|
Далее, в объявлении основного класса Activity
, после существующих методов, создайте вспомогательный метод для получения информации об аудиофайле:
1
2
3
|
public void getSongList() {
//retrieve song info
}
|
Внутри этого метода создайте экземпляр ContentResolver
, ContentResolver
URI для внешних музыкальных файлов и создайте экземпляр Cursor
используя экземпляр ContentResolver
для запроса музыкальных файлов:
1
2
3
|
ContentResolver musicResolver = getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
|
Теперь мы можем перебрать результаты, сначала проверив, что у нас есть действительные данные:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
if(musicCursor!=null && musicCursor.moveToFirst()){
//get columns
int titleColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.ARTIST);
//add songs to list
do {
long thisId = musicCursor.getLong(idColumn);
String thisTitle = musicCursor.getString(titleColumn);
String thisArtist = musicCursor.getString(artistColumn);
songList.add(new Song(thisId, thisTitle, thisArtist));
}
while (musicCursor.moveToNext());
}
|
Сначала мы извлекаем индексы столбцов для элементов данных, которые нас интересуют для каждой песни, затем мы используем их для создания нового объекта Song
и добавления его в список, прежде чем продолжить циклический просмотр результатов.
Вернувшись в onCreate
, после кода, который мы добавили, вызовите этот новый метод:
1
|
getSongList();
|
3. Показать песни
Шаг 1
Теперь мы можем отобразить список песен в пользовательском интерфейсе. В методе onCreate
, после вызова вспомогательного метода, который мы создали минуту назад, давайте отсортируем данные так, чтобы песни были представлены в алфавитном порядке:
1
2
3
4
5
|
Collections.sort(songList, new Comparator<Song>(){
public int compare(Song a, Song b){
return a.getTitle().compareTo(b.getTitle());
}
});
|
Мы используем переменную title
в классе Song
, используя добавленные нами методы get , для реализации метода compare
, сортирующего песни по названию.
Шаг 2
Давайте определим макет для представления каждой песни в списке. Добавьте новый файл в папку res / layout вашего проекта, назвав его song.xml и введя следующее:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<LinearLayout xmlns:android=»http://schemas.android.com/apk/res/android»
xmlns:tools=»http://schemas.android.com/tools»
android:layout_width=»fill_parent»
android:layout_height=»wrap_content»
android:onClick=»songPicked»
android:orientation=»vertical»
android:padding=»5dp» >
<TextView
android:id=»@+id/song_title»
android:layout_width=»fill_parent»
android:layout_height=»wrap_content»
android:textColor=»#FFFFFF99″
android:textSize=»20sp»
android:textStyle=»bold» />
<TextView
android:id=»@+id/song_artist»
android:layout_width=»fill_parent»
android:layout_height=»wrap_content»
android:textColor=»#FFFFFF99″
android:textSize=»18sp» />
</LinearLayout>
|
Не стесняйтесь вносить изменения в макет в соответствии с вашими предпочтениями. Каждая песня в списке будет представлена текстовыми строками заголовка и исполнителя, поэтому мы будем использовать TextViews
для отображения этих данных. Обратите внимание, что открывающий тег LinearLayout
содержит атрибут LinearLayout
. Мы будем использовать этот метод в основном классе Activity
чтобы реагировать на нажатия пользователя на песни в списке, воспроизводя песню, представленную элементом списка, который был нажат.
Шаг 3
Мы будем использовать Adapter
для отображения песен в виде списка. Добавьте новый класс в свое приложение, назвав его SongAdapter или другим именем по вашему выбору. При создании класса присвойте ему суперкласс android.widget.BaseAdapter
. Затмение должно вставить следующую схему:
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
|
public class SongAdapter extends BaseAdapter {
@Override
public int getCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
// TODO Auto-generated method stub
return null;
}
}
|
Вам нужно будет добавить следующий импорт:
1
2
3
4
5
|
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.TextView;
|
Внутри объявления класса объявите следующие переменные экземпляра:
1
2
|
private ArrayList<Song> songs;
private LayoutInflater songInf;
|
Мы передадим список песен из основного класса Activity
и используем LayoutInflater
для сопоставления строк заголовка и исполнителя с TextViews
в макете песни, который мы создали.
После переменных экземпляра передайте адаптеру метод конструктора для их создания:
1
2
3
4
|
public SongAdapter(Context c, ArrayList<Song> theSongs){
songs=theSongs;
songInf=LayoutInflater.from(c);
}
|
Измените содержимое метода getCount
чтобы получить размер списка:
1
2
3
4
|
@Override
public int getCount() {
return songs.size();
}
|
Вы можете оставить методы getItem
и getItemId
. Обновите реализацию метода getView
как показано ниже:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//map to song layout
LinearLayout songLay = (LinearLayout)songInf.inflate
(R.layout.song, parent, false);
//get title and artist views
TextView songView = (TextView)songLay.findViewById(R.id.song_title);
TextView artistView = (TextView)songLay.findViewById(R.id.song_artist);
//get song using position
Song currSong = songs.get(position);
//get title and artist strings
songView.setText(currSong.getTitle());
artistView.setText(currSong.getArtist());
//set position as tag
songLay.setTag(position);
return songLay;
}
|
Мы устанавливаем название и текст исполнителя, извлекая правильный экземпляр Song
из списка, используя индекс позиции, сопоставляя эти строки с представлениями, которые мы добавили в файл макета песни. Мы также устанавливаем позицию в качестве тега просмотра, что позволит нам воспроизводить правильную песню, когда пользователь щелкает элемент в списке. Помните, что файл макета song.xml содержит атрибут onClick . Мы будем использовать метод, перечисленный там, чтобы получить тег в Activity
.
Шаг 3
Вернувшись в основной класс Activity
, в методе onCreate
после сортировки списка создайте новый экземпляр класса Adapter
и установите его в ListView
:
1
2
|
SongAdapter songAdt = new SongAdapter(this, songList);
songView.setAdapter(songAdt);
|
Когда вы запускаете приложение, оно должно представить список песен на устройстве, щелкнув по ним, вы вызовете исключение в данный момент, но мы реализуем обработчик щелчков в следующем уроке.
Вывод
Теперь мы настроили приложение для чтения песен с пользовательского устройства. В следующей части мы начнем воспроизведение, когда пользователь выберет песню, используя класс MediaPlayer
. Мы реализуем воспроизведение с использованием класса Service
чтобы оно продолжалось при взаимодействии пользователя с другими приложениями. Наконец, мы будем использовать класс MediaController
чтобы предоставить пользователю контроль над воспроизведением.
Если вам когда-нибудь понадобится дополнительная помощь в ваших проектах по разработке приложений для Android, вы можете найти опытных разработчиков Android в Envato Studio, которые помогут вам во всем — от дизайна пользовательского интерфейса до создания собственного приложения для Android .