Android音乐播放器

Android音乐播放器

目录

使用Android多媒体API Media Player来创建一个音乐播放器,要求来电停止播放,电话挂断后继续播放。

搭建整体框架

  1. 完成app界面的设计
  2. 定义onClick事件的方法
  3. 在MainActivity里面获取文本输入框以此来获得本地音乐文件的名字。
  4. 第2步创建的方法中对点击button进行switch case判断,这里设置了4个button:
    a) 播放(btnPlay)
    b) 暂停/继续(btnPause)
    c) 重播(btnReplay)
    d) 停止(btnStop)
  5. 将音乐文件放在SD卡的根目录,并创建File对象,获取文件的绝对路径:
File audioFile=new File(Environment.getExteralStorageDirectory(),filename);
String path=audioFile.getAbsolutePath();

至此完成了整体应用框架的编写。

功能实现

在Button的onClick方法中对v.getId()进行switch case判断,一共有4种情况:
- R.id.btnPlay
- R.id.btnPause
- R.id.btnReplay
- R.id.btnStop
在进一步编写4中情况的具体业务逻辑时,需要一些准备工作。
首先在MainActivity的onCreate方法中已经创建了Android的多媒体对象:

MediaPlayer mediaPlayer=new MediaPlayer()

编写play(position)方法,表示在从特定的位置开始播放。
具体步骤将在代码的注释中体现:

        // mediaPlay
        try {
            mediaPlayer.reset();// 把各项参数恢复到初始状态
            mediaPlayer.setDataSource(filePath);//设置数据源
            mediaPlayer.prepare();//缓冲数据
            mediaPlayer.setOnPreparedListener(new PrepareListener(position));
            //完成对缓冲数据的监听
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //内部类用于实现对缓冲事件的监听
    private final class PrepareListener implements OnPreparedListener {
        private int position;
        public PrepareListener(int position) {
            this.position=position;
        }

        @Override
        public void onPrepared(MediaPlayer mp) {//数据缓冲完后会执行该方法
            mediaPlayer.start();//播放媒体文件
            if(position>0){
                mediaPlayer.seekTo(position); //从position的位置开始播放
            }
        }
    }

这里需要注意的就是编写内部类实现OnpreparedListener接口完成对数据缓冲的监听,一旦缓冲完成,我们就开始播放媒体文件。
有了play(position)方法,在4个button的条件逻辑就比较简单了,代码如下:

public void mediaPlay(View v) {
        String filename = editTextFilename.getText().toString();
        switch (v.getId()) {
        case R.id.btnPlay:
            File audioFile = new File(
                    Environment.getExternalStorageDirectory(), filename);
            if (audioFile.exists()) {
                filePath = audioFile.getAbsolutePath();
                play(0);
                // play
            } else {
                filePath = null;
                Toast.makeText(getApplicationContext(), "文件不存在",
                        Toast.LENGTH_LONG).show();
            }
            break;
        case R.id.btnPause:
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();
                isPause = true;
                ((Button) v).setText(R.string.btnContinue);
            } else {
                if (isPause) {
                    mediaPlayer.start();
                    //play(position);
                    isPause = false;
                    ((Button) v).setText(R.string.btnPause);
                }
            }
            break;
        case R.id.btnReplay:
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.seekTo(0);
            } else {
                if (filePath != null) {
                    play(0);
                }
            }
            break;
        case R.id.btnStop:
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
            }
            break;
        default:
            break;
        }
    }

电话事件监听

首先不要忘了在AndroidMenifest.xml文件中添加权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

在MainActivity中使用TelephonyManager完成对电话事件的监听,这里与上述创建监听准备数据类似,创建继承PhoneStateListener的内部类,通过重写onCallStateChanged方法完成对电话事件的监听:

//来电:
TelephonyManager.CALL_STATE_RINGING
//挂断后:
TelephonyManager.CALL_STATE_IDLE

代码:

