1. 程式人生 > >android 四大元件service 音樂播放器的實現

android 四大元件service 音樂播放器的實現

  • 新建立一個Android工程《音樂播放器》,包名:com.itheima.musicPlayer。
    在res目錄下新建一個資料夾raw(名字必須為raw,約定大於配置的原則),然後在raw目錄中拷貝進一個音樂檔案,注意檔名必須遵循Android資原始檔的命名規則。
  • 在src目錄下,新建一個MediaService繼承Service類,在該類中實現核心服務的方法。
private static MediaPlayer player;
    public static  int ispb;
    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("服務返回了MediaContoller物件。。。。"
); return new MediaContoller(); } @Override public void onCreate() { super.onCreate(); System.out.println("建立一個服務,並初始化MediaPlayer"); player = MediaPlayer.create(getApplicationContext(), R.raw.a); } public static class MediaContoller extends Binder
{
//開始播放 public int play(){ player.start(); return 0; } //暫停播放 public int puse(){ player.pause(); return 1; } //停止播放 public void stop(){ player.stop(); } //音樂的總時長 public
int getDuration(){ return player.getDuration(); } //當前播放的位置 public int getCurrentPosition(){ return player.getCurrentPosition(); } //判斷是否播放 public boolean isplaying(){ return player.isPlaying(); } }
  • 這是使用系統預設的佈局檔案,activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:padding="10dp"
        android:text="音樂播放器"
        android:textSize="20sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="play"
            android:text="播放" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="puse"
            android:text="暫停" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="stop"
            android:text="停止" />
    </LinearLayout>

    <ProgressBar
        android:id="@+id/pb"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="10dp" />

</LinearLayout>
  • 使用預設的MainActivity類,在該類中完成業務的控制
package com.example.servicemusic;

import com.example.service.MusicService;
import com.example.service.MusicService.MediaContoller;

import android.support.v7.app.ActionBarActivity;
import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

    private ProgressBar pb;
    // 宣告自定義的MediaController物件
    private MediaContoller controller;
    private boolean isrunning;
    private static int ispb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pb = (ProgressBar) findViewById(R.id.pb);
        // 如何繫結服務?
        // 建立一個用於啟動服務的顯示意圖,指向我們自定義的MediaService類
        Intent service = new Intent(this, MusicService.class);
        // 繫結服務,同時服務開啟,如果成功則返回true否則返回false
        isrunning = bindService(service, new MediaConnection(),
                BIND_AUTO_CREATE);
        if (isrunning) {
            System.out.println("服務繫結成功!");
        } else {
            System.out.println("服務繫結失敗!");
        }
    }

    /**
     * 播放
     * 
     * @param v
     */
    @SuppressLint("ShowToast")
    public void play(View v) {
        if (controller != null) {
            if (controller.isplaying()) {
                Toast.makeText(this, "音樂正在播放中......", 1).show();
                return;
            }else{
                controller.play();
                System.out.println("開始播放音樂");

            }
        }

    }

    /**
     * 暫停
     * 
     * @param v
     */
    public void puse(View v) {

        if (controller != null) {
            controller.puse();
            System.out.println("音樂暫停");
        }

    }

    /**
     * 停止
     * 
     * @param v
     */
    public void stop(View v) {

        if (controller != null) {
            pb.setProgress(0);
            controller.stop();
            //unbindService(new MediaConnection());//終止繫結
            System.out.println("音樂停止");
        }

    }

    /**
     * 更新進度條
     */
    private void updatePro() {
        new Thread() {
            public void run() {
                while (true) {
                    SystemClock.sleep(400);
                    pb.setProgress(controller.getCurrentPosition());
                    if (controller.getCurrentPosition() == controller
                            .getDuration()) {
                        break;
                    }

                }

            };
        }.start();
    }

    /**
     * 實現ServiceConnection 類
     * 
     * @author Blake
     * 
     */
    class MediaConnection implements ServiceConnection {

        /**
         * 當service被繫結的時候回撥該函式
         */
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

            // 返回的ibinder物件其實就是我們自定義的MediaContoller
            controller = (MediaContoller) service;
            // 設定進度條的最大值
            pb.setMax(controller.getDuration());
            // 更新進度條
            updatePro();
            System.out.println("伺服器已經連線......");

        }

        /**
         * 伺服器斷開或關閉的時候呼叫該方法
         */
        @Override
        public void onServiceDisconnected(ComponentName name) {
            System.out.println("伺服器斷開或關閉");

        }

    }

}
  • 在AndroidManifest.xml中註冊Service
  • 將工程部署到模擬器上,點選播放,發現成功播放了音樂。點選暫停,發現音樂暫停了,然後點選播放,音樂再次響起。點選停止,問題來了,我們發現點選停止後再次點選播放音樂沒能再次播放,因為這裡面直接呼叫MediaPlayer的stop方法是有bug的。因此為了解決這樣的問題,我們應該將停止呼叫層pause方法,同時只需呼叫MediaPlayer的seekTo(int)方法將音樂設定到開始位置。
  • //停止播放
    public void stop(){
    player.pause();
    player.seekTo(0);
    }

    這裡寫圖片描述