MediaPlayer延迟重复播放时,切换按钮在等待阶段无法停止音频的问题求助
解决方案
问题根源有两个:一是stop()方法里只判断mediaPlayer.isPlaying(),但音频播放完进入5秒延迟阶段时,mediaPlayer已经处于停止状态,导致停止逻辑不执行;二是后台的延迟重启任务还在等待,到点会自动重新启动音频。
要实现“无论音频是否在延迟阶段,点击按钮都能彻底停止”的需求,你需要:
- 保存延迟任务的引用,方便随时取消它
- 修改
stop()方法,移除播放状态判断,直接执行停止清理逻辑,同时取消延迟任务 - 每次启动音频前,确保之前的延迟任务已经被取消
修改后的完整代码
public static MediaPlayer mediaPlayer = new MediaPlayer(); public View mView; private Context mContext; public boolean status; // 新增:保存延迟任务的引用,用于后续取消 private Handler delayHandler; private Runnable restartRunnable; public boolean getStatus() { return status; } public void setStatus(boolean status) { this.status = status; } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void toggle(View view, Context context) { this.mView = view; this.mContext = context; // 用status判断状态比直接判断mediaPlayer更可靠 if (getStatus()) { this.stop(); } else { this.start(); } } /** * 启动扫描音频 */ @SuppressLint("UseCompatLoadingForColorStateLists") @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void start() { // 先取消之前的延迟任务(如果存在) if (delayHandler != null && restartRunnable != null) { delayHandler.removeCallbacks(restartRunnable); } // 释放旧的mediaPlayer实例,避免内存泄漏 if (mediaPlayer != null) { mediaPlayer.release(); } mediaPlayer = MediaPlayer.create(mContext, scanner); mediaPlayer.setOnPreparedListener(mediaPlayerListener -> mediaPlayer.start()); // 创建新的延迟重启任务 delayHandler = new Handler(Looper.getMainLooper()); restartRunnable = () -> mediaPlayer.start(); mediaPlayer.setOnCompletionListener(listener -> delayHandler.postDelayed(restartRunnable, 5000)); setStatus(true); // 可选:添加开启提示 // Snackbar.make(mView, "Scanner is ON", Snackbar.LENGTH_SHORT).show(); } /** * 停止扫描音频 */ @SuppressLint("UseCompatLoadingForColorStateLists") @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void stop() { // 取消延迟重启任务 if (delayHandler != null && restartRunnable != null) { delayHandler.removeCallbacks(restartRunnable); delayHandler = null; restartRunnable = null; } // 彻底清理mediaPlayer资源,不管当前是否在播放 try { if (mediaPlayer != null) { if (mediaPlayer.isPlaying()) { mediaPlayer.stop(); } mediaPlayer.release(); mediaPlayer = null; } } catch (Exception e) { e.printStackTrace(); } mView.setBackgroundTintList(null); Snackbar.make(mView, "Scanner is OFF", Snackbar.LENGTH_LONG).setAction("Action", null).show(); setStatus(false); }
辅助方法保持不变
public static void setTimeout(Runnable runnable, int delay) { new Handler(Looper.getMainLooper()).postDelayed(runnable, delay); }
这样修改后,无论音频处于播放中还是5秒延迟等待阶段,点击按钮都能彻底停止音频,不会再出现自动重启的情况。
内容的提问来源于stack exchange,提问作者xRay
相关产品推荐
相关产品推荐

