2015年11月28日 星期六

Android - 使用MediaPlayer 播放音效

在Android中,MediaPlayer類別可以用來播放音效,只要給定音效源的Uri,不管是SD Card、手機中、還是網路上的聲音源,都可以利用其來播放,不過要注意的是,在Android 4.0以上規定了更嚴格的權限規範,所以如果聲音檔不是用正常管道放進SD Card的(例如:用IDE去強制放進去的),就不可以播放。

下面就來演示一個簡單的播放例子:

AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.gjun.mediaplayerpractice" >

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


MainActivity :
package com.example.gjun.mediaplayerpractice;

import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.SeekBar;
import android.widget.Toast;

import java.io.IOException;

public class MainActivity extends ActionBarActivity {


    private SeekBar control;
    private MediaPlayer mediaPlayer;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //取得元件
        control = (SeekBar) findViewById(R.id.control);
        // 註冊SeekBar元件進度改變事件
        control.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                // 一定要判斷是使用者的操作,因為播放過程也會更改進度
                if (fromUser) {
                    // 移動音樂到指定的進度
                    mediaPlayer.seekTo(progress);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }

    public void clickPlay(View view) {
        // 開始播放
        if (mediaPlayer != null){
            mediaPlayer.start();
            // 執行顯示播放進度的AsyncTask物件
            new MyPlayTask().execute();
        }else if (!mediaPlayer.isPlaying()){
            new NetworkTask().execute("http://www.ntust20140311ai2.comuv.com/song01.mp3");
        }
    }

    public void clickPause(View view) {
        // 暫停播放
        if (mediaPlayer != null && mediaPlayer.isPlaying()){
            mediaPlayer.pause();
        }
    }

    public void clickStop(View view) {
        // 停止播放
        if (mediaPlayer != null){
            mediaPlayer.stop();
            // 回到開始的位置
            mediaPlayer.seekTo(0);
            control.setProgress(0);
        }
    }

    // 從指定的網路資源載入音樂並開始播放
    private class NetworkTask extends AsyncTask<String, Void, Void> {
        @Override
        protected Void doInBackground(String... networkPah) {
            // 建立網路資源音樂檔案Uri物件
            Uri uri = Uri.parse(networkPah[0]);
            mediaPlayer = MediaPlayer.create(MainActivity.this,uri);
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            control.setMax(mediaPlayer.getDuration());
            // 註冊播放完畢監聽事件
            // 切換按鈕為可播放
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mediaPlayer) {
                    clickStop(null);
                    Toast.makeText(MainActivity.this, "Play End!",Toast.LENGTH_SHORT).show();
                }
            });
            // 開始播放
            mediaPlayer.start();
            Toast.makeText(MainActivity.this,"Play Start!",Toast.LENGTH_SHORT).show();
        }
    }

    // 在播放過程中顯示播放進度
    private class MyPlayTask extends AsyncTask<Void, Integer, Void> {
        @Override
        protected Void doInBackground(Void... voids) {
            while (mediaPlayer.isPlaying()){
                this.publishProgress(mediaPlayer.getCurrentPosition());
            }
            return null;
        }
        // 設定播放進度
        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
            control.setProgress(progress[0]);
        }
    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}


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

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/retangle_drawable"
        android:layout_margin="6sp"
        android:padding="6sp" >
        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/play_icon"
            android:onClick="clickPlay" />
        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/pause_icon"
            android:onClick="clickPause" />
        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/stop_icon"
            android:onClick="clickStop" />
        <SeekBar
            android:id="@+id/control"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/retangle_drawable"
        android:layout_margin="6sp"
        android:padding="6sp" >

        <ImageButton
            android:id="@+id/record_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/record_dark_icon"
            android:onClick="clickRecord" />
        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/play_icon"
            android:onClick="clickRecordPlay" />
        <ProgressBar
            android:id="@+id/record_volumn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="6dp"
            android:layout_marginRight="6dp"
            android:max="15"
            style="@android:style/Widget.ProgressBar.Horizontal" />
    </LinearLayout>

</LinearLayout>

源碼下載:
MediaPlayerPractice.7z

沒有留言 :

張貼留言