android97 播放音频 有进度条控制-阿里云开发者社区

开发者社区> 开发与运维> 正文

android97 播放音频 有进度条控制

简介:

package com.itheima.musicplayer;

import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.view.Menu; import android.view.View; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; public class MainActivity extends Activity { static Handler handler = new Handler(){//handler是谷歌说明的定义成静态的, public void handleMessage(android.os.Message msg) { Bundle bundle = msg.getData(); int duration = bundle.getInt("duration"); int currentPostition = bundle.getInt("currentPosition"); //刷新进度条的进度,设置SeekBar的Max和Progress就能够时时更新SeekBar的长度, sb.setMax(duration); sb.setProgress(currentPostition); } }; MusicInterface mi; private MyserviceConn conn; private Intent intent; private static SeekBar sb;//属性在对象生成的时候才有,所以在静态代码中要变成静态。 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sb = (SeekBar) findViewById(R.id.sb); sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {//SeekBar进度改变事件 @Override public void onStopTrackingTouch(SeekBar seekBar) {//手指抬起 //拖动SeekBar的进度改变音乐播放进度 int progress = seekBar.getProgress(); //改变播放进度 mi.seekTo(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) {//手指按下 } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {//手指滑动 } }); intent = new Intent(this, MusicService.class); startService(intent); conn = new MyserviceConn(); bindService(intent, conn, BIND_AUTO_CREATE); } class MyserviceConn implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { mi = (MusicInterface) service;//中间人 } @Override public void onServiceDisconnected(ComponentName name) { } } public void play(View v){ mi.play(); } public void continuePlay(View v){ mi.continuePlay(); } public void pause(View v){ mi.pause(); } public void exit(View v){ unbindService(conn); //解绑 stopService(intent); //停止 } } //清单文件:<service android:name="com.itheima.musicplayer.MusicService"></service> /*<SeekBar android:id="@+id/sb" android:layout_width="match_parent" android:layout_height="wrap_content" /> 音乐播放器的进度条,可以拖动改变音乐的播放进度,不同于processBar不可以拖动*/
复制代码
复制代码
package com.itheima.musicplayer;

public interface MusicInterface {

    void play();
    void pause();
    void continuePlay();
    void seekTo(int progress);
}
复制代码
复制代码
package com.itheima.musicplayer;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

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

public class MusicService extends Service {

    MediaPlayer player;//播放音乐API
    private Timer timer;
    @Override
    public IBinder onBind(Intent intent) {
        return new MusicController();
    }

    class MusicController extends Binder implements MusicInterface{

        @Override
        public void play() {
            MusicService.this.play();
        }

        @Override
        public void pause() {
            MusicService.this.pause();
        }

        @Override
        public void continuePlay() {
            MusicService.this.continuePlay();
        }

        @Override
        public void seekTo(int progress) {
            MusicService.this.seekTo(progress);
        }
    }
    
    @Override
    public void onCreate() {
        super.onCreate();
        player = new MediaPlayer();
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        //停止播放
        player.stop();
        //释放占用的资源,此时player对象已经废掉了,但是player对象还在。
        player.release();
        player = null;
        if(timer != null){
            timer.cancel();
            timer = null;
        }
    }
    
    //播放音乐
    public void play(){
        //重置
        player.reset();
        try {
            //加载多媒体文件
            player.setDataSource("sdcard/zxmzf.mp3");//播放本地音频可以同步准备,调用主线程的player.prepare()方法和start()方法,因为主线程知道prepare()好了之后再start()
//            player.setDataSource("http://192.168.13.119:8080/bzj.mp3");  //播放网络音频是一个耗时操作必须要开启子线城异步准备调用player.prepareAsync()方法,这个方法默认就是开启子线城,不能直接调用主线程的start()方法因为主线程不知道子线城什么时候准备完毕,因此要在主线程做监听setOnPreparedListener(),当子线城准备完了之后主线程监听到了之后主线程才能start()
//            player.prepare();  因为调用了硬件所以要做准备
            player.prepareAsync();   //异步准备,开启子线程加载资源
//            player.start();
            player.setOnPreparedListener(new OnPreparedListener() {//准备监听
                //prepare()方法准备完毕时,此方法调用
                @Override
                public void onPrepared(MediaPlayer mp) {
                    player.start();
                    addTimer();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
    
    //继续播放
    public void continuePlay(){
        player.start();
    }
    
    //暂停播放
    public void pause(){
        player.pause();
    }
    
    public void seekTo(int progress){
        player.seekTo(progress);
    }
    public void addTimer(){
        if(timer == null){
            timer = new Timer();//timer就是开启子线程执行任务,与纯粹的子线城不同的是可以控制子线城执行的时间,
            timer.schedule(new TimerTask() {
                
                @Override
                public void run() {
                    //获取歌曲总时长
                    int duration = player.getDuration();
                    //获取歌曲当前播放进度
                    int currentPosition= player.getCurrentPosition();
                    Message msg = MainActivity.handler.obtainMessage();
                    //把进度封装至消息对象中
                    Bundle bundle = new Bundle();
                    bundle.putInt("duration", duration);
                    bundle.putInt("currentPosition", currentPosition);
                    msg.setData(bundle);
                    MainActivity.handler.sendMessage(msg);
                }
                //开始计时任务后的5毫秒后第一次执行run方法,以后每500毫秒执行一次
            }, 5, 500);
        }
    }
}
复制代码

 


本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/4966598.html,如需转载请自行联系原作者


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章