AudioManager详解(结合源代码)

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代码
  java代码
  1. //获取实例

  2.   AudioManager audioManager = (AudioManager)
  3. getSystemService(AUDIO_SERVICE);
  4.   //获取/设置系统音量
  5.   audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM);
  6.   audioManager.setStreamVolume(AudioManager.STREAM_SYSTEM,
  7.   AudioManager.ADJUST_RAISE
  8.   , AudioManager.FLAG_SHOW_UI);
  9.   //获取/设置音乐音量
  10.   audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
  11.   audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
  12.   AudioManager.ADJUST_RAISE
  13.   , AudioManager.FLAG_SHOW_UI);
  14.   //其他的类似
  15.   //获取/设置铃声的模式
  16.   int ringMode = audioManager.getRingerMode();
  17.   //普通模式
  18.   audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
  19.   //静音模式
  20.   audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
  21.   //其他的类似
  22.   //设置声音流静音/不静音
  23.   //音乐静音
  24.   audioManager.setStreamMute(AudioManager.STREAM_MUSIC, true);
  25.   //铃声不静音
  26.   audioManager.setStreamMute(AudioManager.STREAM_RING, false);
  27.   //其他的类似
复制代码
  二. 分析下这个类里面的部分源代码
  由于知识水平有限,我觉得下面的代码自己分析不好,建议看这篇博文: http://blog.csdn.net/qinjuning/article/details/6938436
  java代码
  1. /*

  2.   为Action == “MEDIA_BUTTON”注册广播接收者
  3.   用来广播“耳机插入”的事件
  4.   eventReceiver一般接受的参数为这样一个ComponentName对象
  5.   如:
  6.   AudioManager audioManager = (AudioManager)
  7. getSystemService(AUDIO_SERVICE);
  8.   ComponentName component = new
  9. ComponentName(context.getApplicationContext(),MediaControlReceiver.class);
  10.   audioManager.registerMediaButtonEventReceiver(component);
  11.   */
  12.   public void registerMediaButtonEventReceiver(ComponentName eventReceiver)
  13. {
  14.   if (eventReceiver == null) {
  15.   return;
  16.   }
  17.   if (!eventReceiver.getPackageName().equals(mContext.getPackageName()))
  18. {
  19.   Log.e(TAG, "registerMediaButtonEventReceiver() error: " +
  20.   "receiver and context package names don't match");
  21.   return;
  22.   }
  23.   // construct a PendingIntent for the media button and register it
  24.   Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
  25.   // the associated intent will be handled by the component being
  26. registered
  27.   mediaButtonIntent.setComponent(eventReceiver);
  28.   PendingIntent pi = PendingIntent.getBroadcast(mContext,
  29.   0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/);
  30.   registerMediaButtonIntent(pi, eventReceiver);
  31.   }
  32.   /**
  33.   为MediaButton注册一个Intent
  34.   可以发现,这边也是通过aidl的方式进行的调用
  35.   IAudioService的aidl:https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/IAudioService.aidl
  36.   */
  37.   public void registerMediaButtonIntent(PendingIntent pi, ComponentName
  38. eventReceiver) {
  39.   if ((pi == null) || (eventReceiver == null)) {
  40.   Log.e(TAG, "Cannot call registerMediaButtonIntent() with a null
  41. parameter");
  42.   return;
  43.   }
  44.   IAudioService service = getService();
  45.   try {
  46.   // pi != null
  47.   service.registerMediaButtonIntent(pi, eventReceiver);
  48.   } catch (RemoteException e) {
  49.   Log.e(TAG, "Dead object in registerMediaButtonIntent"+e);
  50.   }
  51.   }
  52.   /**
  53.   * Unregister the receiver of MEDIA_BUTTON intents.
  54.   * @param eventReceiver identifier of a {@link
  55. android.content.BroadcastReceiver}
  56.   * that was registered with {@link
  57. #registerMediaButtonEventReceiver(ComponentName)}.
  58.   */
  59.   public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver)
  60. {
  61.   if (eventReceiver == null) {
  62.   return;
  63.   }
  64.   // construct a PendingIntent for the media button and unregister it
  65.   Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
  66.   // the associated intent will be handled by the component being
  67. registered
  68.   mediaButtonIntent.setComponent(eventReceiver);
  69.   PendingIntent pi = PendingIntent.getBroadcast(mContext,
  70.   0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/);
  71.   unregisterMediaButtonIntent(pi, eventReceiver);
  72.   }
  73.   /**
  74.   * @hide
  75.   */
  76.   public void unregisterMediaButtonIntent(PendingIntent pi, ComponentName
  77. eventReceiver) {
  78.   IAudioService service = getService();
  79.   try {
  80.   service.unregisterMediaButtonIntent(pi, eventReceiver);
  81.   } catch (RemoteException e) {
  82.   Log.e(TAG, "Dead object in unregisterMediaButtonIntent"+e);
  83.   }
  84.   }
  85.   /**
  86.   * Registers the remote control client for providing information to display
  87. on the remote
  88.   * controls.
  89.   * @param rcClient The remote control client from which remote controls will
  90. receive
  91.   * information to display.
  92.   * @see RemoteControlClient
  93.   */
  94.   public void registerRemoteControlClient(RemoteControlClient rcClient) {
  95.   if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) {
  96.   return;
  97.   }
  98.   IAudioService service = getService();
  99.   try {
  100.   service.registerRemoteControlClient(rcClient.getRcMediaIntent(), /*
  101. mediaIntent */
  102.   rcClient.getIRemoteControlClient(), /* rcClient */
  103.   // used to match media button event receiver and audio focus
  104.   mContext.getPackageName()); /* packageName */
  105.   } catch (RemoteException e) {
  106.   Log.e(TAG, "Dead object in registerRemoteControlClient"+e);
  107.   }
  108.   }
  109.   /**
  110.   * Unregisters the remote control client that was providing information to
  111. display on the
  112.   * remote controls.
  113.   * @param rcClient The remote control client to unregister.
  114.   * @see #registerRemoteControlClient(RemoteControlClient)
  115.   */
  116.   public void unregisterRemoteControlClient(RemoteControlClient rcClient)
  117. {
  118.   if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) {
  119.   return;
  120.   }
  121.   IAudioService service = getService();
  122.   try {
  123.   service.unregisterRemoteControlClient(rcClient.getRcMediaIntent(), /*
  124. mediaIntent */
  125.   rcClient.getIRemoteControlClient()); /* rcClient */
  126.   } catch (RemoteException e) {
  127.   Log.e(TAG, "Dead object in unregisterRemoteControlClient"+e);
  128.   }
  129.   }
  130.   /**
  131.   * @hide
  132.   * Registers a remote control display that will be sent information by
  133. remote control clients.
  134.   * @param rcd
  135.   */
  136.   public void registerRemoteControlDisplay(IRemoteControlDisplay rcd) {
  137.   if (rcd == null) {
  138.   return;
  139.   }
  140.   IAudioService service = getService();
  141.   try {
  142.   service.registerRemoteControlDisplay(rcd);
  143.   } catch (RemoteException e) {
  144.   Log.e(TAG, "Dead object in registerRemoteControlDisplay " + e);
  145.   }
  146.   }
  147.   /**
  148.   * @hide
  149.   * Unregisters a remote control display that was sent information by remote
  150. control clients.
  151.   * @param rcd
  152.   */
  153.   public void unregisterRemoteControlDisplay(IRemoteControlDisplay rcd) {
  154.   if (rcd == null) {
  155.   return;
  156.   }
  157.   IAudioService service = getService();
  158.   try {
  159.   service.unregisterRemoteControlDisplay(rcd);
  160.   } catch (RemoteException e) {
  161.   Log.e(TAG, "Dead object in unregisterRemoteControlDisplay " + e);
  162.   }
  163.   }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值