当前位置: 首页 > news >正文

【Android Audio Focus 音频焦点】

介绍

Android 中的音频焦点(Audio Focus)是一种机制,用于管理应用程序之间的音频资源竞争。当多个应用程序同时请求使用音频设备时,通过音频焦点机制可以确保最终用户的体验不受影响。

两个或两个以上的 Android 应用可同时向同一输出流播放音频。系统会将所有音频流混合在一起。虽然这是一项出色的技术,但却会给用户带来很大的困扰。为了避免所有音乐应用同时播放,Android 引入了“音频焦点”的概念。 一次只能有一个应用获得音频焦点。

当您的应用需要输出音频时,它需要请求获得音频焦点,获得焦点后,就可以播放声音了。不过,在您获得音频焦点后,您可能无法将其一直持有到播放完成。其他应用可以请求焦点,从而占有您持有的音频焦点。如果发生这种情况,您的应用应暂停播放或降低音量,以便于用户听到新的音频源。

音频焦点采用合作模式。我们建议应用遵守音频焦点准则,但系统不会强制执行这些准则。如果应用想要在失去音频焦点后继续大声播放,系统无法阻止它。这是一种不好的体验,用户很可能会卸载具有这种不良行为的应用。


焦点事件

  • AUDIOFOCUS_GAIN
    说明: 应用获得了音频焦点,可以继续播放音频。
    处理方式: 在这个状态下,应用可以正常播放音频。在失去焦点后再次获取焦点时,通常需要在这个状态下恢复播放。

  • AUDIOFOCUS_LOSS
    说明: 【永久性失去焦点】应用失去了音频焦点,需要停止音频播放。
    处理方式: 当收到 AUDIOFOCUS_LOSS 时,应用应该停止播放音频,并释放相关资源。这种情况通常是由于其他应用请求了长时间的音频焦点,例如开始播放长时间的音频文件。不要立即尝试重新获取焦点。

  • AUDIOFOCUS_LOSS_TRANSIENT
    说明: 【暂时性失去焦点】应用短暂失去了音频焦点,但可以在稍后重新获取焦点。
    处理方式: 当收到 AUDIOFOCUS_LOSS_TRANSIENT 时,应用应该暂停音频播放。这种情况通常是由于短暂的通知声、铃声等情况导致的。应用通常会在稍后重新获取焦点并恢复播放。

  • AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
    说明: 【暂时性失去焦点】应用短暂失去了音频焦点,但可以降低音量继续播放。稍后可以重新获取焦点。
    处理方式: 当收到 AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK 时,应用可以选择降低音量而不是完全停止音频播放。这种情况通常用于在接收短暂通知时,应用可以继续以较低的音量播放。

暂时性失去焦点:

在暂时性失去音频焦点时,您应该继续监控音频焦点的变化,并准备好在重新获得焦点后恢复正常播放。当抢占焦点的应用放弃焦点时,您会收到一个回调 (AUDIOFOCUS_GAIN)。此时,您可以在此回调中,将音量恢复到正常水平或重新开始播放。

永久性失去焦点:

如果是永久性失去音频焦点 (AUDIOFOCUS_LOSS),则其他应用会播放音频。您的应用应立即暂停播放,因为它不会收到 AUDIOFOCUS_GAIN 回调。要想重新开始播放,用户必须执行明确的操作,例如在通知或应用界面中按播放传输控件。


代码示例

Android 8.0 及更高版本中的音频焦点:

从 Android 8.0(API 级别 26)开始,当您调用 requestAudioFocus() 时,必须提供 AudioFocusRequest 参数。要释放音频焦点,请调用 abandonAudioFocusRequest() 方法,该方法也接受 AudioFocusRequest 作为参数。在请求和放弃焦点时,应使用相同的 AudioFocusRequest 实例。

