AudioManager详解(结合源代码)

时间:2023-01-05 11:53:08

AudioManager:用来对音量大小,声音模式(静音,震动,震动加声音等模式)的管理, 还有用它来注册“插入耳机”时的广播接收者(Action: android.intent.action.MEDIA_BUTTON)

源码(没有Android源码的可以看下我之前的博文,有提供下载地址哈~)所在位置:
Android-4.0/frameworks/base/media/java/android/media/AudioManager.java


一. 首先在应用层面上分析下怎么使用这个类:

1.获取AudioManager实例对象
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);

2.AudioManager能实现的一些基本的功能的函数介绍

adjustStreamVolume(int streamType, int direction, int flags)
/**
方法分析:(通过该方法可以控制特定的声音的音量)

用"步长"调整手机声音大小的函数(Adjusts the volume of a particular stream by one step in a direction.)
这个函数只能用于应用程序对Audio属性的设置或者通话(telephony)应用程序

streamType(表示要处理的声音是哪种):
    能使用的streamType的值包括:
    STREAM_VOICE_CALL(通话)
    STREAM_SYSTEM(系统声音)
    STREAM_RING(铃声)
    STREAM_MUSIC(音乐)
    STREAM_ALARM(闹铃)
    
direction(“方向”:顾名思义是要往上增加音量,往下减少音量,还是维持不变):
    能使用的值有:
    ADJUST_LOWER(降低)
    ADJUST_RAISE(升高)
    ADJUST_SAME(维持原来的)[呵~~呵]

flags(可选标志位):
    flags One(单个参数) or more flags.(参数1|参数2|参数3..)
    如下flag:
        AudioManager.FLAG_SHOW_UI(显示出音量调节UI)
        AudioManager.FLAG_ALLOW_RINGER_MODES
        AudioManager.FLAG_PLAY_SOUND
        AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
        AudioManager.FLAG_VIBRATE

对应get方法:
    getStreamVolume(int streamType)
    最大值为7,最小值为0,当为0时,手机自动将模式调整为“震动模式”
*/

adjustVolume(int direction, int flags)
/**
方法分析:
系统智能地判断现在是要处理的是哪个类型的声音("通话音","媒体音"等)
如果你在打电话,这个时候这个函数相应处理的就是"通话音",而如果你在听歌,处理的就是“媒体音”~~平时其实用一些软件也是有这种感觉的哈~~

direction(“方向”:顾名思义是要往上增加音量,往下减少音量,还是维持不变):
    能使用的值有:
    ADJUST_LOWER(降低)
    ADJUST_RAISE(升高)
    ADJUST_SAME(维持原来的)[呵~~呵]

flags(可选标志位):
    flags One(单个参数) or more flags.(参数1|参数2|参数3..)
    如下flag:
        AudioManager.FLAG_SHOW_UI(显示出音量调节UI)
        AudioManager.FLAG_ALLOW_RINGER_MODES
        AudioManager.FLAG_PLAY_SOUND
        AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
        AudioManager.FLAG_VIBRATE

*/

int getMode()
/**
方法分析:
得到声音的模式

返回值(int)对应的宏:
    MODE_INVALID: 发生异常的时候返回
    MODE_NORMAL: 普通模式
    MODE_RINGTONE:铃声模式
    MODE_IN_CALL: 通话模式
    MODE_IN_COMMUNICATION:通话模式

对应set方法:
    setMode(int mode)
*/

int getRingerMode()
/**
方法分析:
得到铃声设置的模式

返回值(int)对应的宏:
    RINGER_MODE_NORMAL(铃声模式)
         RINGER_MODE_SILENT(静音模式)
    RINGER_MODE_VIBRATE(静音但是震动)

对应set方法(改变铃声模式):
    setRingerMode(int ringerMode)
*/

getStreamMaxVolume(int streamType)
/**

方法分析:
    得到手机最大的音量

*/

setStreamMute(int streamType, boolean state)
/**

方法分析:
    让streamType指定的对应的声音流做处理
    state为true表示让它静音,false表示不让它静音
    如:让音乐静音
    setStreamMute(AudioManager.STREAM_MUSIC , true);
*/

3.实例Demo代码

//获取实例
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE); //获取/设置系统音量
audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM);
audioManager.setStreamVolume(AudioManager.STREAM_SYSTEM,
AudioManager.ADJUST_RAISE
, AudioManager.FLAG_SHOW_UI);
//获取/设置音乐音量
audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.ADJUST_RAISE
, AudioManager.FLAG_SHOW_UI);
//其他的类似 //获取/设置铃声的模式
int ringMode = audioManager.getRingerMode();
//普通模式
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
//静音模式
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
//其他的类似 //设置声音流静音/不静音
//音乐静音
audioManager.setStreamMute(AudioManager.STREAM_MUSIC, true);
//铃声不静音
audioManager.setStreamMute(AudioManager.STREAM_RING, false);
//其他的类似

