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);
    }

    這裏寫圖片描述
發佈了56 篇原創文章 · 獲贊 16 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章