zoukankan      html  css  js  c++  java
  • Android中的Audio播放:控制Audio输出通道切换

    Audio 输出通道有很多,Speaker、headset、bluetooth A2DP等。通话或播放音乐等使用Audio输出过程中,可能发生Audio输出通道的切换。比如,插入有线耳机播放音乐时,声音是从耳机发出的;而此时拔出耳机,Audio输出通道会发生切换。如果音乐播放器不做处理,Audio输出是被切换到扬声器的,声音直接从Speaker发出。我们在编写程序时,要捕获并按照需求来处理这样的事,本文就是讲解如何处理的。

    Android中可以通过android.media.AudioManager查询当前Audio输出的情况,并且在Audio输出发生变化时,捕获并处理这种变化。

    AudioNoisy AudioManager

     

    一、Audio输出状态查询与控制

    android.media.AudioManager提供的下列方法可以用来查询当前Audio输出的状态:

     

    •  isBluetoothA2dpOn():检查A2DPAudio是否通过蓝牙耳机;
    •  isSpeakerphoneOn():检查扬声器是否打开;
    •  isWiredHeadsetOn():检查线控耳机是否连着;注意这个方法只是用来判断耳机是否是插入状态,并不能用它的结果来判定当前的Audio是通过耳机输出的,这还依赖于其他条件。

     

     

     

    另外还有一些设置这些Audio输出的setXYZ()方法,这些方法在一般使用Audio输出的应用程序不要直接调用,他们由系统来管理,实现Audio输出通道的自动切换。除非,界面提供给用户切换的菜单或按钮,而用户选择了却换,比如要直接选择扬声器发声,可直接调用setSpeakerphoneOn()。

     

    二、Audio输出通道切换的事件的捕获与处理

    因为耳机插拔、蓝牙耳机的断开,Audio输出通路会自动切换。此时正在播放Audio的程序要获得通知,知道这一事件的发生。Android中是通过广播ACTION_AUDIO_BECOMING_NOISY这个Intent通知的。

    处理广播的较好的方式,是动态注册/注销自己所关心的广播。下面代码演示了,开始播放时注册广播的Receiver;停止播放时注销广播的Receiver。对Audio输出通道切换的处理是暂停当前的播放,不直接从新的通道里发出声来。

    [java] view plaincopy
     
    1. private class NoisyAudioStreamReceiver extends BroadcastReceiver {  
    2.     @Override  
    3.     public void onReceive(Context context, Intent intent) {  
    4.         if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {  
    5.             // Pause the playback   
    6.         }  
    7.     }  
    8. }  
    9.   
    10. private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);  
    11.   
    12. private void startPlayback() {  
    13.     registerReceiver(myNoisyAudioStreamReceiver(), intentFilter);  
    14. }  
    15.   
    16. private void stopPlayback() {  
    17.     unregisterReceiver(myNoisyAudioStreamReceiver);  
    18. }  
    [java] view plaincopy
     
    1. private class NoisyAudioStreamReceiver extends BroadcastReceiver {  
    2.     @Override  
    3.     public void onReceive(Context context, Intent intent) {  
    4.         if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {  
    5.             // Pause the playback  
    6.         }  
    7.     }  
    8. }  
    9.   
    10. private IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);  
    11.   
    12. private void startPlayback() {  
    13.     registerReceiver(myNoisyAudioStreamReceiver(), intentFilter);  
    14. }  
    15.   
    16. private void stopPlayback() {  
    17.     unregisterReceiver(myNoisyAudioStreamReceiver);  
    18. }

     

    三、Audio输出通道切换的典型场景—— 用耳机听音乐时,拔出耳机

    听耳机听音乐时,耳机别拔出的时序图如下:

    AudioNoisy_Sequence.jpg

    图中:

     

    •  AudioNoisy Client注册了侦听广播AudioManager.ACTION_AUDIO_BECOMING_NOISY;
    •  用耳机一直在听音乐;
    •  HeadsetObserver一直在监视耳机状态的变化。检测到耳机被拔出之后,发出广播AudioManager.ACTION_AUDIO_BECOMING_NOISY;
    •  AudioNoisy Client收到了广播,发送暂停命令给MediaPaybackService去暂停当前的播放。

    小结

            Audio 输出通道切换时,要根据具体需求来做相应的处理。

  • 相关阅读:
    NET打包時加入卸载功能
    c#水晶报表注册码
    sqlserver:某年份某月份 是否在某时间段内的函数
    修改KindEditor编辑器 版本3.5.1
    Flash大文件上传(带进度条)
    让.Net程序脱离.net framework框架运行的方法(转载)
    夏天到了,什么时候园子的T恤可以出来?
    VS2005项目的安装与布署
    解决Select覆盖Div的简单直接的方法
    .Net向Page和UpdatePanel输出JS
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4562548.html
Copyright © 2011-2022 走看看