Android Audio 常见客制化问题(一)

来源:互联网 发布:淘宝买精密管有公安查 编辑:程序博客网 时间:2024/06/04 18:24

  • 插入印度SIM 卡相机拍照声音开关控制无效
  • 录音时如何获取mic进来的音量大小
  • 如何调整录像和拍照的声音大小
  • 在播放器界面使用侧键如何调整Media音量
  • 如何监听手机上面音乐FM等多媒体声音的播放停止的动作
  • 音频输出结束后尽早关闭设备
  • 预览来电铃声如何让背景音乐暂停播放
  • 如何在TP 上Home back添加按键音
  • 蓝牙耳机模式下拨号拨第1个数字没有声音
  • 在filemanager中重命名MP3的名称进入Music中发现歌曲仍显示原来的名称
  • 修改通话时第二通电话呼叫等待提示音音量大小
  • 插入耳机时也能将音乐收音机声音调成最大
  • 铃声选择列表排序顺序客制化
  • 静音模式下来电能震动
  • 铃声列表添加更多铃声选项后日历或闹钟中选择铃声从静音到更多铃声时失败
  • 更多铃声中选择用户盘中的歌曲做铃声首次选择无效不能选中

插入印度SIM 卡,相机拍照声音开关控制无效

[DESCRIPTION]
插入印度卡后,关闭camera拍照声的情况下也有声音,使用其他SIM卡不会有问题。

[SOLUTION]
是由于客户印度卡mcc为404,405,所以调用frameworks/base/core/res/res/valuesmcc404/
config.xml中的config_camera_sound_forced 的值,而这个值为true,从而导致强制使用
拍照声音,修改为false就可以了。

当然,在Audioservice.java里readCameraSoundForced(), 强制赋值false也是可行的。

录音时如何获取mic进来的音量大小

[DESCRIPTION]
如何获取MIC录音音量变化

[SOLUTION]
在使用Mediarecorder进行录音时,Mediarecorder中已经提供方法getMaxAmplitude(),获取当前这段时间内最大的采样点的值,其代表了录入的最大声音的采样,可以每隔一段时间(0.5s)调用此接口即可

如何调整录像和拍照的声音大小

[DESCRIPTION]
如何调整录像和拍照的声音大小
[SOLUTION]
CameraService.cpp

playSound(...){  ...  player->seekTo(0);  //增加下行  player->setVolume(leftVolume,rightVolume);  ...  }  

其中leftVolume & rightVolume 大小限定在0~1 之间。

在播放器界面,使用侧键如何调整Media音量

[DESCRIPTION]
在播放器中,若当前没有播放,侧键一般会针对Ring音量进行调整
如何在某个界面中针对Media音量进行调整
[SOLUTION]
在当前界面对应的XXXActivity.onCreate方法中,加上如下:

setVolumeControlStream(AudioManager.STREAM_MUSIC);

如何监听手机上面音乐/FM等多媒体声音的播放/停止的动作?

[DESCRIPTION]
如何监听手机上面音乐/FM等多媒体声音的播放/停止的动作?
[SOLUTION]
Android有一个AudioFocus的机制,要播放声音的app可以去requestAudioFocus(),当拿到audiofocus之后再播放音乐,当失去audiofocus的时候做停止播放的动作,当自己的播放动作结束后,释放audiofocus。通过audiofocus可以做到
监听有使用audiofocus的那些app的播放/停止的动作,可以达到在同一时间,只有拿到audiofocus的app才可以播放音
乐的目的,这样可以避免各个app的声音相互冲突。
代码例子如下:
1)要播放时,先requestAudioFocus(),再Startplayback:

AudioManageram=mContext.getSystemService(Context.AUDIO_SERVICE);...//Requestaudiofocusforplaybackintresult=am.requestAudioFocus(afChangeListener,//Usethemusicstream.AudioManager.STREAM_MUSIC,//Requestpermanentfocus.AudioManager.AUDIOFOCUS_GAIN);if(result==AudioManager.AUDIOFOCUS_REQUEST_GRANTED){am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);//Startplayback.}

2)当播放结束时,要abandonAudioFocus,这样之前被打断的app可以重新得到audiofocus,恢复播放:

//Abandonaudiofocuswhenplaybackcompleteam.abandonAudioFocus(afChangeListener);

3)还要注册OnAudioFocusChangeListener(),这样当audiofocus被别人拿走时,可以及时暂停播放。当别人归还
audiofocus时,可以恢复播放:

