天天看點

【GT-安卓應用開發之MediaPlayer使用】

前言:之前做項目涉及到一個功能是播放音頻,考慮到其邏輯比較簡單,便采用安卓自帶的MediaPlayer實作。先了解一下需求,接收三個參數分别是标題、圖檔位址和音頻url,支援播放、暫停、重放以及拖動控制條。

        要實作前言中涉及到的幾個功能,我們需要先熟悉一下MediaPlayer提供的幾個方法:

        1、setDataSource,設定資料源,也就是前言中提到的音頻url

        2、prepare、start,分别是準備與開始播放

        3、isPlaying、pause、stop、release,分别是是否正在播放、暫停、停止、釋放

        4、getCurrentPosition、seekTo,擷取目前播放位置、跳到某位置開始播放

        基本這次需求就涉及到上面幾個方法,接下來開始實作該需求:

        1、界面設計

        從需求可以看出界面不需要太複雜,主要由圖檔、進度條、暫停/播放按鈕、重放按鈕以及标題幾部分組成,直接貼代碼:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/relative"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/back"
            android:layout_width="@dimen/dp_45"
            android:layout_height="@dimen/dp_60"
            android:padding="@dimen/dp_10"
            android:src="@mipmap/back" />

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="@dimen/dp_60"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:singleLine="true"
            android:text="标題"
            android:textColor="@color/black_font"
            android:textSize="@dimen/text_16_sp" />
    </RelativeLayout>

    <TextView
        android:id="@+id/data"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="@dimen/dp_30"
        android:textColor="@color/black_font"
        android:layout_marginLeft="@dimen/dp_30"
        android:visibility="invisible"
        android:gravity="center_vertical"
        android:text="正在緩沖" />

    <LinearLayout
        android:id="@+id/linearButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/data"
        android:layout_marginLeft="@dimen/dp_30"
        android:layout_marginRight="@dimen/dp_30"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/play_pause"
            android:layout_width="@dimen/dp_60"
            android:layout_height="@dimen/dp_60"
            android:padding="@dimen/dp_15"
            android:src="@mipmap/stop_play_music" />

        <ImageView
            android:id="@+id/reset"
            android:layout_width="@dimen/dp_60"
            android:layout_height="@dimen/dp_60"
            android:padding="@dimen/dp_15"
            android:src="@mipmap/resetting" />

        <SeekBar
            android:id="@+id/seekbar"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/dp_10" />
    </LinearLayout>

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_500"
        android:layout_above="@id/linearButton"
        android:layout_below="@id/relative"
        android:layout_centerHorizontal="true"
        android:layout_margin="@dimen/dp_30"
        android:scaleType="centerCrop"
        android:src="@mipmap/vp1" />
</RelativeLayout>
           

        2、邏輯實作

public class EnglistDetailedActivity extends BaseActivity {

