在开发音乐播放器时除了网络音乐我们很多时候需要读取本地的音频文件,并且把歌曲的名字、歌手、时间等内容显示出来,但是本地储存的格式是不规范的,所以我们在把音频文件从本地获取出来之后还需要进行格式的转换
效果图:
步骤一:创建一个歌曲类,定义变量,这些变量用来储存需要获取的内容
package com.contentprovide.liuliu.get_demo2;
/**
* Created by liuliu on 2018/1/14.
*/
public class Song {
public String song;//歌曲名
public String singer;//歌手
public long size;//歌曲所占空间大小
public int duration;//歌曲时间长度
public String path;//歌曲地址
}
步骤二:定义一个工具类,在这个类中获取音频文件,并且对歌曲名、歌手和时间等进行格式规范
package com.contentprovide.liuliu.get_demo2;
import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore;
import java.util.ArrayList;
import java.util.List;
/**
* Created by liuliu on 2018/1/14.
*/
//工具类
public class Utils {
//定义一个集合,存放从本地读取到的内容
public static List list;
public static Song song;
public static List getmusic(Context context) {
list = new ArrayList<>();
Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
, null, null, null, MediaStore.Audio.AudioColumns.IS_MUSIC);
if (cursor != null) {
while (cursor.moveToNext()) {
song = new Song();
song.song = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
song.singer = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
song.path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
song.duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
song.size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
// 把歌曲名字和歌手切割开
if (song.size > 1000 * 800) {
if (song.song.contains("-")) {
String[] str = song.song.split("-");
song.singer = str[0];
song.song = str[1];
}
list.add(song);
}
}
}
cursor.close();
return list;
}
// 转换歌曲时间的格式
public static String formatTime(int time) {
if (time / 1000 % 60 < 10) {
String tt = time / 1000 / 60 + ":0" + time / 1000 % 60;
return tt;
} else {
String tt = time / 1000 / 60 + ":" + time / 1000 % 60;
return tt;
}
}
}
步骤三:在主布局文件activity_main.xml中放一个ListView显示获取到的音频文件
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:id="@+id/mylist"
android:layout_width="match_parent"
android:layout_height="match_parent">
步骤四:定义一个布局text.xml用于展示每一个音频文件的内容,并把这个布局添加到主布局文件中的ListView中去,在这里需要写一个适配器把内容映射到ListView中
text.xml布局:
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/t_postion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
/>
android:id="@+id/t_song"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
/>
android:id="@+id/t_singer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
/>
android:id="@+id/t_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Java代码:
package com.contentprovide.liuliu.get_demo2;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
ListView mylist;
List list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mylist = (ListView) findViewById(R.id.mylist);
list = new ArrayList<>();
list = Utils.getmusic(this);
MyAdapter myAdapter = new MyAdapter(this, list);
mylist.setAdapter(myAdapter);
}
class MyAdapter extends BaseAdapter {
Context context;
List list;
public MyAdapter(MainActivity mainActivity, List list) {
this.context = mainActivity;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return list.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
Myholder myholder;
if (view == null) {
myholder = new Myholder();
view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.text, null);
myholder.t_position = view.findViewById(R.id.t_postion);
myholder.t_song = view.findViewById(R.id.t_song);
myholder.t_singer = view.findViewById(R.id.t_singer);
myholder.t_duration = view.findViewById(R.id.t_duration);
view.setTag(myholder);
} else {
myholder = (Myholder) view.getTag();
}
myholder.t_song.setText(list.get(i).song.toString());
myholder.t_singer.setText(list.get(i).singer.toString());
String time = Utils.formatTime(list.get(i).duration);
myholder.t_duration.setText(time);
myholder.t_position.setText(i + 1 + "");
return view;
}
class Myholder {
TextView t_position, t_song, t_singer, t_duration;
}
}
}
如果本地资源成功显示之后需要实现另外一个功能,点击每首歌对应的列表项,歌曲会进行播放
步骤一:在MainActivity.java中定义一个方法play()进行音频的处理
public void play(String path) {
try {
// 重置音频文件,防止多次点击会报错
mediaPlayer.reset();
// 调用方法传进播放地址
mediaPlayer.setDataSource(path);
// 异步准备资源,防止卡顿
mediaPlayer.prepareAsync();
// 调用音频的监听方法,音频准备完毕后响应该方法进行音乐播放
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
步骤二:在MainActivity.java中的onCreat()方法中调用刚才定义的play方法,并且将获取到的歌曲地址传递给这个方法
// 给ListView添加点击事件,实现点击哪首音乐就进行播放
mylist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
String p = list.get(i).path;//获得歌曲的地址
play(p);
}
});