要创建 AudioFocusRequest,请使用 AudioFocusRequest.Builder。由于焦点请求始终必须指定请求的类型,因此此类型会包含在构建器的构造函数中。使用构建器的方法来设置请求的其他字段。

    audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManagerfocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run {setAudioAttributes(AudioAttributes.Builder().run {setUsage(AudioAttributes.USAGE_MEDIA)//or AudioAttributes.USAGE_GAMEsetContentType(AudioAttributes.CONTENT_TYPE_MUSIC)build()})setAcceptsDelayedFocusGain(true)setOnAudioFocusChangeListener(afChangeListener, handler)build()}val focusLock = Any()var playbackDelayed = falsevar playbackNowAuthorized = false// ...val res = audioManager.requestAudioFocus(focusRequest)synchronized(focusLock) {playbackNowAuthorized = when (res) {AudioManager.AUDIOFOCUS_REQUEST_FAILED -> falseAudioManager.AUDIOFOCUS_REQUEST_GRANTED -> {playbackNow()true}AudioManager.AUDIOFOCUS_REQUEST_DELAYED -> {playbackDelayed = truefalse}else -> false}}val afChangeListener = AudioManager.OnAudioFocusChangeListener { focusChange ->when (focusChange) {AudioManager.AUDIOFOCUS_LOSS -> {// Permanent loss of audio focus. Pause playback immediatelysynchronized(focusLock) {resumeOnFocusGain = falseplaybackDelayed = false}pausePlayback()}AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {// Pause playbacksynchronized(focusLock) {resumeOnFocusGain = trueplaybackDelayed = false}pausePlayback()}AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {// ... pausing or Lower the volume depends on your app}AudioManager.AUDIOFOCUS_GAIN -> {// Your app has been granted audio focus again// Raise volume to normal, restart playback if necessaryif (playbackDelayed || resumeOnFocusGain) {synchronized(focusLock) {playbackDelayed = falseresumeOnFocusGain = false}playbackNow()}}}}

官方文档链接管理音频焦点

相关文章:

【Android Audio Focus 音频焦点】

介绍 Android 中的音频焦点(Audio Focus)是一种机制,用于管理应用程序之间的音频资源竞争。当多个应用程序同时请求使用音频设备时,通过音频焦点机制可以确保最终用户的体验不受影响。 两个或两个以上的 Android 应用可同时向同…...

ChatGPT一周年,一图总结2023生成式AI里程碑大事件时间线

带你探索AI的无限可能!AI一日,人间一年,这句话绝非空谈! AI技术在不断地发展,让我们一起期待它未来更多的可能性吧! 2022 年 11 月 30 日,OpenAI 宣布正式推出 ChatGPT。365 天过去,…...

Python 接口测试response返回数据对比的方法

背景:之前写的接口测试一直没有支持无限嵌套对比key,上次testerhome逛论坛,有人分享了他的框架,看了一下,有些地方不合适我这边自己修改了一下,部署在jenkins上跑完效果还不错,拿出来分享一下。…...

LainChain 原理解析:结合 RAG 技术提升大型语言模型能力

摘要:本文将详细介绍 LainChain 的工作原理,以及如何通过结合 RAG(Retrieval-Aggregated Generation)技术来增强大型语言模型(如 GPT 和 ChatGPT 等)的性能。我们将探讨 COT、TOT、RAG 以及 LangChain 的概…...

6-6 堆排序 分数 10

typedef int Datatype; typedef struct {Datatype* elem; int Length; }SqList; typedef SqList HeapType; void swap(int* a, int* b) {int tmp *a;*a *b;*b tmp; } //建大堆 //m: 结点个数 s: 待下调父结点下标 void HeapAdjust(HeapType H, int s, int m) {int child …...

高翔《自动驾驶与机器人中的SLAM技术》第九、十章载入静态地图完成点云匹配重定位

修改mapping.yaml文件中bag_path: 完成之后会产生一系列的点云文件以及Keyframe.txt文件: ./bin/run_frontend --config_yaml ./config/mapping 生成拼接的点云地图map.pcd文件 : ./bin/dump_map --pose_sourcelidar 。、 完成第一次优…...

英语六级翻译

1. 青海是中国西北部的一个省份,平均海拔 3000 以上,大部分地区为高山和高原。青海省得名全国最大的咸水湖青海湖。青海湖被誉为“中国最美的湖泊”,是最受欢迎的旅游景点之一,也是摄影师和艺术家的天堂。 青海山川壮丽,地大物博。石油和天然气储量丰富,省内许多城市的…...

VMware配置Ubuntu虚拟机

目录标题 1. 相关问题 1. 相关问题 Ubuntu虚拟机与主机能ping通,但是xftp无法连接 解决:Ubuntu安装 OpenSSH 服务器:sudo apt install openssh-server...

Backtrader 文档学习-Platform Concepts

Backtrader 文档学习-Platform Concepts 1.开始之前 导入backtrader ,以及backtrader 的指示器、数据反馈的模块 。 import backtrader as bt import backtrader.indicators as btind import backtrader.feeds as btfeeds看看btind模块下有什么方法和属性&#x…...

策略模式(常用)

策略模式的简介 在软件开发中,设计模式是为了解决常见问题而提供的一套可重用的解决方案。策略模式(Strategy Pattern)是其中一种常见的设计模式,它属于行为型模式。该模式的核心思想是将不同的算法封装成独立的策略类&#xff0c…...

Express中使用Swagger

Swagger Swagger 是一种规范,用于描述 API 的结构,功能和参数。使用 Swagger 可以提供清晰的可视化 API 文档,可用于 API 交互的文档驱动开发,以及 API 的自动化测试和集成。 使用 npm 或 yarn 下载。 npm install swagger-jsdo…...

【C++】单一职责模式

目录 一、简介1. 含义2. 特点 二、实现1. 将类拆分成多个类2. 使用命名空间(Namespace)3. 使用组合而不是继承 三、总结如果这篇文章对你有所帮助,渴望获得你的一个点赞! 一、简介 1. 含义 在面向对象设计中,单一职责…...

GPT4-隐者地址

网址 https://evo.ninja/测试是否是GPT4 https://blog.csdn.net/fyfugoyfa/article/details/130254735...

教师考编需要什么条件

教师考编,了解考编需要什么条件是非常重要的。接下来,我来介绍几点教师考编的条件。 需要具备相应的学历背景。一般来说,考编需要具备本科或以上学历,并且所学专业与所报考的岗位相关。在某些特殊情况下,如报考幼儿园教…...

刘家窑中医医院鲁卫星主任:冬季守护心脑血管,为社区居民送去健康关爱

随着冬季的来临,气温逐渐降低,心脑血管疾病的风险也随之增加。为了提高公众对心脑血管疾病的认知和预防意识,北京刘家窑中医医院于近日成功举办了冬季守护心脑血管公益义诊活动。 本次义诊活动主要针对社区居民中的中老年人,特别是…...

专家级定位咨询:打造不可复制的市场地位

在这个快速变化的商业环境中,每个品牌都渴望在市场中占据一个独一无二的位置。但是,真正实现这一点并非易事。这就是为什么专家级定位咨询如此重要:它不仅帮助品牌发现其独特之处,还能指导它们如何有效地利用这一优势来在市场中脱…...

为什么说代码注释是程序员必备的技能?

代码注释是对代码中的特定部分或整体功能的解释和说明。注释添加在代码中,是给程序员看的,当系统运行程序,读取注释时会越过不执行。随着技术的发展,现在具有百万行代码的程序已经很常见了,在这样一个大型的代码中&…...

日期——年月日星期时间封装和年月日时间封装

年月日星期时间 function nowDate(time) {var getTime new Date().getTime(); //获取到当前时间戳var time new Date(getTime); //创建一个日期对象var year time.getFullYear(); // 年let wk new Date().getDay()var month (time.getMonth() 1).toString().padStart(2, …...

RK3568全国产化多网口板卡带poe供电,支持鸿蒙麒麟系统

信迈XM-3568-01主板采用瑞芯微RK3568四核Cortex-A55 处理器,主频最高可达2.0GHz,效能有大幅提升最高可配8GB内存容量,频率高达1600MHz;支持全链路ECC,让数据更安全可靠配置双千兆自适应RJ45以太网口,并扩展…...

UI卡顿问题

1、 监测卡顿的方式 a、Xcode 层级关系是否有异常 b、 instruments 的Animation Hitch工具检测:碰到问题,录制完了无数据(用iphone7录制有数据的,iphne14录制无数据?) 2、可能导致的卡顿的原因 a、 直播广…...

解决RK3588安装OpenCV时libjasper-dev缺失问题:Ubuntu20.04特殊源配置教程

RK3588平台OpenCV安装困境:深度解析libjasper-dev缺失问题与多维度解决方案 在RK3588平台上部署计算机视觉应用时,OpenCV作为核心依赖库的安装过程往往成为开发者的第一个"拦路虎"。特别是在Ubuntu 20.04环境下,当执行标准的sudo a…...

九、《算力架构新范式:华为CloudMatrix384超节点如何重塑AI推理经济模型》——从2300 Tokens/s看系统级创新的降本增效逻辑

1. 从2300 Tokens/s看算力架构的经济学革命 当AI推理的Token消耗量在18个月内激增300倍时,企业突然发现:传统算力架构的成本曲线正在失控。我最近测试某开源大模型时,单次推理成本高达传统方案的4倍——直到接触华为CloudMatrix384超节点&…...

Go UUID终极指南:为什么选择go.uuid而非标准库的5大理由

Go UUID终极指南:为什么选择go.uuid而非标准库的5大理由 【免费下载链接】go.uuid UUID package for Go 项目地址: https://gitcode.com/gh_mirrors/go/go.uuid 在Go语言开发中,生成全局唯一标识符(UUID)是常见的需求。虽然…...

AsyncAPI通道管理终极指南:如何高效组织消息流的关键技巧

AsyncAPI通道管理终极指南:如何高效组织消息流的关键技巧 【免费下载链接】spec The AsyncAPI specification allows you to create machine-readable definitions of your asynchronous APIs. 项目地址: https://gitcode.com/gh_mirrors/spec/spec AsyncAPI…...

PP-DocLayoutV3入门指南:从零开始理解bbox坐标、label_id、score字段含义

PP-DocLayoutV3入门指南:从零开始理解bbox坐标、label_id、score字段含义 1. 前言:为什么你需要了解这些字段? 如果你刚开始接触文档布局分析,看到PP-DocLayoutV3输出的JSON数据,可能会对里面那些bbox、label_id、sc…...

Notepad4:轻量级编辑器的技术突破与实用指南

Notepad4:轻量级编辑器的技术突破与实用指南 【免费下载链接】notepad2 Notepad2-zufuliu is a light-weight Scintilla based text editor for Windows with syntax highlighting, code folding, auto-completion and API list for many programming languages and…...

Qwen2-VL-2B-Instruct在Qt桌面应用中的集成:开发跨平台图像分析工具

Qwen2-VL-2B-Instruct在Qt桌面应用中的集成:开发跨平台图像分析工具 1. 引言 如果你是做桌面应用开发的,特别是用C和Qt的,最近可能也注意到了AI模型带来的新机会。很多开发者都在想,怎么把这些强大的AI能力,比如看图…...

别再傻傻匀速拖滑块了!用Python模拟真人鼠标轨迹,轻松过Geetest验证码

突破验证码防线:Python模拟人类行为轨迹的实战艺术 验证码系统正变得越来越智能,Geetest等平台已经能够通过分析用户行为模式来区分人类和机器。传统的匀速滑块操作在这些系统面前几乎无所遁形。本文将带你深入理解现代验证码系统的工作原理,…...

LeetCode 102. Binary Tree Level Order Traversal 题解

LeetCode 102. Binary Tree Level Order Traversal 题解 题目描述 给你二叉树的根节点 root,返回其节点值的 层序遍历。 (即逐层地,从左到右访问所有节点)。 示例 1: 输入:root [3,9,20,null,null,15,7] 输…...

告别单行代码:在Python IDLE中编写完整函数的完整指南

告别单行代码:在Python IDLE中编写完整函数的完整指南 对于刚接触Python的开发者来说,IDLE是一个既熟悉又陌生的环境。熟悉是因为它随Python安装包一起提供,陌生则是因为很多人仅仅把它当作一个简单的交互式Shell,而忽略了它作为完…...