来电铃声和通话中的提示音
来源:互联网 发布:linux 解压包指定目录 编辑:程序博客网 时间:2024/04/30 00:57
InCallTonePlayer
packages/services/Telecomm/src/com/Android/server/telecom/InCallTonePlayer.Java,该类用于通话中提示音的播放。
- public static class Factory {
- private final CallAudioManager mCallAudioManager;
- private final TelecomSystem.SyncRoot mLock;
- Factory(CallAudioManager callAudioManager, TelecomSystem.SyncRoot lock) {
- mCallAudioManager = callAudioManager;
- mLock = lock;
- }
- InCallTonePlayer createPlayer(int tone) {
- return new InCallTonePlayer(tone, mCallAudioManager, mLock);
- }
- }
- /** The ID of the tone to play. */
- private final int mToneId;
- public static final int TONE_INVALID = 0;
- public static final int TONE_BUSY = 1;
- public static final int TONE_CALL_ENDED = 2;
- ...
- public static final int TONE_VOICE_PRIVACY = 13;
- public static final int TONE_VIDEO_UPGRADE = 14;
- public final class InCallTonePlayer extends Thread
- @Override
- public void run() {
- ToneGenerator toneGenerator = null;
- try {
- Log.d(this, "run(toneId = %s)", mToneId);
- final int toneType; // Passed to ToneGenerator.startTone.
- final int toneVolume; // Passed to the ToneGenerator constructor.
- final int toneLengthMillis;
- switch (mToneId) {
- case TONE_BUSY:
- // TODO: CDMA-specific tones
- toneType = ToneGenerator.TONE_SUP_BUSY; //依据id获取tone的类型、音量和时长,可见tone类型是在framework中定义的
- toneVolume = RELATIVE_VOLUME_HIPRI;
- toneLengthMillis = 4000;
- break;
- ...
- default:
- throw new IllegalStateException("Bad toneId: " + mToneId);
- }
- int stream = AudioManager.STREAM_VOICE_CALL;
- if (mCallAudioManager.isBluetoothAudioOn()) {
- stream = AudioManager.STREAM_BLUETOOTH_SCO; //设置音频stream,有蓝牙连接就切换到蓝牙设备播放
- ...
- toneGenerator = new ToneGenerator(stream, toneVolume); //初始化ToneGenerator
- ...
- synchronized (this) {
- if (mState != STATE_STOPPED) {
- mState = STATE_ON;
- toneGenerator.startTone(toneType); //播放
- try {
- Log.v(this, "Starting tone %d...waiting for %d ms.", mToneId,
- toneLengthMillis + TIMEOUT_BUFFER_MILLIS);
- wait(toneLengthMillis + TIMEOUT_BUFFER_MILLIS); //阻塞直到停止播放
- } catch (InterruptedException e) {
- Log.w(this, "wait interrupted", e);
- }
- }
- }
- mState = STATE_OFF;
- } finally {
- if (toneGenerator != null) { //资源释放
- toneGenerator.release();
- }
- cleanUpTonePlayer();
- }
- }
- void stopTone() { //停止tone播放
- synchronized (this) {
- if (mState == STATE_ON) {
- Log.d(this, "Stopping the tone %d.", mToneId);
- notify(); //由于run中最后是调用wait阻塞,所以这里notify就是通知线程可以结束运行了。
- }
- mState = STATE_STOPPED;
- }
- }
- /**
- * Proprietary tone, prompt tone: 400Hz+1200Hz, 200ms ON
- *
- * @see #ToneGenerator(int, int)
- */
- public static final int TONE_PROP_PROMPT = 27;
AsyncRingtonePlayer
packages/services/Telecomm/src/com/android/server/telecom/AsyncRingtonePlayer.java
- private static final int EVENT_PLAY = 1;
- private static final int EVENT_STOP = 2;
- private static final int EVENT_REPEAT = 3;
- private Handler getNewHandler() {
- Preconditions.checkState(mHandler == null);
- HandlerThread thread = new HandlerThread("ringtone-player");
- thread.start();
- return new Handler(thread.getLooper()) {
- @Override
- public void handleMessage(Message msg) {
- switch(msg.what) {
- case EVENT_PLAY:
- handlePlay((Uri) msg.obj);
- break;
- case EVENT_REPEAT:
- handleRepeat();
- break;
- case EVENT_STOP:
- handleStop();
- break;
- }
- }
- };
- }
Ringer
packages/services/Telecomm/src/com/android/server/telecom/Ringer.java,负责来电时候铃声和振动处理
- private void startRingingOrCallWaiting(Call call) { //响铃的入口
- Call foregroundCall = mCallsManager.getForegroundCall();
- Log.v(this, "startRingingOrCallWaiting, foregroundCall: %s.", foregroundCall);
- if (mRingingCalls.contains(foregroundCall)
- && !mCallsManager.hasActiveOrHoldingCall()) { //普通来电状态
- ...
- AudioManager audioManager =
- (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
- if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
- if (mState != STATE_RINGING) {
- Log.event(call, Log.Events.START_RINGER);
- mState = STATE_RINGING;
- }
- mCallAudioManager.setIsRinging(call, true);
- ...
- mRingtonePlayer.play(foregroundCall.getRingtone()); //使用AsyncRingtonePlayer响铃
- ...
- } else {
- Log.v(this, "startRingingOrCallWaiting, skipping because volume is 0");
- }
- if (shouldVibrate(mContext) && !mIsVibrating) { //振动
- mVibrator.vibrate(VIBRATION_PATTERN, VIBRATION_PATTERN_REPEAT,
- VIBRATION_ATTRIBUTES);
- mIsVibrating = true;
- }
- } else if (foregroundCall != null) { //通话中来电
- ...
- // All incoming calls are in background so play call waiting.
- stopRinging(call, "Stop for call-waiting");
- if (mState != STATE_CALL_WAITING) {
- Log.event(call, Log.Events.START_CALL_WAITING_TONE);
- mState = STATE_CALL_WAITING;
- }
- if (mCallWaitingPlayer == null) {
- mCallWaitingPlayer =
- mPlayerFactory.createPlayer(InCallTonePlayer.TONE_CALL_WAITING);
- mCallWaitingPlayer.startTone(); //使用InCallTonePlayer响起提示音
- }
- }
- }
音量键和电源键停止响铃
系统按键会先在PhoneWindowManager中处理然后再发送到app窗口去处理,关于铃声的PhoneWindowManager会处理,所以不会发送到app再去处理,这个对要修改这个逻辑的同学来说不大友好,不过一般厂商也不改这些默认动作。
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
- public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
- ...
- switch (keyCode) {
- case KeyEvent.KEYCODE_VOLUME_DOWN:
- case KeyEvent.KEYCODE_VOLUME_UP:
- case KeyEvent.KEYCODE_VOLUME_MUTE: {
- ...
- TelecomManager telecomManager = getTelecommService();
- if (telecomManager != null) {
- if (telecomManager.isRinging()) {
- telecomManager.silenceRinger();
- ...
- }
- private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
- ...
- if (telecomManager != null) {
- if (telecomManager.isRinging()) {
- // Pressing Power while there's a ringing incoming
- // call should silence the ringer.
- telecomManager.silenceRinger();
- } else if ((mIncallPowerBehavior
- & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
- && telecomManager.isInCall() && interactive) {
- // Otherwise, if "Power button ends call" is enabled,
- // the Power button will hang up any current active call.
- hungUp = telecomManager.endCall();
- }
- }
- ...
- }
阅读全文
0 0
- 来电铃声和通话中的提示音
- 来电铃声和通话中的提示音
- mt6735 “提示音和通知”中试听手机铃声时来电,来电铃声和预览铃声声音重叠
- FAQ08356][Audio Volume]来电\闹钟\短信提示\铃声预览\拍照音等,在播放过程中插入或者拔出耳机,外放中的铃声音异常
- Android设置来电铃声和分享操作
- Android 系统自动获取来电/短信/提示铃声
- SoundPool提示音铃声
- android 播放来电铃声
- android 设置来电铃声
- Android来电铃声设置
- android5.0联系人铃声设置和来电读取分析
- 来电手机铃声捕获方法
- 设置默认来电铃声 android
- Android 代码设置来电铃声
- Android 修改系统来电铃声
- Android4.22来电铃声流程
- Android 代码设置来电铃声
- Android 代码设置来电铃声
- rem、px、em之间的区别
- Java中的break和continue关键字使用
- Linux--crond和crontab学习
- Nodejs 利用passport完成本地认证 示例一
- 献给写作者的 Markdown 新手指南及语法
- 来电铃声和通话中的提示音
- java读取xml和xml写入数据
- 淘宝、天猫用的Android框架V-Layout,赶紧收藏
- 哈夫曼编码的一个实际应用(压缩与解压)
- toCharArray()和 split()方法
- spirngboot整合mybatis
- Laravel中chunk方法分块处理数据,update需注意
- K-means空间聚类分析
- IntelliJ IDEA破解教程(方式二)