private final class MyPhoneListener extends PhoneStateListener {

        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            switch (state) {
            case TelephonyManager.CALL_STATE_RINGING:
                if (mediaPlayer.isPlaying()) {
                    position = mediaPlayer.getCurrentPosition();
                    mediaPlayer.stop();
                }
                break;
            case TelephonyManager.CALL_STATE_IDLE:
                if (position > 0 && filePath != null) {
                    play(position);
                    //mediaPlayer.seekTo(position);
                    position = 0;
                }
                break;
            default:
                break;
            }
        }

    }

PS:至此完成了音乐播放器的编写,在这里,我们将音乐播放服务放到了MainActivity.java中。一般情况下我们在MainActivity.java中完成功能框架,在Service组件中完成功能,有时间会将这部分补上。

附录代码

MainActivity.java

public class MainActivity extends Activity {
    private EditText editTextFilename;
    private String filePath;
    private MediaPlayer mediaPlayer;
    private boolean isPause;
    private int position;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editTextFilename = (EditText) this.findViewById(R.id.editTextFilename);
        mediaPlayer = new MediaPlayer();
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(new MyPhoneListener(),
                PhoneStateListener.LISTEN_CALL_STATE);
    }

    private final class MyPhoneListener extends PhoneStateListener {

        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            switch (state) {
            case TelephonyManager.CALL_STATE_RINGING:
                if (mediaPlayer.isPlaying()) {
                    position = mediaPlayer.getCurrentPosition();
                    mediaPlayer.stop();
                }
                break;
            case TelephonyManager.CALL_STATE_IDLE:
                if (position > 0 && filePath != null) {
                    play(position);
                    //mediaPlayer.seekTo(position);
                    position = 0;
                }
                break;
            default:
                break;
            }
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    // 这种方式只要Activity被覆盖就会停止音乐

    // @Override
    // protected void onPause() {// activity完全被覆盖的时候
    // if (mediaPlayer.isPlaying()) {
    // position = mediaPlayer.getCurrentPosition();
    // mediaPlayer.stop();
    // }
    // super.onPause();
    // }

    // @Override
    // protected void onResume() {
    // if (position > 0 && filePath != null) {
    // play();
    // mediaPlayer.seekTo(position);
    // position = 0;
    // }
    // super.onResume();
    // }

    @Override
    protected void onDestroy() {
        mediaPlayer.release();
        mediaPlayer = null;
        super.onDestroy();
    }

    public void mediaPlay(View v) {
        String filename = editTextFilename.getText().toString();
        switch (v.getId()) {
        case R.id.btnPlay:
            File audioFile = new File(
                    Environment.getExternalStorageDirectory(), filename);
            if (audioFile.exists()) {
                filePath = audioFile.getAbsolutePath();
                play(0);
                // play
            } else {
                filePath = null;
                Toast.makeText(getApplicationContext(), "文件不存在",
                        Toast.LENGTH_LONG).show();
            }
            break;
        case R.id.btnPause:
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();
                isPause = true;
                ((Button) v).setText(R.string.btnContinue);
            } else {
                if (isPause) {
                    mediaPlayer.start();
                    //play(position);
                    isPause = false;
                    ((Button) v).setText(R.string.btnPause);
                }
            }
            break;
        case R.id.btnReplay:
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.seekTo(0);
            } else {
                if (filePath != null) {
                    play(0);
                }
            }
            break;
        case R.id.btnStop:
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
            }
            break;
        default:
            break;
        }
    }

    private void play(int position) {
        // mediaPlay
        try {
            mediaPlayer.reset();// 把各项参数恢复到初始状态
            mediaPlayer.setDataSource(filePath);//设置数据源
            mediaPlayer.prepare();//缓冲数据
            mediaPlayer.setOnPreparedListener(new PrepareListener(position));//完成对缓冲数据的监听
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private final class PrepareListener implements OnPreparedListener {
        private int position;
        public PrepareListener(int position) {
            this.position=position;
        }
        @Override
        public void onPrepared(MediaPlayer mp) {//数据缓冲完后会执行该方法
            mediaPlayer.start();//播放媒体文件
            if(position>0){
                mediaPlayer.seekTo(position); //从position的位置开始播放
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值