Android中播放音频,除了使用MediaPlayer,还可以使用SoundPool。SoundPool使用音效池的概念来管理多个短促的音效,对于需要短促的提示音的场景特别合适。

通常调用SoundPool.load来加载某个音频文件,获得一个音效id,然后就可以用play方法来播放。

SoundPool的play方法原型如下:

int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate);

play方法第二、三个参数用于指定左右声道的音量,取值范围是0.0~1.0。这里要说的就是这个音量值与系统音量的关系。

比如你使用AudioManager.STREAM_MUSIC或者AudioManager.STREAM_VOICE_CALL来播放提示音,此时的媒体音量或通话音量为 A (AudioManager.getStreamVolume(AudioManager.STREAM_MUSIC),那使用SoundPool.play方法播放音效时,实际的音量大小,就相当于:

leftVolume * A

注意,实际的音量效果,是乘积关系

下面是网上流传的一段代码,其中对音量的设置就存在一个容易忽略的Bug:

AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
int currentVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
int maxVolume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = ((float)currentVolume)/maxVolume;
...
mSoundPool.play(soundID, volume, volume, 1, -1, 1);

上面的代码根据当前媒体音量和媒体音量的最大值,计算出一个比值传递给play方法,作为左右声道的音量,这样的结果是缩小了实际音量!尤其是(Bug),你在播放开始前将媒体音量调整为0,开始播放后,你将听不到声音!此时你再通过音量键调整音量,也听不到声音!(我今天刚解了一个类似的Bug)

所以,如果想按照用户设置的音量来播放音效,正确的做法是:

mSoundPool.play(soundID, 1, 1, 1, -1, 1);

而如果想按系统设置音量的一半来播放音效,则可以用类似下面的代码:

mSoundPool.play(soundID, 0.5f, 0.5f, 1, -1, 1);

Android开发文档没有SoundPool.play的音量参数做详尽的说明,不过我们自己需要注意哦,否则就容易出现问题。

Android SoundPool.play方法的音量与系统音量的关系的更多相关文章

  1. iOS 设置系统音量和监听系统音量变化

    很简单的调用 首先在工程引入MediaPlayer.framework #import <MediaPlayer/MediaPlayer.h> 1. 获取系统音量 // 获取系统音量 MP ...

  2. android小工具-系统音量管理器

    简介:调节系统音量的小工具,能够快捷的调节系统铃声,媒体音乐.闹钟和通话声音.你可能会想,手机自带的音量键还不够快捷吗?还得写个程序?首先,用音量键调音只能调节一种声音,像闹钟这种声音不能直接调.其次 ...

  3. Android 高版本API方法在低版本系统上的兼容性处理

    Android 版本更替,新的版本带来新的特性,新的方法. 新的方法带来许多便利,但无法在低版本系统上运行,如果兼容性处理不恰当,APP在低版本系统上,运行时将会crash. 本文以一个具体的例子说明 ...

  4. [转]JS调用Android里面的方法,Android调用JS里面的方法

    FROM : http://blog.csdn.net/hj563308597/article/details/45197709 Android WebView 在公司Android的开发过程中遇到一 ...

  5. Android编程: 调试方法

    学习知识:Android的调试方法 ====调试方法==== 前提: IDE环境为Android Studio,熟悉LogCat,知道如何查看日志信息 工具: Android DDMS调试工具,一般点 ...

  6. 基于Android 4.4 开发的多窗体系统 开放源代码

    Hi, 这是我基于Android 4.4开发的多窗体系统,还有非常多不足,还请多多不吝赐教啊,代码已经所有开源. 视频地址 源代码地址 Done: 1. APP以窗体化显示 在 PhoneWindow ...

  7. iOS编程修改系统音量

    iOS的AVFoundation框架提供了基本的音视频播放工具,我们基本上可以靠其中提供的类完成绝大部分的音视频播放任务.但是在音频播放的输出音量的处理上,苹果的策略比较保守.尽管AVPlayer和A ...

  8. NDK Android* 应用移植方法

    概述 本指南用于帮助开发者将现有的基于 ARM* 的 NDK 应用移植到 x86.假设您已经拥有一个正常执行的应用,须要知道怎样可以高速让 x86 设备在 Android* Market 中找到您的应 ...

  9. Android root检测方法小结

    转载目的,之前主要应用这里的原理解决了,手机被某个APP检测为root过的手机的问题,记录后续可能参考. 出于安全原因,我们的应用程序不建议在已经root的设备上运行,所以需要检测是否设备已经root ...

随机推荐

  1. php-fpm的重启/关闭

    php 5.3.3 下的php-fpm 不再支持 php-fpm 以前具有的 /usr/local/php/sbin/php-fpm (start|stop|reload)等命令,需要使用信号控制: ...

  2. netty4 连通步骤

    转载:http://xw-z1985.iteye.com/blog/1973205 服务端依次发生的步骤 建立服务端监听套接字ServerSocketChannel,以及对应的管道pipeline: ...

  3. 在 Linux 中怎样将 MySQL 迁移到 MariaDB 上

    自从甲骨文收购 MySQL 后,由于甲骨文对 MySQL 的开发和维护更多倾向于闭门的立场,很多 MySQL 的开发者和用户放弃了 MySQL.在社区驱动下,促使更多人移到 MySQL 的另一个叫 M ...

  4. 标签视图控制器UITabBarController

    标签视图控制器 UITabBarController FirstViewController*first = [[FirstViewController alloc] init]; //创建一个UIT ...

  5. C# 子窗体点击按钮产生的新子窗体放在父窗体里

    情景展示: 父窗体Form1,左边是按钮,右边是panel(放置子窗体) 父窗体点击按钮,在panel显示第一个子窗体AA, AA有个按钮,点击按钮,是第二个子窗体ZZ, 怎样将AA的子窗体ZZ也显示 ...

  6. 2.精通前端系列技术之seajs和gruntJs结合开发(三)

    1.我们先来了解下模块化历史 模块化历史 nodeJS的出现(http://nodejs.org/) commonJS规范(http://www.commonjs.org/) 浏览器JS的模块化? A ...

  7. jquery判断多选框是否选中

    if($("#xieyi").is(":checked")){ alert('选中'); }else{ alert('没有选中') }

  8. (BFS)hdoj2377-Bus Pass

    题目地址 因为最后要看的是到所有路线上的区域最大距离最小的中心点,所以可以采取遍历路线上所有的区域,对每个区域进行BFS的办法.为了更方便的在每一次BFS都遍历所有的区域,可以加一个reach数组,记 ...

  9. 数据结构-AVL树的旋转

    http://blog.csdn.net/GabrieL1026/article/details/6311339 平衡二叉树在进行插入操作的时候可能出现不平衡的情况,AVL树即是一种自平衡的二叉树,它 ...

  10. UITableViewCell Property “icon” cannot be found in forward class object “DJWeiBo”

    UITableViewCell 自定义表格 实体属性不显示错误 Property “icon” cannot be found in forward class object “DJWeiBo”引入实 ...