该文章主要针对 android 的音乐播放器软件进行简单的功能添加:播放、断点播放、停止、上一曲、下一曲、随机播放、显示当前播放歌曲(后续会为当前显示的播放添加动画);
软件开发流程:
1、先向内存卡导入音乐文件(文件的导入方法可以自己查找,文章类较多);
2、获取内存卡中的音乐文件;
3、将音乐文件存入集合中,便于调用,并将需要播放的文件显示在 ListView 中(点击 ListView 中的文件也可播放);
4、运用 MediaPlayer的方法实现播放、暂停、断点播放、连续播放文件;
5、通过调用写好的方法实现手动的下一曲、上一曲、随机播放、显示当前播放的音乐名;
package com.wangban.yzbbanban.v10;import android.content.Context;import android.content.Intent;import android.database.Cursor;import android.media.MediaPlayer;import android.os.Environment;import android.provider.MediaStore;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.ImageButton;import android.widget.ListView;import android.widget.RadioButton;import android.widget.TextView;import android.widget.Toast;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.List;import java.util.Locale;import java.util.Random;public class MainActivity extends AppCompatActivity {    //声明各个组件,集合    private List musics;    private ListView lvMusicList;    private ImageButton ibtnPlayOrPause;    private ImageButton ibtnNext;    private ImageButton ibtnprevious;    private ImageButton ibtnGetPosition;    private RadioButton rbtnPlayRandown;    private RadioButton rbtnPlaySequence;    private RadioButton rbtnPlaySingle;    private MusicAdapter adapter;    private TextView tvTip;    private Context context;    //声明 MediaPla    private MediaPlayer player;    // 记录的暂停时的播放位置    private int pausePosition;    // 当前播放的歌曲的索引    private int currentMusicIndex;    @Override    //主函数    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //设置布局为 activity_main        setContentView(R.layout.activity_main);        //初始化控件        initView();        //获取歌曲列表        loadData();        //列出列表        initListView();        //配置监听器        setListener();        //重置(设置 MediaPlayer必须步骤)        player.reset();    }    //设置各种监听器    private void setListener() {        InnerOnclickListener listener = new InnerOnclickListener();        //暂停播放        ibtnPlayOrPause.setOnClickListener(listener);        //下一首        ibtnNext.setOnClickListener(listener);        //上一首        ibtnprevious.setOnClickListener(listener);        //获取当前播放音乐        ibtnGetPosition.setOnClickListener(listener);        InnerItemOnCLickListener listener2 = new InnerItemOnCLickListener();        //给 ListView 添加点击(点击音乐即可播放)        lvMusicList.setOnItemClickListener(listener2);        // MediaPlay 自动播放(因为就一条,无需加变量)        player.setOnCompletionListener(new InnerOnCompletionListener());    }    //播放ListView 点击的音乐    private class InnerItemOnCLickListener implements AdapterView.OnItemClickListener {        @Override        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {            //获取点击的列表的中音乐的位置,赋值给当前播放音乐            currentMusicIndex = position;            //令暂停的进度为0(即为从头播放)            pausePosition = 0;            //播放            play();        }    }    //主要按钮的播放监听器    private class InnerOnclickListener implements View.OnClickListener {        @Override        public void onClick(View v) {            switch (v.getId()) {                // 播放/暂停按钮即执行的方法                case R.id.ibtn_playorpause:                    //当音乐在播放时                    if (player.isPlaying()) {                        //暂停                        pause();                    } else {                        //不在播放,则播放                        play();                    }                    break;                //下一首按钮即执行方法                case R.id.ibtn_next:                    next();                    break;                //上一首按钮即执行方法                case R.id.ibtn_previous:                    previous();                    break;                //获取当前播放音乐即执行方法                case R.id.ibtn_getposition:                    getPosition();                    break;            }        }    }    //单曲循环    private void single() {        currentMusicIndex++;        currentMusicIndex--;        pausePosition = 0;        play();    }    //随机播放方法    private void randown() {        currentMusicIndex = new Random().nextInt(musics.size());        Toast.makeText(MainActivity.this, "随机", Toast.LENGTH_SHORT).show();        pausePosition = 0;        play();    }    //列表循环    private void sequence() {        currentMusicIndex++;        if (currentMusicIndex >= musics.size()) {            currentMusicIndex = 0;        }        pausePosition = 0;        play();    }    //获取当前播放的音乐文件的名字,必先是在另一个布局中;    private void getPosition() {        //声明一个意图,用来切换布局和传递数据        Intent intent = new Intent();        //定义要传递的数据        String extra = musics.get(currentMusicIndex).getName() + "";        //传递数据        intent.putExtra("currentMusic", extra);        //切换布局        intent.setClass(MainActivity.this, Main2Activity.class);        //执行此系列活动        MainActivity.this.startActivity(intent);    }    //暂停    private void pause() {        //直接调用MediaPlay 中的暂停方法        player.pause();        //获取暂停的位置(音乐进度)        pausePosition = player.getCurrentPosition();        //切换为播放的按钮(按钮为android系统自带的按钮,可直接用)        ibtnPlayOrPause.setImageResource(android.R.drawable.ic_media_play);    }    //播放上一曲    private void previous() {        //判断是否为第一首歌曲,若为第一首歌曲,则播放最后一首        if (rbtnPlaySingle.isChecked()) {            single();        } else {            //当前音乐播放位置--(上一曲)            currentMusicIndex--;            if (currentMusicIndex <= 0) {                Toast.makeText(MainActivity.this, "已经是第一首了", Toast.LENGTH_SHORT).show();                return;            } else {                //音乐进度置为0                pausePosition = 0;                //播放                play();            }        }    }    //播放下一曲(与上一曲类似)    private void next() {        if (rbtnPlayRandown.isChecked()) {            randown();        } else if (rbtnPlaySingle.isChecked()) {            single();        } else if (rbtnPlaySequence.isChecked()) {            sequence();        } else {            currentMusicIndex++;            if (currentMusicIndex >= musics.size()) {                Toast.makeText(MainActivity.this, "已经是最后一首了", Toast.LENGTH_SHORT).show();                return;            } else {                pausePosition = 0;                play();            }        }    }    //播放音乐    private void play() {        //重置        player.reset();        try {            //设置音乐文件来源            player.setDataSource(musics.get(currentMusicIndex).getPath());            //准备(缓冲文件)            player.prepare();            //将进度设置到“音乐进度”            player.seekTo(pausePosition);            //获取音乐进度            player.getCurrentPosition();            //播放开始            player.start();            //用当前界面的 TextView显示当前播放的音乐            tvTip.setText(musics.get(currentMusicIndex).getName() + "");            //设置按钮图片为暂停图标            ibtnPlayOrPause.setImageResource(android.R.drawable.ic_media_pause);        } catch (IOException e) {            e.printStackTrace();        }    }    private final class InnerOnCompletionListener implements MediaPlayer.OnCompletionListener {        @Override        public void onCompletion(MediaPlayer mp) {            next();        }    }    private void initListView() {        adapter = new MusicAdapter(getApplicationContext(), musics);        lvMusicList.setAdapter(adapter);    }    private void loadData() {        //获取音乐文件的内容        Cursor cursor = context.getContentResolver().query(                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,                MediaStore.Audio.Media.DEFAULT_SORT_ORDER);        // 获取歌曲列表        musics = new ArrayList<>();        // 1. 检查sdcard是否可用        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {            // 2. 获取sdcard下Music文件夹的File对象            File musicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);            // 3. 检查Music文件夹是否存在            if (musicDir.exists()) {                // 4. 通过File类的listFiles()方法,获取Music文件夹下所有子级File对象                File[] files = musicDir.listFiles();                // 5. 检查获取到的File列表是否有效(数组是否为null,或数组长度是否为0)                if (files != null && files.length > 0) {                    // 6. 遍历File列表                    for (int i = 0; i < files.length; i++) {                        //下一个文件                        cursor.moveToNext();                        //获取艺术家内容                        String artist = cursor.getString(cursor                                .getColumnIndex(MediaStore.Audio.Media.ARTIST));                        // 6.1. 通过File类的isFile()方法,检查是否是文件                        if (files[i].isFile()) {                            // 6.2. 通过File类的getName()方法获取文件名,                            // 结合String类的endsWith()方法,检查是否是mp3文件                            String fileName = files[i].getName();                            if (fileName.toUpperCase(Locale.CHINA).endsWith(".MP3")) {                                // 6.3. 创建Music对象,并封装必要的属性                                Music music = new Music();                                music.setName(fileName.substring(0, fileName.length() - 4));                                music.setArtist(artist);                                music.setPath(files[i].getAbsolutePath());                                // 6.4. 将新创建的Music对象添加到集合中                                musics.add(music);                            }                        }                    }                }            }        }    }    //初始化控件级布局文件等    private void initView() {        player = new MediaPlayer();        lvMusicList = (ListView) findViewById(R.id.lv_musiclist);        ibtnPlayOrPause = (ImageButton) findViewById(R.id.ibtn_playorpause);        ibtnNext = (ImageButton) findViewById(R.id.ibtn_next);        ibtnprevious = (ImageButton) findViewById(R.id.ibtn_previous);        ibtnGetPosition = (ImageButton) findViewById(R.id.ibtn_getposition);        rbtnPlayRandown = (RadioButton) findViewById(R.id.rbtn_playrandowm);        rbtnPlaySequence = (RadioButton) findViewById(R.id.rbtn_playsequence);        rbtnPlaySingle = (RadioButton) findViewById(R.id.rbtn_playsingle);        tvTip = (TextView) findViewById(R.id.tv_musictip);        context = MainActivity.this;    }}

   
package com.wangban.yzbbanban.v10;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.TextView;//实现显示当前播放的音乐public class Main2Activity extends AppCompatActivity {    private TextView tvCurrentMusic;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //设置当前布局为activity_main2        setContentView(R.layout.activity_main2);        //声明 TextView 控件        tvCurrentMusic = (TextView) findViewById(R.id.tv_current_music);        //获取主程序传出的“当前播放文件名字”的值        Intent intent= this.getIntent();        String stringValue=intent.getStringExtra("currentMusic");        tvCurrentMusic.setText(stringValue);    }}

package com.wangban.yzbbanban.v10;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import java.util.List;//集合:显示音乐文件的名称、路径,显示在 ListView 中public class MusicAdapter extends BaseAdapter{    private Context context;    private List musics;    public MusicAdapter(Context context, List musics) {        this.context = context;        this.musics = musics;    }    @Override    public int getCount() {        return musics.size();    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        //获取当个文件的位置        Music music=musics.get(position);        //将文件布置在模板中        if (convertView==null){            LayoutInflater inflater=LayoutInflater.from(context);            convertView=inflater.inflate(R.layout.music_item,null);        }        //初始化控件        TextView tvName= (TextView) convertView.findViewById(R.id.tv_music_title);        TextView tvArtist= (TextView) convertView.findViewById(R.id.tv_music_path);        //TextView tvPath= (TextView) convertView.findViewById(R.id.tv_music_path);        //显示文件内容        //显示歌曲名        tvName.setText(music.getName());        //tvPath.setText(music.getPath());        //显示艺术家名字        tvArtist.setText(music.getArtist());        return convertView;    }    @Override    public Object getItem(int position) {        return null;    }    @Override    public long getItemId(int position) {        return 0;    }}

package com.wangban.yzbbanban.v10;//Music 类型文件,用于集合musics,声明一个类型,获取集合中的名字、路径public class Music {    //name 类型    private String name;    //path 类型    private String path;    //获取艺术家    private String artist;    public String getArtist() {        return artist;    }    public void setArtist(String artist) {        this.artist = artist;    }    public String getPath() {        return path;    }    public void setPath(String path) {        this.path = path;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String toString() {        return "Music{" +                "name='" + name + '\'' +                ", path='" + path + '\'' +                '}';    }}

<?xml version="1.0" encoding="utf-8"?>            

<?xml version="1.0" encoding="utf-8"?>                                                                                                            

<?xml version="1.0" encoding="utf-8"?>            
//随机图标的选择
<?xml version="1.0" encoding="utf-8"?>        
//顺序播放的图标的选择

<?xml version="1.0" encoding="utf-8"?>        
//单曲循环的图标的选择

<?xml version="1.0" encoding="utf-8"?>        




更多相关文章

  1. Android(安卓)Q分区存储权限变更及适配
  2. Android中利用ZipEntry漏洞实现免root写恶意文件到应用的沙盒中
  3. Android之使用SoundPool播放一小段音频,实现猜歌的功能
  4. iOS /Android多渠道打包方案、重签名方案
  5. Android笔记之开发中处理异常并写入本地log文件
  6. 基于Android的小巫新闻客户端开发---显示新闻详细内容业务逻辑实
  7. Android(安卓)Studio初使用之百度地图初使用(一)--配置
  8. 【Android7.1.2源码解析系列】Android编译系统翻译------Android
  9. Android(安卓)Studio中布局文件(如activity_main.xml)设计视图&代

随机推荐

  1. AIDL使用详解及原理
  2. 关于在Mac上使用真机进行Android程序调试
  3. AndServer+Service打造Android服务器实现
  4. Android(安卓)GPS坐标 画路线
  5. Android(安卓)实现图片缓存异步加载框架
  6. Android(安卓)命名方式
  7. android studio下百度地图sdk的初体验
  8. Android的网络应用-使用HttpURLConnectio
  9. Android(安卓)HAL 是如何被调用的
  10. Android基本功:事件处理