一、ToneGenerator的使用
参照com.android.contacts.dialpad.DialpadFragment
ToneGenerator只能播放在ToneGenerator中定义好的TONE_TYPE。
1、常量申明
/** Tone音的长度,单位:milliseconds */
private static final int TONE_LENGTH_MS = 150;
/** 主音量的比例:以80%的主音量播放Tone音 */
private static final int TONE_RELATIVE_VOLUME = 80;
/** 主音量的音频种别 */
private static final int DIAL_TONE_STREAM_TYPE =AudioManager.STREAM_MUSIC;
2、变量申明
// Tone音播放器
private ToneGenerator mToneGenerator;
// Tone相关的同步锁
private Object mToneGeneratorLock = new Object();
// 设定中的Tone音播放设置
private boolean mDTMFToneEnabled;
3、Tone的初始化
public void onResume() {
super.onResume();
// 读取设定的值
mDTMFToneEnabled =Settings.System.getInt(getActivity().getContentResolver(),
Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
// 失败了也无所谓,不是啥重要的东西
synchronized (mToneGeneratorLock) {
if (mToneGenerator == null) {
try {
// we want the user to be ableto control the volume of the dial tones
// outside of a call, so we usethe stream type that is also mapped to the
// volume control keys for thisactivity
mToneGenerator = newToneGenerator(DIAL_TONE_STREAM_TYPE, TONE_RELATIVE_VOLUME);
getActivity().setVolumeControlStream(DIAL_TONE_STREAM_TYPE);
} catch (RuntimeException e) {
Log.w(TAG, "Exceptioncaught while creating local tone generator: " + e);
mToneGenerator = null;
}
}
}
}
4、释放Tone资源
public voidonPause() {
super.onPause();
synchronized (mToneGeneratorLock) {
if (mToneGenerator != null) {
mToneGenerator.release();
mToneGenerator = null;
}
}
}
5、播放Tone音
/**
* 播放TONE_LENGTH_MS milliseconds的Tone音.
* 只有在设定中选择了播放Tone,并且不是静音模式才会播放Tone音。
* @param tone a tone code from {@linkToneGenerator}
*/
void playTone(int tone) {
// 设定中没有选中的话,就不播
if (!mDTMFToneEnabled) {
return;
}
// 静音模式的时候也不播,需要每次都检查,因为没有Activity切换也能设成静音模式
// 设定中的那个就不需要,因为要设定必须要先切入设定Activity才行
AudioManager audioManager =
(AudioManager)getActivity().getSystemService(Context.AUDIO_SERVICE);
int ringerMode =audioManager.getRingerMode();
if ((ringerMode == AudioManager.RINGER_MODE_SILENT)
|| (ringerMode ==AudioManager.RINGER_MODE_VIBRATE)) {
return;
}
synchronized (mToneGeneratorLock) {
if (mToneGenerator == null) {
Log.w(TAG, "playTone:mToneGenerator == null, tone: " + tone);
return;
}
// Start the new tone (will stop anyplaying tone)
mToneGenerator.startTone(tone,TONE_LENGTH_MS);
}
}
二、ToneGenerator的实现
相关代码位置:
ToneGenerator.java:ICS/frameworks/base/media/java/
Android_media_ToneGenerator.cpp:ICS/frameworks/base/core/jni/
ToneGenerator.cpp:ICS/frameworks/base/media/libmedia/
1、ToneGenerator.java
定义了多种ToneType,提供了java的接口
2、Android_media_ToneGenerator.cpp
将Java层的请求转发给Native层。
android_media_ToneGenerator_native_setup中的有句话看不懂:
ToneGenerator *lpToneGen= new ToneGenerator(streamType, AudioSystem::linearToLog(volume),true);
// change this value tochange volume scaling
static const float dBPerStep= 0.5f;
// shouldn't need totouch these
static const floatdBConvert = -dBPerStep * 2.302585093f / 20.0f;
static const floatdBConvertInverse = 1.0f / dBConvert;
floatAudioSystem::linearToLog(int volume)
{
// float v = volume ? exp(float(100 -volume) * dBConvert) : 0;
// LOGD("linearToLog(%d)=%f",volume, v);
// return v;
return volume ? exp(float(100 - volume) *dBConvert) : 0;
}
算出来的值会直接设到AudioTrack中,可是AudioTrack中的音量应该是个0~1.0f的百分比才对,为啥需要这么个公式呢,难道是Bug。应该测试一下!!
3、ToneGenerator.cpp
根据定义的Tone因的频率,长度等信息生成音频数据,最后交给AudioTrack播放。
三、AudioPolicyService中的mTonePlaybackThread
本来以为这个线程是专门处理Tone音设备的,可是根据上面一看原来是直接走AudioTrack的。这就奇怪了,并且AudioSystem中也没有提供对应的接口,这就更奇怪了,难道它没准备让外面的人用。再一检索,发现原来它是提供给AudioPolicyManagerBase使用的一个非同期播放Tone音的接口。
经过AudioCommandThread的处理,最终还是交给ToneGenerator来处理。
四、RingtoneManager与Ringtone
播放铃声的类,没具体看,最后是通过MediaPlayer来播放的。
五、结论
本来还以为会有个单独硬件来处理Tone音的,最后发现竟然是自动生成后,通过AudioTrack来处理的。
据说是因为硬件生成的Tone音很难听,所以才用软件来生成的。
分享到:
相关推荐
解压后放入sdk\platforms\ 文件夹下即可 Android 4.0.3 sdk API15
Ubuntu12.04下编译和下载Android4.0.3源码
Android sdk 4.0.3源码
很好用的一键android4.0.3ROOT工具.rar
android sdk 4.0.3源碼
Android4.0.3系统照相机源码。
MT3732 Android4.0.3Ril
安卓开发Android4.0.3环境配置与安装
samsung s5pv210 android4.0.3 的补丁文件,是一个朋友发给我的。 如有侵权,请提示删除。
项目导入使用Import->General->Existing Projects into Workspace,保证配置一样 详情请参考:http://blog.csdn.net/you_and_me12/article/details/12101071
从Android4.0.3系统中剥离得到的Gallery JNI源码
Android4.0.3源代码包(Java部分),打包好的源代码,调试使用.
一个简单的小例子,android4.0.3上的,支持12小时,24小时自动区分,背景图片是实体机上的,在模拟器上有点大
N12豪华版Android4.0.3破解工具包
现为大家带来android4.0.3的源码,没有下又想下载的朋友们有福了
只能在真机上面运行,从gooleplay官方上面下载下来的189.0.0.35.91(只支持android8.0),更新日期2018年9月12日,(不过2018年9月20日,官方...将两个版本都分享出来,同时另外提供了两个非官方版本的,支持Android 4.0.3
Android4.0.3环境配置与安装,按此文档配置开发环境,非常好用
该代码是我移植到android4.0.3下的ntfs-3g源码,已顺利通过编译,测试通过
Android4.0.3系统源码,下载后解压,放到sources文件夹下,然后指引导这个目录即可