L1 AudioService.adjustSuggestedStreamVolume
2015-07-13 17:52
756 查看
前言
AudioService改变音量的方法有几个。实现方式最终的出口AudioSystem.XXX相同,形式上略有不同。adjustSuggestedStreamVolume
通过物理按键调节,常见的调用位置是:
http://androidxref.com/5.1.1_r6/xref/frameworks/base/services/core/java/com/android/server/media/MediaSessionService.java#875
boolean isStreamMute = mAudioService.isStreamMute(suggestedStream); if (direction == MediaSessionManager.DIRECTION_MUTE) { mAudioManager.setStreamMute(suggestedStream, !isStreamMute); } else { mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream, flags, packageName); //提到了setStreamMute()的使用 // Do not call setStreamMute when direction = 0 which is used just to // show the UI. if (isStreamMute && direction != 0) { mAudioManager.setStreamMute(suggestedStream, false); } }
如果有必要,修改streamType,flags
private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, int uid) { if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream="+suggestedStreamType + ", flags=" + flags); int streamType; if (mVolumeControlStream != -1) { streamType = mVolumeControlStream; } else { // 找到active stream type,就是ringer mode, play music时stream type的原因 streamType = getActiveStreamType(suggestedStreamType); } // 找到alias,stream对device的行为,必有这一步 final int resolvedStream = mStreamVolumeAlias[streamType]; // Play sounds on STREAM_RING only. if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && resolvedStream != AudioSystem.STREAM_RING) { flags &= ~AudioManager.FLAG_PLAY_SOUND; } // For notifications/ring, show the ui before making any adjustments if (mVolumeController.suppressAdjustment(resolvedStream, flags)) { direction = 0; flags &= ~AudioManager.FLAG_PLAY_SOUND; flags &= ~AudioManager.FLAG_VIBRATE; if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment"); } adjustStreamVolume(streamType, direction, flags, callingPackage, uid); }
相关函数
adjustStreamVolume
adjustStreamVolume可以参考 (L1)AudioService adjustStreamVolume代码走读 点击打开链接getActiveStreamType
按手机一般调节音量的流程来看1. 先区分platform------->看到这种if ...else...多的代码就想用多态
2. 区分in communication
3. 判断suggestStreamType
public static final int USE_DEFAULT_STREAM_TYPE = Integer.MIN_VALUE
http://developer.android.com/reference/android/media/AudioManager.html#USE_DEFAULT_STREAM_TYPE
整个函数:
返回值就bluetooth sco, voice call, music, ring, notification 和suggestdStreamType。看来suggestdStreamType就是用来决定是否进判断的
private int getActiveStreamType(int suggestedStreamType) { switch (mPlatformType) { case PLATFORM_VOICE: if (isInCommunication()) { if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION) == AudioSystem.FORCE_BT_SCO) { // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO..."); return AudioSystem.STREAM_BLUETOOTH_SCO; } else { // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL..."); return AudioSystem.STREAM_VOICE_CALL; } } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { if (isAfMusicActiveRecently(StreamOverride.sDelayMs)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active"); return AudioSystem.STREAM_MUSIC; } else { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING b/c default"); return AudioSystem.STREAM_RING; } } else if (isAfMusicActiveRecently(0)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active"); return AudioSystem.STREAM_MUSIC; } break; case PLATFORM_TELEVISION: if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { // TV always defaults to STREAM_MUSIC return AudioSystem.STREAM_MUSIC; } break; default: if (isInCommunication()) { if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION) == AudioSystem.FORCE_BT_SCO) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO"); return AudioSystem.STREAM_BLUETOOTH_SCO; } else { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL"); return AudioSystem.STREAM_VOICE_CALL; } } else if (AudioSystem.isStreamActive(AudioSystem.STREAM_NOTIFICATION, StreamOverride.sDelayMs) || AudioSystem.isStreamActive(AudioSystem.STREAM_RING, StreamOverride.sDelayMs)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION"); return AudioSystem.STREAM_NOTIFICATION; } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) { if (isAfMusicActiveRecently(StreamOverride.sDelayMs)) { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: forcing STREAM_MUSIC"); return AudioSystem.STREAM_MUSIC; } else { if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: using STREAM_NOTIFICATION as default"); return AudioSystem.STREAM_NOTIFICATION; } } break; } if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type " + suggestedStreamType); return suggestedStreamType; }
isAfMusicActiveRecently
调用AudioSystem.isStreamActive(), AudioSystem.isStreamActiveRemotely() 从native获得状态private boolean isAfMusicActiveRecently(int delay_ms) { return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, delay_ms) || AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, delay_ms); }
相关文章推荐
- Xcode6解决storyboard没有箭头的问题
- IOS 请求服务器的方式
- IOS 代码管理工具
- BIOS中英对照(部分)
- ios8.3——ios9弹出警告框
- iOS8使用TestFlight进行内部测试功能尝鲜
- iOS 第三方库(1)
- 常用iOS第三方库以及XCode插件介绍
- iOS设计模式——Category
- Json解析字符串的类型总结--IOS
- iOS设计模式-抽象工厂
- iOS 支付宝 集成
- PhoneGap开发对策:如何通过苹果审核
- 支付宝 iOS SDK 官方下载页面
- iOS 中的 NSTimer
- JS判断客户端是否是iOS或者Android
- iOS真机沙盒文件查看 图片批量存储/获取/删除
- 程序日志--ios“文字长度--button与label的交互”程序
- 常用的iOS开发或者优化的小工具
- ios证书制作与打包发布