天天看點

Android 音樂盒完整版

public class MusicService extends Service {
    private static final String TAG = "jojo";
    private MediaPlayer mediaPlayer;

    @Override
    public void onCreate() {
        //1 初始化mediaPlayer
        mediaPlayer = new MediaPlayer();
        super.onCreate();
    }

    // 把我們定義的中間人對象傳回
    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();
    }
    // 播放音樂的方法
    public void playMusic() {
        // TODO: 2017/4/27 等撸完多媒體 再完善這個案例
        //2 設定要播放的資源位置 path 可以是網絡 路徑 也可以是本地路徑
        try {
            mediaPlayer.reset();
            mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getPath() + "/1.mp3");
            //3 準備播放
            mediaPlayer.prepare();
            //4 開始播放
            mediaPlayer.start();
            //5 更新進度條
            updateSeekBar();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    //更新進度條的方法
    private void updateSeekBar() {
        //1 擷取目前播放的總長度
        final int duration = mediaPlayer.getDuration();
        //2 使用Timer 定時器去定時截取目前進度
        final Timer timer = new Timer();
        final TimerTask task = new TimerTask() {
            @Override
            public void run() {
                //3 一秒鐘擷取一次目前進度
                int currentPosition = mediaPlayer.getCurrentPosition();
                //4 拿着我們在MainActivity建立的handler發消息 消息就可以攜帶資料
                Message msg = Message.obtain();
                Bundle bundle = new Bundle(); // map
                bundle.putInt("duration", duration);
                bundle.putInt("currentPosition", currentPosition);
                msg.setData(bundle);
                // 發送一條消息 mainActivity裡面的handleMessage方法就會執行
                MainActivity.handler.sendMessage(msg);
            }
        };
        // 100 毫秒後 每隔1秒執行一次run方法
        timer.schedule(task, 100, 1000);
        // 當歌曲執行完畢後 把timer和timertask取消
        // 設定播放完成的監聽
        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                Log.d(TAG, "onCompletion:  歌曲播放完成了");
                // 把 timer 和 timertask 取消
                timer.cancel();
                task.cancel();
            }
        });
    }
    // 暫停音樂的方法
    public void pauseMusic() {
        mediaPlayer.pause();
    }
    //繼續播放音樂的方法
    public void rePlayMusic() {
        mediaPlayer.start();
    }
    //實作指定播放的位置
    public void seekTo(int position) {
        mediaPlayer.seekTo(position);
    }

    //1 在服務的内部定義一個中間人對象(IBinder)
    private class MyBinder extends Binder implements Iservice{
        //調用播放音樂的方法
        @Override
        public void callPlayMusic() {
            playMusic();
        }
        //調用暫停音樂的方法
        @Override
        public void callPauseMusic() {
            pauseMusic();
        }
        //調用繼續播放音樂的方法
        @Override
        public void callRePlayMusic() {
            rePlayMusic();
        }
        @Override
        public void callSeekTo(int position) {
            seekTo(position);
        }
    }
}      
public interface Iservice {
    //把想暴露的方法都定義在接口
    public void callPlayMusic();
    public void callPauseMusic();
    public void callRePlayMusic();
    public void callSeekTo(int position);
}      
public class MainActivity extends AppCompatActivity {

    private Iservice iservice; // 這個是我們定義的中間人對象
    private MyConn conn;
    private static SeekBar sbar;

    public static Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            // 擷取我們攜帶的資料
            Bundle data = msg.getData();
            // 擷取歌曲的總時長和目前進度
            int duration = data.getInt("duration");
            int currentPosition = data.getInt("currentPosition");
            // 設定seekBar的進度
            sbar.setMax(duration);
            sbar.setProgress(currentPosition);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 混合方式開啟服務
        //1 先調用startService 目的是可以保證服務在背景長期運作
        Intent intent = new Intent(this, MusicService.class);
        startService(intent);
        //2 調用bingService 目的是為了擷取我們定義的中間人對象 就可以間接的調用服務裡面的方法了
        conn = new MyConn();
        bindService(intent, conn, BIND_AUTO_CREATE);
        //3 找到seekBar 設定進度
        sbar = (SeekBar) findViewById(R.id.seekBar1);
        //4 給seekBar設定監聽事件
        sbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
           // 當進度改變的時候調用
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            }
            // 開始拖動的時候調用
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }
            // 停止拖動的時候調用
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                iservice.callSeekTo(seekBar.getProgress());
            }
        });
    }

    @Override
    protected void onDestroy() {
        //當Activity銷毀的時候解綁服務,目的是為了不報紅色日志
        unbindService(conn);
        super.onDestroy();
    }
    //點選按鈕 播放音樂
    public void click1(View v) {
        //調用播放音樂的方法
        iservice.callPlayMusic();
    }
    //點選按鈕 暫停音樂
    public void click2(View v) {
        //調用暫停音樂的方法
        iservice.callPauseMusic();
    }
    //點選按鈕 繼續播放音樂
    public void click3(View v) {
        //調用繼續播放音樂的方法
        iservice.callRePlayMusic();
    }

    //監聽服務的狀态
    private class MyConn implements ServiceConnection {
        //當服務連接配接成功時調用
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 擷取我們的中間人對象
            iservice = (Iservice) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }
}      
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.a68_baidumusic.MainActivity">

    <Button
        android:text="播放"
        android:onClick="click1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:text="暫停"
        android:onClick="click2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <Button
        android:text="繼續播放"
        android:onClick="click3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <SeekBar
        android:id="@+id/seekBar1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>      

加寫外存權限