二. 分析下这个类里面的部分源代码

由于知识水平有限,我觉得下面的代码自己分析不好,建议看这篇博文:http://blog.csdn.net/qinjuning/article/details/6938436

 /*
为Action == “MEDIA_BUTTON”注册广播接收者 用来广播“耳机插入”的事件 eventReceiver一般接受的参数为这样一个ComponentName对象 如:
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
ComponentName component = new ComponentName(context.getApplicationContext(),MediaControlReceiver.class);
audioManager.registerMediaButtonEventReceiver(component); */
public void registerMediaButtonEventReceiver(ComponentName eventReceiver) {
if (eventReceiver == null) {
return;
}
if (!eventReceiver.getPackageName().equals(mContext.getPackageName())) {
Log.e(TAG, "registerMediaButtonEventReceiver() error: " +
"receiver and context package names don't match");
return;
}
// construct a PendingIntent for the media button and register it
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
// the associated intent will be handled by the component being registered
mediaButtonIntent.setComponent(eventReceiver);
PendingIntent pi = PendingIntent.getBroadcast(mContext,
0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/);
registerMediaButtonIntent(pi, eventReceiver);
} /**
为MediaButton注册一个Intent
可以发现,这边也是通过aidl的方式进行的调用
IAudioService的aidl:https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/IAudioService.aidl
*/
public void registerMediaButtonIntent(PendingIntent pi, ComponentName eventReceiver) {
if ((pi == null) || (eventReceiver == null)) {
Log.e(TAG, "Cannot call registerMediaButtonIntent() with a null parameter");
return;
}
IAudioService service = getService();
try {
// pi != null
service.registerMediaButtonIntent(pi, eventReceiver);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in registerMediaButtonIntent"+e);
}
} /**
* Unregister the receiver of MEDIA_BUTTON intents.
* @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
* that was registered with {@link #registerMediaButtonEventReceiver(ComponentName)}.
*/
public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) {
if (eventReceiver == null) {
return;
}
// construct a PendingIntent for the media button and unregister it
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
// the associated intent will be handled by the component being registered
mediaButtonIntent.setComponent(eventReceiver);
PendingIntent pi = PendingIntent.getBroadcast(mContext,
0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/);
unregisterMediaButtonIntent(pi, eventReceiver);
} /**
* @hide
*/
public void unregisterMediaButtonIntent(PendingIntent pi, ComponentName eventReceiver) {
IAudioService service = getService();
try {
service.unregisterMediaButtonIntent(pi, eventReceiver);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in unregisterMediaButtonIntent"+e);
}
} /**
* Registers the remote control client for providing information to display on the remote
* controls.
* @param rcClient The remote control client from which remote controls will receive
* information to display.
* @see RemoteControlClient
*/
public void registerRemoteControlClient(RemoteControlClient rcClient) {
if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) {
return;
}
IAudioService service = getService();
try {
service.registerRemoteControlClient(rcClient.getRcMediaIntent(), /* mediaIntent */
rcClient.getIRemoteControlClient(), /* rcClient */
// used to match media button event receiver and audio focus
mContext.getPackageName()); /* packageName */
} catch (RemoteException e) {
Log.e(TAG, "Dead object in registerRemoteControlClient"+e);
}
} /**
* Unregisters the remote control client that was providing information to display on the
* remote controls.
* @param rcClient The remote control client to unregister.
* @see #registerRemoteControlClient(RemoteControlClient)
*/
public void unregisterRemoteControlClient(RemoteControlClient rcClient) {
if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) {
return;
}
IAudioService service = getService();
try {
service.unregisterRemoteControlClient(rcClient.getRcMediaIntent(), /* mediaIntent */
rcClient.getIRemoteControlClient()); /* rcClient */
} catch (RemoteException e) {
Log.e(TAG, "Dead object in unregisterRemoteControlClient"+e);
}
} /**
* @hide
* Registers a remote control display that will be sent information by remote control clients.
* @param rcd
*/
public void registerRemoteControlDisplay(IRemoteControlDisplay rcd) {
if (rcd == null) {
return;
}
IAudioService service = getService();
try {
service.registerRemoteControlDisplay(rcd);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in registerRemoteControlDisplay " + e);
}
} /**
* @hide
* Unregisters a remote control display that was sent information by remote control clients.
* @param rcd
*/
public void unregisterRemoteControlDisplay(IRemoteControlDisplay rcd) {
if (rcd == null) {
return;
}
IAudioService service = getService();
try {
service.unregisterRemoteControlDisplay(rcd);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e);
}
}

