Android开发:如何检测选中的音频是否正在播放?
解决音频重复播放的小技巧
嘿,我来帮你搞定这个问题!核心思路就是让你的Activity和Service能互通状态——Service要记住当前播的是哪首,Activity点击音频时先跟Service确认是不是同一首正在播,再决定要不要操作。
第一步:给你的播放Service加个“状态记录本”
在你的播放Service里,先加几个变量来记录关键状态,再写几个方法让Activity能拿到这些状态:
// 用这个变量存当前播放音频的唯一标识,比如音频的文件路径、数据库ID都可以 private String currentAudioTag; // 记录当前是否处于播放状态 private boolean isPlayingNow = false; // 对外提供方法,让Activity能拿到当前播放的音频标识 public String getCurrentAudioTag() { return currentAudioTag; } // 对外提供方法,判断当前是否在播放 public boolean isPlaying() { return isPlayingNow; }
然后在你播放音频的方法里,先做个判断:
// 假设你的播放方法叫playTargetAudio,参数是选中音频的标识 public void playTargetAudio(String audioTag) { // 如果当前正在播的就是这首,直接返回,啥也不做 if (isPlayingNow && audioTag.equals(currentAudioTag)) { return; } // 不是同一首的话,先停掉当前播放(如果有的话) stopCurrentPlay(); // 更新状态记录 currentAudioTag = audioTag; isPlayingNow = true; // 接下来执行你的播放逻辑,比如初始化MediaPlayer、设置数据源这些 // ... } // 停止播放的时候别忘了更新状态 private void stopCurrentPlay() { // 这里写你原来的停止播放逻辑,比如mediaPlayer.stop()、release()之类的 // ... isPlayingNow = false; }
第二步:让Activity和Service“牵上线”
因为Activity和Service是分开运行的,得用Binder让它们能互相调用方法。
1. 在Service里写个自定义Binder
public class AudioBinder extends Binder { public AudioPlayerService getServiceInstance() { return AudioPlayerService.this; } } // 实例化这个Binder private final IBinder audioBinder = new AudioBinder(); @Override public IBinder onBind(Intent intent) { return audioBinder; }
2. 在Activity里绑定Service,拿到Service实例
private AudioPlayerService playerService; private boolean isServiceConnected = false; // 绑定Service的回调 private ServiceConnection serviceConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { AudioPlayerService.AudioBinder binder = (AudioPlayerService.AudioBinder) service; playerService = binder.getServiceInstance(); isServiceConnected = true; } @Override public void onServiceDisconnected(ComponentName name) { playerService = null; isServiceConnected = false; } }; // 在Activity启动的时候绑定Service @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 你的其他初始化代码 // ... Intent serviceIntent = new Intent(this, AudioPlayerService.class); bindService(serviceIntent, serviceConn, Context.BIND_AUTO_CREATE); } // 销毁Activity的时候记得解绑 @Override protected void onDestroy() { super.onDestroy(); if (isServiceConnected) { unbindService(serviceConn); isServiceConnected = false; } }
3. 处理音频点击事件
现在在你点击音频的地方,加个判断逻辑就行:
// 假设你选中的音频标识是selectedAudioTag,比如从列表里拿到的路径或者ID String selectedAudioTag = "这里填选中音频的唯一标识"; if (isServiceConnected && playerService != null) { // 先判断:是不是正在播放,而且是同一首? if (playerService.isPlaying() && selectedAudioTag.equals(playerService.getCurrentAudioTag())) { // 是同一首正在播,直接返回,啥也不做 return; } else { // 不是同一首,或者没在播,调用Service的播放方法 playerService.playTargetAudio(selectedAudioTag); } } else { // 如果还没绑定Service,先启动Service再传音频标识过去 Intent serviceIntent = new Intent(this, AudioPlayerService.class); serviceIntent.putExtra("SELECTED_AUDIO", selectedAudioTag); startService(serviceIntent); // 这里也可以重新绑定一下Service,确保后续能拿到状态 }
额外小提示
如果你用的是Android自带的MediaPlayer,其实可以直接用mediaPlayer.isPlaying()来判断播放状态,不用自己维护isPlayingNow变量,但currentAudioTag还是得存,用来判断是不是同一首。另外,在Service销毁的时候,记得把currentAudioTag置空,状态重置,避免内存泄漏~
这样处理之后,点击正在播放的音频就不会从头播啦,只有点不同的音频才会切换播放,完美解决你的需求!
内容的提问来源于stack exchange,提问作者Ugy Astro
相关产品推荐
相关产品推荐

