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,如需转载请自行联系原作者


相关文章
|
16天前
|
XML Java Android开发
Android实现自定义进度条(源码+解析)
Android实现自定义进度条(源码+解析)
49 1
|
7月前
|
编解码 Android开发 数据安全/隐私保护
Android平台外部编码数据(H264/H265/AAC/PCMA/PCMU)实时预览播放技术实现
好多开发者可能疑惑,外部数据实时预览播放,到底有什么用? 是的,一般场景是用不到的,我们在开发这块前几年已经开发了非常稳定的RTMP、RTSP直播播放模块,不过也遇到这样的场景,部分设备输出编码后(视频:H.264/H.265,音频:AAC/PCMA/PCMU)的数据,比如无人机或部分智能硬件设备,回调出来的H.264/H.265数据,除了想转推到RTMP、轻量级RTSP服务或GB28181外,还需要本地预览甚至对数据做二次处理(视频分析、实时水印字符叠加等,然后二次编码),基于这样的场景诉求,我们开发了Android平台外部编码数据实时预览播放模块。
|
4月前
|
XML Java Android开发
Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)
Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)
72 0
|
4月前
|
XML API Android开发
Android 自定义View 之 圆环进度条
Android 自定义View 之 圆环进度条
|
4月前
|
XML API Android开发
Android 自定义View 之 饼状进度条
Android 自定义View 之 饼状进度条
|
4月前
|
Android开发 UED
[Android]ProgressBar进度条
[Android]ProgressBar进度条
40 0
|
4月前
|
XML Java 调度
Android开发音效增强中铃声播放Ringtone及声音池调度SoundPool的讲解及实战(超详细 附源码)
Android开发音效增强中铃声播放Ringtone及声音池调度SoundPool的讲解及实战(超详细 附源码)
47 0
|
4月前
|
XML Java Android开发
Android App开发实战项目之仿手机QQ动感影集动画播放(附源码和演示视频 可直接使用)
Android App开发实战项目之仿手机QQ动感影集动画播放(附源码和演示视频 可直接使用)
28 0
|
4月前
|
XML 算法 Java
Android Studio App开发之利用图像解码器ImageDecoder播放GIF动图、Webp、HEIF图片(附源码 简单实用)
Android Studio App开发之利用图像解码器ImageDecoder播放GIF动图、Webp、HEIF图片(附源码 简单实用)
105 0
|
4月前
|
XML Java Android开发
Android Studio App开发中异步任务AsynTask与异步服务IntentService的讲解与实战(实现四大名著的加载进度条 附源码)
Android Studio App开发中异步任务AsynTask与异步服务IntentService的讲解与实战(实现四大名著的加载进度条 附源码)
54 0