    @BindView(R.id.back)
    ImageView back;
    @BindView(R.id.title)
    TextView title;
    @BindView(R.id.iv)
    ImageView iv;
    @BindView(R.id.data)
    TextView data;
    @BindView(R.id.relative)
    RelativeLayout relative;
    @BindView(R.id.play_pause)
    ImageView playPause;
    @BindView(R.id.reset)
    ImageView reset;
    @BindView(R.id.seekbar)
    SeekBar seekbar;
    @BindView(R.id.linearButton)
    LinearLayout linearButton;
    private String title1;
    private String picture;
    private String path;
    private MediaPlayer player = null;
    private boolean ifplay = false;
    private boolean iffirst = false;
    private Timer mTimer;
    private TimerTask mTimerTask;
    private boolean isChanging = false;//互斥變量,防止定時器與SeekBar拖動時進度沖突

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_englist_detailed);
        ButterKnife.bind(this);
        Intent intent = getIntent();
        path = intent.getStringExtra("path");
        picture = intent.getStringExtra("picture");
        title1 = intent.getStringExtra("title");
        title.setText(title1);
        player = new MediaPlayer();
        playPause.setOnClickListener(new MyClick());
        reset.setOnClickListener(new MyClick());
        seekbar.setOnSeekBarChangeListener(new MySeekbar());
        GlideLoadUtils.getInstance().glideLoad(this, picture, iv, R.color.default_bg);
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (player != null) {
                    try {
                        if (player.isPlaying()) {
                            player.stop();
                            player.release();
                        }
                    } catch (IllegalStateException e) {

                    }
                }
                if (mTimer != null || mTimerTask != null) {
                    mTimer.purge();
                    mTimerTask.cancel();
                }
                if (seekbar != null) {
                    seekbar = null;
                }

                finish();
            }
        });
    }

    class MyClick implements View.OnClickListener {
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.play_pause:
                    if (player != null && !ifplay) {
//                        data.setVisibility(View.VISIBLE);
                        playPause.setImageResource(R.mipmap.start_play_music);
                        if (!iffirst) {
                            player.reset();
                            try {
                                player.setDataSource(path);
                                player.prepare();// 準備

                            } catch (IllegalArgumentException e) {
                                e.printStackTrace();
                            } catch (IllegalStateException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            seekbar.setMax(player.getDuration());//設定進度條
                            //----------定時器記錄播放進度---------//
                            mTimer = new Timer();
                            mTimerTask = new TimerTask() {
                                @Override
                                public void run() {
                                    if (isChanging == true) {
                                        return;
                                    }
                                    try {
                                        if (player.getCurrentPosition()>0){
                                        }
                                        seekbar.setProgress(player.getCurrentPosition());
                                    }catch (IllegalStateException e){
                                        e.printStackTrace();
                                    }
                                }
                            };
                            mTimer.schedule(mTimerTask, 0, 10);
                            iffirst = true;
                        }
                        player.start();// 開始
                        ifplay = true;
                    } else if (ifplay) {
                        playPause.setImageResource(R.mipmap.stop_play_music);
//                        data.setVisibility(View.INVISIBLE);
                        player.pause();
                        ifplay = false;
                    }
                    break;
                case R.id.reset:
                    if (ifplay) {
//                        data.setVisibility(View.INVISIBLE);
                        player.seekTo(0);
                    } else {
//                        data.setVisibility(View.VISIBLE);
                        player.reset();
                        try {
                            player.setDataSource(path);
                            player.prepare();// 準備
                            player.start();// 開始
//                            data.setVisibility(View.INVISIBLE);
                        } catch (IllegalArgumentException e) {
                            e.printStackTrace();
                        } catch (IllegalStateException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
            }
//            }
        }
    }

    //進度條處理
    class MySeekbar implements SeekBar.OnSeekBarChangeListener {
        public void onProgressChanged(SeekBar seekBar, int progress,
                                      boolean fromUser) {
        }

        public void onStartTrackingTouch(SeekBar seekBar) {
            isChanging = true;
        }

        public void onStopTrackingTouch(SeekBar seekBar) {
            player.seekTo(seekbar.getProgress());
            isChanging = false;
        }

    }

    
    protected void onDestroy() {
        if (player != null) {
            try {
                if (player.isPlaying()) {
                    player.stop();
                    player.release();
                }
            } catch (
                    IllegalStateException e) {
            }
        }
        super.onDestroy();

    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (player != null) {
                try {
                    if (player.isPlaying()) {
                        player.stop();
                        player.release();
                    }
                } catch (IllegalStateException e) {

                }
            }
            if (mTimer != null || mTimerTask != null) {
                mTimer.purge();
                mTimerTask.cancel();
            }
            if (seekbar != null) {
                seekbar = null;
            }
            finish();
        }
        return super.onKeyDown(keyCode, event);
    }

    protected void onPause() {
        if (player != null) {
            try {

                if (player.isPlaying()) {
                    player.pause();
                }
            } catch (IllegalStateException e) {

            }
        }

        super.onPause();
    }

    protected void onResume() {
//        data.setVisibility(View.VISIBLE);
        if (player != null) {
            try {
                if (!player.isPlaying()) {
                    player.start();
//                    data.setVisibility(View.INVISIBLE);
                }
            } catch (IllegalStateException e) {

            }
        }

        super.onResume();
    }
}
           

        3、效果圖

【GT-安卓應用開發之MediaPlayer使用】

繼續閱讀