实测Android音频的焦点获取和归还

这篇具有很好参考价值的文章主要介绍了实测Android音频的焦点获取和归还。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实测Android音频的焦点获取和归还

实测Android音频的焦点获取和归还

前言

最近老板想在产品中的短视频后者直播播放的时候对于手机中的音乐播放器进行暂停播放,并且退出视频播放后手机的音乐播放器还能继续播放之前的音乐。

先试试微信,emmm,确实可以。

Android官网:管理音频焦点

官网管理音频焦点准则:

  • 在即将开始播放之前调用 requestAudioFocus(),并验证调用是否返回 AUDIOFOCUS_REQUEST_GRANTED。如果按照本指南中的说明设计应用,则应在媒体会话的 onPlay() 回调中调用 requestAudioFocus()
  • 在其他应用获得音频焦点时,停止或暂停播放,或降低音量。
  • 播放停止后,放弃音频焦点。

不同版本音频焦点的处理方式不太相同:

  • 从 Android 2.2(API 级别 8)开始,应用通过调用 requestAudioFocus()abandonAudioFocus() 来管理音频焦点。应用还必须为这两个调用注册 AudioManager.OnAudioFocusChangeListener,以便接收回调并管理自己的音量。

  • 对于以 Android 5.0(API 级别 21)及更高版本为目标平台的应用,音频应用应使用 AudioAttributes 来描述应用正在播放的音频类型。例如,播放语音的应用应指定 CONTENT_TYPE_SPEECH

  • 面向 Android 8.0(API 级别 26)或更高版本的应用应使用 requestAudioFocus() 方法,该方法会接受 AudioFocusRequest 参数。AudioFocusRequest 包含有关应用的音频上下文和功能的信息。系统使用这些信息来自动管理音频焦点的得到和失去。

API介绍

处理音频焦点都是通过AudioManager这个类,如下是获得该类实例的方法:
AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);

requestAudioFocus()//用于申请音频焦点
abandonAudioFocus() //用于释放音频焦点
AudioManager.OnAudioFocusChangeListener 接口,提供了 onAudioFocusChange() 方法来监听音频焦点变化

  • requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)参数:

    • AudioManager.OnAudioFocusChangeListener l
      用于监听音频焦点变化,从而可以进行适当的操作,例如暂停播放等。

    • streamType
      申请音频焦点处理的音频类型,例如,当播放音乐时,可以传入 STREAM_MUSIC ;当播放铃声时,可以传入 STREAM_RING 。表中列出了一些的可选值:

      类型 含义
      STREAM_VOICE_CALL 通话 0
      STREAM_SYSTEM 系统 1
      STREAM_RING 铃声 2
      STREAM_MUSIC 音乐 3
      STREAM_ALARM 闹铃 4
      STREAM_NOTIFICATION 系统通知 5
    • durationHint (PS:重要参数):
      可选值有以下五个:
      (1) AUDIOFOCUS_GAIN: 此参数表示希望申请一个永久的音频焦点,并且希望上一个持有音频焦点的App停止播放;例如在需要播放音乐时。
      (2) AUDIOFOCUS_GAIN_TRANSIENT:表示申请一个短暂的音频焦点,并且马上就会被释放,此时希望上一个持有音频焦点的App暂停播放。例如播放一个提醒声音。
      (3) AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:效果同 AUDIOFOCUS_GAIN_TRANSIENT ,只是希望上一个持有焦点的App减小其播放声音(但仍可以播放),此时会混音播放。例如导航播报。
      (4) AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: 表示申请一个短暂的音频焦点,并且会希望系统不要播放任何突然的声音(例如通知,提醒等),例如用户在录音。

    • 返回值:
      AUDIOFOCUS_REQUEST_GRANTED 或者 AUDIOFOCUS_REQUEST_FAILED

  • abandonAudioFocus(OnAudioFocusChangeListener l) 参数通上 AudioManager.OnAudioFocusChangeListener .

  • AudioManager.OnAudioFocusChangeListener :当音频焦点发生变化时进行 onAudioFocusChange(int focusChange) 方法的回调;

new AudioManager.OnAudioFocusChangeListener() {
  @Override
  public void onAudioFocusChange(int focusChange) {
    switch (focusChange) {
      case AudioManager.AUDIOFOCUS_GAIN:
        // TBD 继续播放
        break;
      case AudioManager.AUDIOFOCUS_LOSS:
        // TBD 停止播放
        break;
      case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
        // TBD 暂停播放
        break;
      case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
        // TBD 混音播放 
        break;
      default:
        break;
    }
  }
};

实测代码:

核心是需要把 AudioManager.AUDIOFOCUS_GAIN 改为 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT

public class MainActivity extends Activity {

    private AudioManager mAudioManager;
    private AudioFocusRequest mFocusRequest;
    private AudioManager.OnAudioFocusChangeListener mListener;
    private AudioAttributes mAttribute;
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        mListener = new AudioManager.OnAudioFocusChangeListener() {
            @Override
            public void onAudioFocusChange(int focusChange) {
                switch (focusChange) {
                    case AudioManager.AUDIOFOCUS_GAIN:
                       // TBD 继续播放
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS:
                       // TBD 停止播放
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                        // TBD 暂停播放
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                        // TBD 混音播放 
                        break;
                    default:
                        break;
                }

            }
        };
        //android 版本 5.0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mAttribute = new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_MEDIA)
                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                    .build();
        }
        //android 版本 8.0
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
                    .setWillPauseWhenDucked(true)
                    .setAcceptsDelayedFocusGain(true)
                    .setOnAudioFocusChangeListener(mListener, mHandler)
                    .setAudioAttributes(mAttribute)
                    .build();
        }
    }
    private void requestAudioFocus() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
					mAudioManager.requestAudioFocus(mFocusRequest);
        } else {
          mAudioManager.requestAudioFocus(mListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
        }
    }
    private void abandonAudioFocus() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            mAudioManager.abandonAudioFocusRequest(mFocusRequest);
        } else {
          mAudioManager.abandonAudioFocus(mListener);
        }

    }
}

