java 停止线程播放音频_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 ofCmdThread

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);

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值