Статьи

Создание музыкального проигрывателя на Android: настройка проекта

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

Если вы ищете быстрое решение, на Envato Market есть отличная коллекция шаблонов приложений для Android .

В частности, этот шаблон приложения для Android Music Player — отличный способ начать создавать собственное приложение. «Lite Music» — это шаблон приложения премиум-плеера в Android с простым и элегантным интерфейсом.

Создание музыкального проигрывателя будет включать использование класса ContentResolver для извлечения треков на устройстве, класса MediaPlayer для воспроизведения звука и класса MediaController для управления воспроизведением. Мы также будем использовать экземпляр Service для воспроизведения звука, когда пользователь не взаимодействует напрямую с приложением. Вы должны быть в состоянии завершить эту серию, если вы являетесь средним разработчиком Android, поэтому, если вы уже создали несколько приложений, то эта серия не должна быть проблемой для вас. Вот предварительный просмотр финального приложения:

Музыкальный проигрыватель Android

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

Создайте новый проект 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» />

Измените имя пакета в соответствии со своим собственным и измените имя класса, если хотите.

Откройте основной файл макета проекта и замените его содержимое следующим макетом:

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 . Два элемента относятся к чертежным файлам. Создайте свой собственный или используйте эти два изображения для начала:

Музыкальный проигрыватель Android Случайная кнопка
Кнопка завершения музыкального проигрывателя Android

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

Кнопка воспроизведения музыкального проигрывателя Android

Код будет ссылаться на изображения, используя имена rand , end и play, поэтому убедитесь, что вы используете одинаковые имена файлов. Скопируйте изображения в папку (и) drawables вашего проекта. Мы осуществим действия позже.

Давайте запросим на устройстве пользователя аудиофайлы. Сначала добавьте новый класс в ваш проект, назвав его 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;}

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

Откройте основной класс 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();

Теперь мы можем отобразить список песен в пользовательском интерфейсе. В методе 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 , сортирующего песни по названию.

Давайте определим макет для представления каждой песни в списке. Добавьте новый файл в папку 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 чтобы реагировать на нажатия пользователя на песни в списке, воспроизводя песню, представленную элементом списка, который был нажат.

Мы будем использовать 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 .

Вернувшись в основной класс Activity , в методе onCreate после сортировки списка создайте новый экземпляр класса Adapter и установите его в ListView :

1
2
SongAdapter songAdt = new SongAdapter(this, songList);
songView.setAdapter(songAdt);

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

Теперь мы настроили приложение для чтения песен с пользовательского устройства. В следующей части мы начнем воспроизведение, когда пользователь выберет песню, используя класс MediaPlayer . Мы реализуем воспроизведение с использованием класса Service чтобы оно продолжалось при взаимодействии пользователя с другими приложениями. Наконец, мы будем использовать класс MediaController чтобы предоставить пользователю контроль над воспроизведением.

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

Разработчики Android на Envato Studio
Разработчики Android на Envato Studio