Notification 播放声音

NotificationPlayer.java

定义一个播放Notification声音的player,本质上仍然是一个MediaPlayer,这个是多线程编程的很好的例子

public class NotificationPlayer implements OnCompletionListener {

//发送播放和停止的cmd

private static final int PLAY = 1;

private static final int STOP = 2;

//对于多线程处理来说,这个class用来线程之间传递数据

private static final class Command {

        int code;

        Context context;

        Uri uri;

        boolean looping;

        int stream;

        long requestTime;

        public String toString() {

            return "{ code=" + code + " looping=" + looping + " stream=" + stream

                    + " uri=" + uri + " }";

        }

}

//播放类构造函数

public NotificationPlayer(String tag) {

        if (tag != null) {

            mTag = tag;

        } else {

            mTag = "NotificationPlayer";

        }

}

public void play(Context context, Uri uri, boolean looping, int stream) {

//创建用于进程之间传递数据的类。前面说的那个中间class

        Command cmd = new Command();

//初始化信息

        cmd.requestTime = SystemClock.uptimeMillis();

        cmd.code = PLAY;

        cmd.context = context;

        cmd.uri = uri;

        cmd.looping = looping;

        cmd.stream = stream;

        synchronized (mCmdQueue) {

//开始另外一个线程,用来解析用户设置cmd,然后才决定是play还是stop

            enqueueLocked(cmd);

            mState = PLAY;

        }

 }

//这表明CmdThread就是一个thread

private final class CmdThread extends java.lang.Thread {

CmdThread() {

            super("NotificationPlayer-" + mTag);

}

public void run() {

        while (true) {

                Command cmd = null;

                synchronized (mCmdQueue) {

//这一步很巧妙,直接用队列中删除返回删除数据的引用来获取刚才在play中设置的信息

                    cmd = mCmdQueue.removeFirst();

                }

switch (cmd.code) {

case PLAY:

 startSound(cmd);

 break;

//主要是用户发出停止的命令的操作--非正常播放结束stop

case STOP:

……

//强制停止要释放focus

mAudioManager.abandonAudioFocus(null);

break;

}

//处理之后要释放wakelock

synchronized (mCmdQueue) {

      if (mCmdQueue.size() == 0) {

           mThread = null;

           releaseWakeLock();

           return;

      }

}

}

}

}//end of CmdThread 

private void startSound(Command cmd) {

try {

if((mLooper != null)

    && (mLooper.getThread().getState() != Thread.State.TERMINATED)) {

                    mLooper.quit();

}

mCompletionThread = new CreationAndCompletionThread(cmd);

//开启播放线程

synchronized(mCompletionThread) {

     mCompletionThread.start();

     mCompletionThread.wait();

}

}

}

private final class CreationAndCompletionThread extends Thread {

public Command mCmd;

public CreationAndCompletionThread(Command cmd) {

      super();

      mCmd = cmd;

 }

public void run() {

try {

//设置播放信息,并开始播放

MediaPlayer player = new MediaPlayer();

player.setAudioStreamType(mCmd.stream);

player.setDataSource(mCmd.context, mCmd.uri);

player.setLooping(mCmd.looping);

player.prepare();

if ((mCmd.uri != null) && (mCmd.uri.getEncodedPath() != null)

      && (mCmd.uri.getEncodedPath().length() > 0)) {

       if (mCmd.looping) {

           audioManager.requestAudioFocus(null, mCmd.stream,

                                    AudioManager.AUDIOFOCUS_GAIN);

       } else {

           audioManager.requestAudioFocus(null, mCmd.stream,

                                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);

        }

 }

 //这一步是必须的,要释放focus

 player.setOnCompletionListener(NotificationPlayer.this);

 player.start();

}

}

}

public void onCompletion(MediaPlayer mp) {

if (mAudioManager != null) {

            mAudioManager.abandonAudioFocus(null);

 }

}

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值