OnAudioFocusChangeListenerafChangeListener=newOnAudioFocusChangeListener(){publicvoidonAudioFocusChange(intfocusChange){if(focusChange==AUDIOFOCUS_LOSS_TRANSIENT//Pauseplayback}elseif(focusChange==AudioManager.AUDIOFOCUS_GAIN){//Resumeplayback}elseif(focusChange==AudioManager.AUDIOFOCUS_LOSS){am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);am.abandonAudioFocus(afChangeListener);//Stopplayback}}};

PS:您还可以在Google开发文档中搜索“AudioFocus”来获取更多API信息和用法。

音频输出结束后,尽早关闭设备

[DESCRIPTION]
每次声音响完,PA没有马上关掉,会听到speaker中有底噪声,想减少这个时间,尽早关闭PA。
[SOLUTION]
AudioFlinger.h

kDefaultStandbyTimeInNsecs=seconds(3)  

改为0.6

预览来电铃声,如何让背景音乐暂停播放

[DESCRIPTION]
背景在播放音乐,进入audioprofile预览来电铃声,如何让背景音乐暂停播放
[SOLUTION]
该功能实现的思路是使用audioFocus机制。
可以再RingtonePickerActivity.java

oncreate的时候

((AudioManager)getSystemService(AUDIO_SERVICE)).requestAudioFocus(null,AudioManager.STREAM_RING,AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);

然后在onDestory的时候

((AudioManager)getSystemService(AUDIO_SERVICE)).abandonAudioFocus(null);

如何在TP 上Home、 back添加按键音

[DESCRIPTION]
进入情景模式->一般模式->勾选中触屏提示音,但是只有TP上menu键有按键音,home键&back键没有提示音,如何让
home&back键也有触屏提示音。
[SOLUTION]
按照如下方式修改
phonewindowmanager.java

interceptKeyBeforeDispatching(){...//添加如下codeif(keyCode==KeyEvent.KEYCODE_BACK&&event.getAction()==KeyEvent.ACTION_DOWN){Log.d(TAG,"interceptKeyBeforeDispatchingKEYCODE_BACK,keyeventactiondown");AudioManageraudioManager=(AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);if(audioManager!=null){audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);}else{Log.w(TAG,"Couldn'tgetaudiomanager");}}if(keyCode==KeyEvent.KEYCODE_HOME&&event.getAction()==KeyEvent.ACTION_DOWN){Log.d(TAG,"interceptKeyBeforeDispatchingKEYCODE_home,keyeventactiondown");AudioManageraudioManager=(AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);if(audioManager!=null){audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);}else{Log.w(TAG,"Couldn'tgetaudiomanager");}}//添加结束//Firstwealwayshandlethehomekeyhere,soapplications//canneverbreakit,althoughifkeyguardison,wedolet//ithandleit,becausethatgivesusthecorrect5second//timeout.if(keyCode==KeyEvent.KEYCODE_HOME){...}

蓝牙耳机模式下拨号,拨第1个数字没有声音

[DESCRIPTION]
个别蓝牙耳机连上手机,进入拨号盘按数字键盘,按第一个数字键会没有声音。
对比机行为:三星Samsung Galaxy Nexus很容易复现该问题。
测试结果:个别蓝牙耳机也能复现出来。

[SOLUTION]
由于特殊蓝牙耳机的问题,声音数据太短时该耳机无法正常播放,会丢掉一点声音,造成第一个按键tone音听不见,属于个别蓝牙耳机问题.
解决方法:增加tone音播放长度来规避该问题。

在DialpadFragment.java

private static final int TONE_LENGTH_MS=150;

在filemanager中重命名MP3的名称,进入Music中发现歌曲仍显示原来的名称

[DESCRIPTION]
进入文件管理中,将一个MP3重命名,重命名完成后进入Music播放器,发现原先被重命名过的MP3显示的仍然是原先的名称,而非重命名后的名称。

[SOLUTION]
歌曲被Mediascanner扫描后,在Music播放器中,显示的是MP3中的ID3 tag,这个是内置在歌曲中的信息,所以即使在file manager中重命名,也不会改变在music中的名称.

note:有些工具,如格式工厂,将歌曲转换为MP3时会破坏tag里面的数据,此时若在file manager中修改,Music就会随着修改而改变。

修改通话时第二通电话呼叫等待提示音音量大小

[DESCRIPTION]
通话时第二通电话呼叫等待提示音音量比较小。

[SOLUTION]
可以参照如下提示去修改。
android/packages/services/Telephony/src/com/android/phone/CallNotifier.java

public void run() {......switch (mToneId) {case TONE_CALL_WAITING:toneType = ToneGenerator.TONE_SUP_CALL_WAITING;//可以更改下面这个音量,目前是80,代表相对其它声音的大小toneVolume = TONE_RELATIVE_VOLUME_HIPRI; // Call waiting tone is stopped by stopTone() methodtoneLengthMillis = Integer.MAX_VALUE - TONE_TIMEOUT_BUFFER;break;

插入耳机时也能将音乐/收音机声音调成最大

[DESCRIPTION]
在插入耳机的情况下,为保护用户的听力, 以防受损,故在检测到音量调整到警界值时, 会出现上述警告框,而这个警界值, 是可以调整的, 默认是 12, 音量值最大是 15
所以当将音量调整到 12 以上时, 就会有上述警告框出现

[SOLUTION]
如果不想使用此功能, 可以将
frameworks\base\core\res\res\values\config.xml
中下面这行
<integer name="config_safe_media_volume_index">12</integer>
改为:
<integer name="config_safe_media_volume_index">15</integer>
如果想调低警界值, 也是改上述配置, 将其值调小.

铃声选择列表排序顺序客制化

[DESCRIPTION]
铃声选择界面默认是按照Title排序的,希望改成其他的排序方式

[SOLUTION]
如希望修改铃声选择列表的排序界面可以修改文件
frameworks\base\media\java\android\media\RingtoneManager.java中的函数getCursor()->SortCursor()的最后一个参数MediaStore.Audio.Media.DEFAULT_SORT_ORDER; 但是排序的参数要在cursor查询列中,即在RingtoneManager.java中查询的结果列INTERNAL_COLUMNS,DRM_COLUMNS,MEDIA_COLUMNS 中要有被排序的列。

如希望按照铃声播放时间排序,则:

1,INTERNAL_COLUMNS,DRM_COLUMNS, MEDIA_COLUMNS中添加duration的列:

private static final String[] INTERNAL_COLUMNS = new String[] {    MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE,    MediaStore.Audio.Media.DURATION,    "\"" + MediaStore.Audio.Media.INTERNAL_CONTENT_URI + "\"",    MediaStore.Audio.Media.TITLE_KEY};private static final String[] DRM_COLUMNS = new String[] {    DrmStore.Audio._ID, DrmStore.Audio.TITLE,MediaStore.Audio.Media.DURATION,    "\"" + DrmStore.Audio.CONTENT_URI + "\"",    DrmStore.Audio.TITLE + " AS " + MediaStore.Audio.Media.TITLE_KEY};private static final String[] MEDIA_COLUMNS = new String[] {    MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE,    MediaStore.Audio.Media.DURATION,    "\"" + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "\"",    MediaStore.Audio.Media.TITLE_KEY,    MediaStore.Audio.Media.IS_DRM, /// M: add for handling OMA DRM v1 content    MediaStore.Audio.Media.DRM_METHOD /// M: add for handling OMA DRM v1 content};

2,getCursor()中SortCursor的最后一个参数填为Duration,即是按照时间排序:

public Cursor getCursor() {if (mCursor != null && mCursor.requery()) {Log.v(TAG, "getCursor with old cursor = " + mCursor);return mCursor;}final Cursor internalCursor = getInternalRingtones();final Cursor drmCursor = mIncludeDrm ? getDrmRingtones() : null;final Cursor mediaCursor = getMediaRingtones();// mCursor = new SortCursor(new Cursor[] { internalCursor, drmCursor, mediaCursor },// MediaStore.Audio.Media.DEFAULT_SORT_ORDER);mCursor = new SortCursor(new Cursor[] { internalCursor, drmCursor, mediaCursor },MediaStore.Audio.Media.DURATION);Log.v(TAG, "getCursor with new cursor = " + mCursor);return mCursor;}

静音模式下来电能震动

[DESCRIPTION]
希望情景模式为静音模式时,来电可以震动

[SOLUTION]
首先修改Silent这个模式下,震动的默认值,即在AudioProfileManager.java
的getDefaultState()中将DEFAULT_VIBRATION_SILENT设为true;
然后在AudioService.java的shouldVibrate()中 如下:
case AudioManager.VIBRATE_SETTING_ON的地方改成true:

public boolean shouldVibrate(int vibrateType) {if (!mHasVibrator) return false;switch (getVibrateSetting(vibrateType)) {

铃声列表添加“更多铃声”选项后,日历或闹钟中选择铃声从静音到更多铃声时失败。

[DESCRIPTION]
铃声列表添加“更多铃声”选项后,如果日历或闹钟中当前铃声为静音,从“更多铃声”中选择铃声不能成功。

[SOLUTION]
请修改packages\providers\MediaProvider\src\com\android\providers\media\RingtonePickerActivity.java的

if((mClickedPos>=mStaticItemCount)&&(null!=mExistingUri)){

if((mClickedPos>=mStaticItemCount||mClickedPos==mSilentPos||mClickedPos==mDefaultRingtonePos)&&(null!=mExistingUri)){

“更多铃声”中选择用户盘中的歌曲做铃声,首次选择无效,不能选中

[DESCRIPTION]
设置铃声选项中,打开“更多铃声”选项,点击进入音乐播放器选择音乐后,需要两步才能把音乐设置成铃声,一步是
把音乐加入铃声列表,另一步是选择铃声列表中的该首铃声,不能一次性选中,请问如何实现从音乐界面选择音乐后就
能设置铃声?

[SOLUTION]
请在ringtonePickerActivity.java中修改如下:
onResume方法中,原来的如下判断语句
if ((mClickedPos >= mStaticItemCount) && (null != mExistingUri))
改为
Uri defaultRingUri = RingtoneManager.getDefaultRingtoneUri(getApplicationContext(), mType);
if ((mExistingUri != defaultRingUri) && (null != mExistingUri))

原创粉丝点击