参考:

https://segmentfault.com/a/1190000022234509

https://www.jianshu.com/p/26ea60c499a7

文章到这里就全部讲述完啦,若有其他需要交流的可以留言哦~!~!

想阅读作者的更多文章,可以查看我 个人博客 和公共号:
实测Android音频的焦点获取和归还文章来源地址https://www.toymoban.com/news/detail-406175.html

到了这里,关于实测Android音频的焦点获取和归还的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android EditText 获取/失去焦点

    项目的需求中,又一个4位数的验证码界面,小弟才疏学浅,只想到了用 线性布局里面放四个EditText 。 需求需要输入内容后,自动跳到下一个位置聚焦,删除指定位置后,自动跳到上一个位置聚焦,由于聚焦/非聚焦UI展示得都不同,所以每个editText都会频繁的设置焦点变化。

    2024年02月03日
    浏览(43)
  • 搞懂Druid之连接获取和归还

    Druid 是阿里开源的数据库连接池,是阿里监控系统 Dragoon 的副产品,提供了强大的可监控性和基于 Filter-Chain 的可扩展性。 本篇文章将对 Druid 数据库连接池的 连接获取 , 归还 和 连接泄漏检测 进行分析。分析 Druid 数据库连接池的源码前,需要明确几个概念。 Druid 数据库连

    2024年02月05日
    浏览(36)
  • 理解音频焦点 (第1_3部分):常见的音频焦点用例

    译者:oaosj Android手机支持多个应用同时播放音频。操作系统会把多个音频流混合在一起播放,但是多个应用同时播放音频,给用户带来的体验往往不佳。为了提供更友好的用户体验,Android提供了一个API,让应用程序可以共享 音频焦点 ,旨在保证同一时段内只有一个应用可以

    2024年04月12日
    浏览(55)
  • Android12 获取音频输出列表&设置音频输出通道

    有个需求是APP端能够获取所有音频输出列表,研究了很长时间源码,发现只有这个API合适。 这个API能够获取到设备上所有可用的输出,且APP可以调用。 需要在framework层修改,找一个Manager或者自己写一个Manager,添加以下API方法。

    2024年02月16日
    浏览(59)
  • 多媒体音频焦点浅析

    多个音源可以同时向同一个输出流进行播放音频,如果没有音频焦点管控,就会出现多个音源同时播放的现象,给用户带来不便;而Android为了避免多个音源同时播放,就引入了音频焦点的概念,所有音频应用都统一按照音频焦点的规定执行,就可以避免该现象发生。 当应用

    2024年02月13日
    浏览(45)
  • 音频焦点使用及原理

    本博客代码基于Android 10源码 在Android音频领域中,应用层所有的App播放音频,最终都是走到音频回播线程PlaybackThread中,如果多个App都走到同一个PlaybackThread中去,就会出现混音情况,Android本身对混音也有很好的支持,但是也会造成某些重要音频资源播放时,用户听不太清晰

    2024年02月05日
    浏览(32)
  • AAOS 音频焦点请求

    前言 本文章的目标是首先了解Android中音频焦点的基本概念,理解代码中相关音频焦点的使用方法。其次理解AAOS 中相关交互矩阵概念,理解其实现焦点管理的流程。 基本概念 音频焦点的目标是 是确保在多个应用程序同时播放音频时,用户能够顺利地听到他们想要听的声音,

    2024年02月15日
    浏览(46)
  • C# 应用程序强制获取焦点

    Windorm和WPF等应用程序想自己获取焦点焦点那是不可能的,只能通过系统的API来实现 上面第一个函数获取的是当前窗体的句柄,  如果窗体应用要获取自己的句柄的话就使用下面的方法获取 拿到句柄的话我们就可以使用SetForegroundWindow将窗体设置为前台应用 这可以能还不够,

    2024年02月12日
    浏览(34)
  • Element Plus Dialog中无法获取表单焦点

    在Dialog组件中,默认插槽是Form表单,表单子项是input,发现Dialog组件弹出时无法获取input焦点。 需要使用俩次nextTick 使用定时器setTimeout也可以 input获取焦点老生常谈的问题,直接一个nextTick完活!这里不行的原因是Dialog里面嵌套是Form表单,Form表单又嵌套的input组件,所以需要俩

    2024年02月12日
    浏览(38)
  • android 窗口焦点介绍

    我们经常会遇到一种 Application does not hava focused window 的 ANR 异常,这种异常一般是没有焦点窗口FocusedWindow导致,且这类异常只会发生在 key事件的派发 ,因为 key事件 是需要找到一个 焦点窗口 然后再派发,而 触摸事件 只需要找到 当前显示的窗口 即可 WMS只管理窗口,无法确定

    2024年02月14日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包