[DESCRIPTION]
此FAQ 用于解决两类问题:
1.ring back tone有的时候是网络播放的,有的时候是手机本地播放的
不同国家运营商网络播放的ring back tone不同,这就可能导致本地播放和网络播放有差别,比如UK
所以很多客户希望把本地播放的tone音客制化成和网络播放的一致,请参考此FAQ客制化特定频率的tone音;
2.不同国家地区对应的ringtone的tone 音是不一样的,例如,日本地区要报Japan tone。
如果发现播放的tone对应不上地区,也可以参考此FAQ 修改。
问题【1】对应的solution如下:
[SOLUTION1]
ringback tone类型定义在:
ToneGenerator.h
enum regional_tone_type {
TONE_ANSI_DIAL = NUM_TONES,
。。。
}
如当前播放的InCallTonePlayer: run(TONE_JAPAN_BUSY) 想要修改成澳大利亚类型,只需将TONE_JAPAN_BUSY替换为TONE_AUSTRALIA_BUSY即可
TONE_JAPAN_BUSY和TONE_AUSTRALIA_BUSY响铃类型定义在ToneGenerator.cpp中对应ID
如想要客制化的类型在ToneGenerator中没有定义,则需新加tone类型,再请参考 [SOLUTION2 ]
[SOLUTION2 ]
新加的Tone类型在[SOLUTION1] 及ToneGenerater.java中没有定义,则参考此修改
一定要注意新增加进去的Code 的顺序,不能错乱,
目前我们了解到修改无法生效都是因为加到enum 或者数组中
的顺序不对导致的。
ToneGenerator.h
TONE_JAPAN_DIAL, // Dial tone: 400Hz, continuous
TONE_JAPAN_BUSY, // Busy tone: 400Hz, 500ms ON, 500ms OFF…
TONE_JAPAN_RADIO_ACK, // Radio path acknowlegment: 400Hz, 1s ON, 2s OFF…
- // UK Supervisory tones
- TONE_UK_RINGTONE, // Ring Tone: A 400Hz + 450Hz tone repeated in a 0.4s on, 0.2s off, 0.4s on, 2.0s off pattern.
NUM_ALTERNATE_TONES
};
//注意上面是加在了JAPAN 后面,后面其他增加的部分都需要加在JAPAN 后面
//顺序错了,修改就会不成功
enum region {
ANSI,
JAPAN,
- UK, //跟上面一样,加在JAPAN 后面
CEPT,
NUM_REGIONS
};
====================================================================================
ToneGenerator.cpp
{ .duration = 0 , .waveFreq = { 0 }, 0, 0}},
.repeatCnt = ToneGenerator::TONEGEN_INF,
.repeatSegment = 0 }, // TONE_JAPAN_RADIO_ACK
//只能加在JAPAN 的后面,不会回引用到错误的数组数据
- { .segments = { { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
- { .duration = 200, .waveFreq = { 0 }, 0, 0 },
- { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
- { .duration = 2000, .waveFreq = { 0 }, 0, 0},
- { .duration = 0, .waveFreq = { 0 }, 0, 0}},
- .repeatCnt = ToneGenerator::TONEGEN_INF,
- .repeatSegment = 0 }, // TONE_UK_RINGTONE
TONE_SUP_ERROR, // TONE_SUP_ERROR
TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING
TONE_SUP_RINGTONE // TONE_SUP_RINGTONE
- },
//只能加在JAPAN 的后面,不会回引用到错误的数组数据
- { // UK
- TONE_SUP_DIAL, // TONE_SUP_DIAL
- TONE_SUP_BUSY, // TONE_SUP_BUSY
- TONE_SUP_CONGESTION, // TONE_SUP_CONGESTION
- TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK
- TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL
- TONE_SUP_ERROR, // TONE_SUP_ERROR
- TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING
- TONE_UK_RINGTONE // TONE_SUP_RINGTONE
}
};
mRegion = ANSI;
} else if (strcmp(value,“jp”) == 0) {
mRegion = JAPAN;
- } else if (strcmp(value,“uk”) == 0 ||
- strcmp(value,“uk,uk”) == 0) {
- mRegion = UK;
} else {
mRegion = CEPT;
}
问题【2】对应的solution如下:
首先说明下ringtone对应到region的逻辑,请参考这个逻辑进行定制。
1./frameworks/base/telephony/java/android/telephony/TelephonyManager.java中有一个方法public void setSimCountryIsoForPhone(int phoneId, String iso)
这个方法会设置属性值:“gsm.sim.operator.iso-country”
2.在/frameworks/av/media/libaudioclient/ToneGenerator.cpp中的mRegion的获取是通过"gsm.sim.operator.iso-country"属性值获取到的。
if (property_get(“gsm.operator.iso-country”, value, “”) == 0) {
property_get("gsm.sim.operator.iso-country", value, "");
}
// If dual sim device has two SIM cards inserted and is not registerd to any network,
// “,” is set to “gsm.operator.iso-country” prop.
// In this case, “gsm.sim.operator.iso-country” prop should be used.
if (strlen(value) == 1 && strstr(value, “,”) != NULL) {
property_get("gsm.sim.operator.iso-country", value, "");
}
3.在获取具体的地区的铃声时,会调用到ToneGenerator::getToneForRegion(tone_type toneType)方法,然后从map sToneMappingTable中获取到具体哪个region的铃声。
这里传入的toneType 可以理解为就是Telecom传入的值:
04-22 09:36:21.716732 1578 12491 D Telecom : InCallTonePlayer: run(toneId = 11)
综上所述,只要region的值对了,就能获取到正确地区的铃声。
而setSimCountryIsoForPhone的调用的地方在如下两个地方一定能调用到的。您可以尝试在这里面加入运营商的判断,并结合solution 1 来解决播放铃声地区不对的问题。
SIMRecords.java 1547 mTelephonyManager.setSimCountryIsoForPhone( in onAllRecordsLoaded()
MtkUiccProfile.java 259 mTelephonyManager.setSimCountryIsoForPhone(getPhoneId(), in setExternalState()