實現一個簡單的播放器——Service,Handle和MediaPlayer的使用


實現一個簡單的播放器,要求功能有:

1. 播放、暫停,停止,退出功能;

2. 后台播放功能;

3. 進度條顯示播放進度、拖動進度條改變進度功能;

4. 播放時圖片旋轉,顯示當前播放時間功能;

效果圖:

圖片旋轉:

  圖片布局:主要是要實現圖片居中,還有就是id

 

       定義rotate旋轉效果:在res/anim文件夾下新建tip.xml文件。

下面的代碼表示從0到359度開始循環旋轉,0-359(若設置成360在停止時會出現停頓現象)度旋轉所用時間為10000ms,旋轉中心距離view的左頂點為50%距離,距離view的上邊緣為50%距離,即正中心.

 

android:fromDegrees 起始的角度度數

android:toDegrees 結束的角度度數,負數表示逆時針,正數表示順時針。如10圈則比android:fromDegrees大3600即可

android:pivotX 旋轉中心的X坐標

android:pivotY 旋轉中心的Y坐標

浮點數或是百分比。浮點數表示相對於Object的左邊緣,如5; 百分比表示相對於Object的左邊緣,如5%; 另一種百分比表示相對於父容器的左邊緣,如5%p; 一般設置為50%表示在Object中心

android:duration 表示從android:fromDegrees轉動到android:toDegrees所花費的時間,單位為毫秒。可以用來計算速度。

android:interpolator表示變化率,但不是運行速度。一個插補屬性,可以將動畫效果設置為加速,減速,反復,反彈等。默認為開始和結束慢中間快,

android:startOffset 在調用start函數之后等待開始運行的時間,單位為毫秒,若為10,表示10ms后開始運行

android:repeatCount 重復的次數,默認為0,必須是int,可以為-1表示不停止

android:repeatMode 重復的模式,默認為restart,即重頭開始重新運行,可以為reverse即從結束開始向前重新運行。在android:repeatCount大於0或為infinite時生效

android:detachWallpaper 表示是否在壁紙上運行

android:zAdjustment 表示被animated的內容在運行時在z軸上的位置,默認為normal。

normal保持內容當前的z軸順序

top運行時在最頂層顯示

bottom運行時在最底層顯示

運行速度為運行時間(android:duration)除以運行角度差(android:toDegrees-android:fromDegrees)

 

setInterpolator表示設置旋轉速率。LinearInterpolator為勻速效果,Accelerateinterpolator為加速效果、DecelerateInterpolator為減速效果

AnimationUtils.loadAnimation(this,R.anim.tip)就是加載一個動態效果,tip就是前面定義的xml。

開始旋轉:imageview.startAnimation(operatingAnim)

停止旋轉:imageview.clearAnimation();

代碼:

package com.example.hp.lab6;

import android.app.Activity;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.media.Image;
import android.os.Handler;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;

import java.text.SimpleDateFormat;


public class MainActivity extends Activity implements OnClickListener {