AudioManager详解(结合源代码)的更多相关文章

  1. 线程池ThreadPoolExecutor、Executors参数详解与源代码分析

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. ThreadPoolExecutor数据成员 Private final Atom ...

  2. uboot mkimage使用详解

    mkimage使用详解uboot源代码的tools/目录下有mkimage工具,这个工具可以用来制作不压缩或者压缩的多种可启动映象文件. mkimage在制作映象文件的时候,是在原来的可执行映象文件的 ...

  3. 引用 mkimage使用详解

    引用 鱼 的 mkimage使用详解  uboot源代码的tools/目录下有mkimage工具,这个工具可以用来制作不压缩或者压缩的多种可启动映象文件. mkimage在制作映象文件的时候,是在原来 ...

  4. 转载:C/C++源代码到可执行程序的过程详解

    C/C++源代码到可执行程序的过程详解 编译,编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格 ...

  5. Java学习-007-Log4J 日志记录配置文件详解及实例源代码

    此文主要讲述在初学 Java 时,常用的 Log4J 日志记录配置文件详解及实例源代码整理.希望能对初学 Java 编程的亲们有所帮助.若有不足之处,敬请大神指正,不胜感激!源代码测试通过日期为:20 ...

  6. 《TensorFlow学习指南深度学习系统构建详解》英文PDF+源代码+部分中文PDF

    主要介绍如何使用 TensorFlow 框架进行深度学习系统的构建.涉及卷积神经网络.循环神经网络等核心的技术,并介绍了用于图像数据和文本序列数据的模型.给出了分布式深度学习系统在TensorFlow ...

  7. EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

    前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...

  8. [转]keil使用详解

    第一节 系统概述 Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上.结构性.可读性.可维护性上有明显的优势,因而易学易用.用过 ...

  9. malloc 与 free函数详解<转载>

    malloc和free函数详解   本文介绍malloc和free函数的内容. 在C中,对内存的管理是相当重要.下面开始介绍这两个函数: 一.malloc()和free()的基本概念以及基本用法: 1 ...

随机推荐

  1. AX Query

    AX 用代码方式调用静态Query(AOT\Queries节点下面的Query)的方法 static void AXD_CallQuery_SalesInfo(Args _args) { SysQue ...

  2. UVa 270 & POJ 1118 - Lining Up

    题目大意:给一些点,找出一条直线使尽可能多的点在这条直线上,求这条直线上点的个数. 以每一个点为原点进行枚举,求其它点的斜率,斜率相同则说明在一条直线上.对斜率排序,找出斜率连续相等的最大长度. #i ...

  3. Gurobi在Python环境里安装与使用(Windows环境)

  4. JQuery中after() append() appendTo()的区别

    首先 after() 是追加在元素外边而append() appendTo()是追加在元素里面. $(selector).after(content) $("span").afte ...

  5. 如何回收vRealize Automation里被分配出去了的IP地址

    在vRealize里写代码部署虚机,时间长了,便出现了很多虚机在vCenter里不存在,但在vRealize里还存在的这台虚机的注册信息的现象.最直接的后果是,这些影子虚机会占着IP池里的IP地址不放 ...

  6. Python开发接水果小游戏

    我研发的Python游戏引擎Pylash已经更新到1.4了.如今我们就来使用它完毕一个极其简单的小游戏:接水果. 下面是游戏截图: 游戏操作说明:点击屏幕左右两边或者使用键盘方向键控制人物移动.使人物 ...

  7. xtraTabbedMdiManager的标题上右鍵弹出关闭窗体菜单

    实现一个增值功能, 在xtraTabbedMdiManager组件TabPage标题上右鍵弹出关闭当前窗体的菜单. C# Code: private void xtraTabbedMdiManager ...

  8. jenkins二

    破解管理员密码 1.假如我们忘记了Jenkins管理员密码了该怎么办呢?Jenkins没有用到数据库,所有的文件都是保存到xml文件里的 2.第一步找到admin所在的目录 [root@centos- ...

  9. 使用 Anime 类在 XNA 中创建小动画(十一)

    平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛.在这里分享一下经验,仅为了和各位朋友交流经验.平方会逐步将自己编写的类上传到托管项目中,没有什么好名字,就叫 WPXN ...

  10. JobConf

    /**  * A map/reduce job configuration. * 翻译:一个map/reduce作业配置 * <p><code>JobConf</code ...