    private Button play_pauseBtn,stopBtn,quitBtn;
    private MusicService musicService;
    private ImageView imageview;
    private TextView state, playing_time,max_time;
    private SeekBar seekbar;
    private SimpleDateFormat time = new SimpleDateFormat("mm:ss");
    //Bitmap bmp = BitmapFactory.decodeResource(this.getResources(),R.mipmap.image);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);//綁定布局
        findView();//findIdByView,找到個個控件
        bindButton();//按鈕綁定監聽器。
        musicService=new MusicService();//新建一個MusicService后台服務
        connection();//綁定后台服務
        max_time.setText(time.format(musicService.mediaPlayer.getDuration()));//設置max_time這個textview的內容是歌曲的時間長度
        Animation operatingAnim = AnimationUtils.loadAnimation(this, R.anim.tip);
        LinearInterpolator lin = new LinearInterpolator();//LinearInterpolator為勻速效果
        operatingAnim.setInterpolator(lin);//setInterpolator表示設置旋轉速率。
        imageview.startAnimation(operatingAnim);//開始旋轉

    }

    private void findView(){
        /** 通過id獲得各種組件 */
        play_pauseBtn=(Button) findViewById(R.id.play_pause);//開始/暫停按鈕
        stopBtn=(Button) findViewById(R.id.stop);//停止按鈕
        quitBtn=(Button) findViewById(R.id.quit);//退出按鈕
        state=(TextView) findViewById(R.id.state);//seekbar上面表示狀態的文字textview
        playing_time=(TextView) findViewById(R.id.playing_time);//seekbar左邊現在播放的時間
        max_time=(TextView) findViewById(R.id.song_time);//播放的這首歌曲的時長
        seekbar=(SeekBar) findViewById(R.id.seekbar);//seekbar
        imageview=(ImageView ) findViewById(R.id.imageview);//旋轉的圖片
    }

    private void bindButton(){
        /** 為按鈕添加監聽 ,三個按鈕的監聽器都是MainActivity*/
        play_pauseBtn.setOnClickListener(this);
        stopBtn.setOnClickListener(this);
        quitBtn.setOnClickListener(this);
    }
    private ServiceConnection sc=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            musicService=((MusicService.MyBinder)service).getService();
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            musicService=null;
        }
    };

    Handler mHandler=new Handler(); //創建Handler對象
    //要用handler來處理多線程可以使用runnable接口,這里先定義該接口,線程中運行該接口的run函數
    Runnable mRunnable=new Runnable() { //新建一個Runnable接口
        @Override
        public void run() {//將要執行的操作寫在線程對象的run方法當中

            //Matrix mtx = new Matrix();
            //mtx.postRotate(1);
            // Rotating Bitmap
            //Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mtx, true);
            //BitmapDrawable bmd = new BitmapDrawable(rotatedBMP);
            //imageview.setImageDrawable(bmd);

            //設置seekbar左邊的playing_time textview為當前歌曲播放到的時間
            playing_time.setText(time.format(musicService.mediaPlayer.getCurrentPosition()));
            //設置seekbar為當前歌曲播放到的時間
            seekbar.setProgress(musicService.mediaPlayer.getCurrentPosition());
            //seekbar條拖動監聽事件
            seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override//seekbar發生改變時
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    if(fromUser){
                        musicService.mediaPlayer.seekTo(seekBar.getProgress());
                    }//根據seekbar拖動到的位置改變設置歌曲播放到的進度
                }
                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {
                }
                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {
                }
            });
            mHandler.postDelayed(mRunnable,100);//100ms執行一次tun()函數
        }
    };
    @Override
    public void onClick(View v){
        switch (v.getId()){
            case R.id.play_pause://點擊play_pause按鈕事件
                musicService.playORpuase();//調用musicService中的playORpause函數,暫停或開始音樂播放
                if(musicService.mediaPlayer.isPlaying()){
                    state.setText("Playing");//當音樂在播放時,我們設置state的內容為Playing
                    play_pauseBtn.setText("PAUSE");//設置button的內容為Puase
                    //Animation operatingAnim = AnimationUtils.loadAnimation(this, R.anim.tip);
                    //LinearInterpolator lin = new LinearInterpolator();//LinearInterpolator為勻速效果
                    //operatingAnim.setInterpolator(lin);//setInterpolator表示設置旋轉速率。
                   // imageview.startAnimation(operatingAnim);//開始旋轉
                }
                else{
                    state.setText("Paused");//當音樂停止時,設置state內容為Paused
                    play_pauseBtn.setText("PLAY");//button內容為Play
                }
                break;
            case R.id.stop://點擊暫停
                musicService.stop();//關閉音樂
                play_pauseBtn.setText("PLAY");//設置開始和暫停按鈕的內容為Play
                state.setText("Stop");//設置state為Stop
                //imageview.clearAnimation();
                break;
            case R.id.quit://點擊退出
                mHandler.removeCallbacks(mRunnable);//回調mRunnable接口
                unbindService(sc);//解除后台服務的綁定
                try{
                    MainActivity.this.finish();//結束當前的時間
                    System.exit(0);
                }
                catch (Exception e){
                    e.printStackTrace();
                }
                break;
        }

    }

    private void connection(){
        //啟動指定的Service
        Intent intent=new Intent(this ,MusicService.class);
        bindService(intent,sc,BIND_AUTO_CREATE);//綁定服務
    }

    @Override
    protected void onResume() {
        seekbar.setProgress(musicService.mediaPlayer.getCurrentPosition());
        seekbar.setMax(musicService.mediaPlayer.getDuration());
        mHandler.post(mRunnable);//通過Handler啟動Runnable
        super.onResume();
    }

}
package com.example.hp.lab6;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;

public class MusicService extends Service {
    public MediaPlayer mediaPlayer=new MediaPlayer();
    private final IBinder binder=new MyBinder();
    public class MyBinder extends Binder {
        MusicService getService(){
            return MusicService.this;//找到后台服務的指針,返回后台服務實例
        }
    }
    public MusicService() {
        try{
            mediaPlayer.setDataSource("/data/K.Will-Melt.mp3");//綁定播放的歌曲
            mediaPlayer.prepare();//進入就緒狀態
            mediaPlayer.setLooping(true);//設置循環播放
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        //throw new UnsupportedOperationException("Not yet implemented");
        return binder;
    }
    @Override
    public void onCreate(){
        super.onCreate();
    }
    @Override
    public void onDestroy(){
        super.onDestroy();
        if(mediaPlayer!=null){
            mediaPlayer.stop();//停止歌曲播放
            mediaPlayer.release();//釋放mediaPlayer資源
        }
    }
    public void playORpuase(){
        if(mediaPlayer.isPlaying()){
            mediaPlayer.pause();//暫停
        }
        else{
            mediaPlayer.start();//開始
        }
    }
    public void stop(){
        if(mediaPlayer!=null){
            mediaPlayer.stop();//停止
            try{
                mediaPlayer.prepare();//就緒
                mediaPlayer.seekTo(0);//設置歌曲回到最開始
            }
            catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.example.hp.lab6.MainActivity"
    >

    <ImageView
        android:id="@+id/imageview"
        android:layout_gravity="center"
        android:layout_width="300sp"
        android:layout_height="300sp"
        android:src="@drawable/image"
        />
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="vertical">
        <TextView
            android:id="@+id/state"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/margin_top"
            android:textSize="@dimen/textsize1"
            android:text="" />
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginTop="@dimen/margin_top"
            android:gravity="center_horizontal">
            <TextView
                android:id="@+id/playing_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="00:00"/>
            <SeekBar
                android:id="@+id/seekbar"
                android:layout_width="280sp"
                android:layout_height="wrap_content" />

            <TextView
                android:id="@+id/song_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="04:00"/>
        </LinearLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/margin_top"
        android:layout_gravity="center_horizontal"
        android:orientation="horizontal">
        <Button
            android:id="@+id/play_pause"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="PLAY"

            />
        <Button
            android:id="@+id/stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/textsize1"
            android:text="STOP"
            />
        <Button
            android:id="@+id/quit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/textsize1"
            android:text="QUIT"
            />

    </LinearLayout>
</LinearLayout>

 

項目倉庫:https://github.com/luqx3/mediaPlayer


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM