现在在做双卡双待的项目!作为主要核心Phone遇到的问题也是千奇百怪!
今天就被一个问题困扰了一下午--来电后按声音按键需要静音!因为是双Phone对象所以对应的RINGER也有两个!
分析一下解BUG流程!
最开始以为按键处理会在InCallScreen.java里面的
public boolean onKeyDown(int keyCode, KeyEvent event):
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
Phone phone = PhoneApp.getInstance().getPhoneInCall();
if (phone.getState() == Phone.State.RINGING) {
// If an incoming call is ringing, the VOLUME buttons are
// actually handled by the PhoneWindowManager. (We do
// this to make sure that we'll respond to them even if
// the InCallScreen hasn't come to the foreground yet.)
//
// We'd only ever get here in the extremely rare case that the
// incoming call started ringing *after*
// PhoneWindowManager.interceptKeyTq() but before the event
// got here, or else if the PhoneWindowManager had some
// problem connecting to the ITelephony service.
Log.w(LOG_TAG, "VOLUME key: incoming call is ringing!"
+ " (PhoneWindowManager should have handled this key.)");
// But go ahead and handle the key as normal, since the
// PhoneWindowManager presumably did NOT handle it:
//TODO DSDS get the subscription from Phone
//int subscription = mPhone.getSubscriptionInfo();
final CallNotifier notifier;
if (TelephonyManager.isDsdsEnabled()) {
// Get the CallNotifier associated with the phone.
notifier = PhoneApp.getInstance().getCallNotifier(phone.getSubscription());
} else {
notifier = PhoneApp.getInstance().notifier;
}
if (notifier.isRinging()) {
// ringer is actually playing, so silence it.
PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE);
if (DBG) log("VOLUME key: silence ringer");
notifier.silenceRinger();
}
// As long as an incoming call is ringing, we always
// consume the VOLUME keys.
return true;
}
break;
后来发现了这行注释
// Note there's no KeyEvent.KEYCODE_ENDCALL case here.
// The standard system-wide handling of the ENDCALL key
// (see PhoneWindowManager's handling of KEYCODE_ENDCALL)
// already implements exactly what the UI spec wants,
// namely (1) "hang up" if there's a current active call,
// or (2) "don't answer" if there's a current ringing call.
原来在WindowManagerService会有一个 int actions = mPolicy.interceptKeyTq(event, !screenIsOff);
对应的PhoneWindowManager里会有一个
public int interceptKeyTq(RawInputEvent event, boolean screenIsOn);
方法
此方法可以在最初的位置进行拦截事件处理!
// If an incoming call is ringing, either VOLUME key means
// "silence ringer". We handle these keys here, rather than
// in the InCallScreen, to make sure we'll respond to them
// even if the InCallScreen hasn't come to the foreground yet.
// Look for the DOWN event here, to agree with the "fallback"
// behavior in the InCallScreen.
if (down) {
try {
ITelephony phoneServ = getPhoneInterface();
if (phoneServ != null) {
if (phoneServ.isRinging()) {
Log.i(TAG, "interceptKeyTq:"
+ " VOLUME key-down while ringing: Silence ringer!");
// Silence the ringer. (It's safe to call this
// even if the ringer has already been silenced.)
phoneServ.silenceRinger();
// And *don't* pass this key thru to the current activity
// (which is probably the InCallScreen.)
result &= ~ACTION_PASS_TO_USER;
}
} else {
Log.w(TAG, "VOLUME button: Unable to find ITelephony interface");
}
} catch (RemoteException ex) {
Log.w(TAG, "VOLUME button: RemoteException from getPhoneInterface()", ex);
}
}
phoneServ.silenceRinger();
PhoneInterfaceManager.java
public void silenceRinger() {
if (DBG)
log("silenceRinger...");
// TODO: find a more appropriate permission to check here.
// (That can probably wait till the big TelephonyManager API overhaul.
// For now, protect this call with the MODIFY_PHONE_STATE permission.)
enforceModifyPermission();
sendRequestAsync(CMD_SILENCE_RINGER);
}
最终调用的是
PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE);
mApp.getCallNotifier(i).silenceRinger();
以此来电时按声音键会静音!
当然在InCallScreen.java里面那个是个候补!呵呵呵!这样做的好处就是当你在任何界面做为前台进程时都可以按声音键关掉你的来电铃声!
当然在InCallScreen.java里面的也对按键进行了拦截
比如
public boolean dispatchKeyEvent(KeyEvent event) {
// if (DBG) log("dispatchKeyEvent(event " + event + ")...");
// Intercept some events before they get dispatched to our views.
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_DPAD_UP:
case KeyEvent.KEYCODE_DPAD_DOWN:
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_RIGHT:
// Disable DPAD keys and trackball clicks if the touch lock
// overlay is up, since "touch lock" really means "disable
// the DTMF dialpad" (rather than only disabling touch events.)
if (mDialer.isOpened() && isTouchLocked()) {
if (DBG) log("- ignoring DPAD event while touch-locked...");
return true;
}
break;
default:
break;
}
return super.dispatchKeyEvent(event);
}
这样做是为了区别某哥界面的状态对应的按键事件!比如Incallscreen接了电话和没接电话几个按键的事件就不同!
分享到:
相关推荐
android黑名单设置 来电自动静音,可以使用,代码很清晰。
android 静音与马达振动流程.doc vibrator timed_output
android webrtc vad(静音检测) demo webrtc的vad静音检测音频处理模块,含源码。VAD 录音过程中,实时检测当前是否有人在讲话(语音活动检测,或者叫静音检测)。讲话时webRtcVad_Process返回true,不讲话时返回...
Android来电防火墙项目主要是面对android手机用户开发的应用程序,该应用程序可以根据用户的需求自行设置,是进行电话拦截,还是短信拦截,同时还可以设置是只拦截黑名单,只接受白名单和关闭防火墙。其次还可以设置...
VAD - 录音过程中,实时检测当前是否有人在讲话(语音活动检测,或者叫静音检测)。讲话时webRtcVad_Process返回true,不讲话时返回false。直接用android studio打开,编译后“喂喂”两下,看log即可。by tanyaping...
主要介绍了手机来电铃声响起后,通过此代码实现静音而非挂断的方法的相关资料
android静音模式震动模式选择情景模式的选择.zip,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
这是一个Android应用程序,我从书上敲下来的,修改了一些小错误,在AVD上运行试验过。
android 静音模式震动模式选择 情景模式的选择
android 利用重力感应监听 微修改代码可以解决 来电时翻转手机后静音。
Android 静音控制 音量控制 减小增大音量的实例源代码,如示图所示,音量控制时候,适时显示音量进度条: ToggleButton tbMute = (ToggleButton)findViewById(R.id.tbMute);//获得ToggleButton对象 tbMute....
无声音频静音音频Android保活安卓保活(强烈建议不要这么做,不仅仅从用户角度考虑,它只会滋生更多的流氓应用,拖垮Android 平台的流畅性)mute_wave.wav
Android系统定制-SystemUI-下拉状态栏快捷设置新增选项(自动亮度&静音)_Patch 文章链接:https://blog.csdn.net/qq_33750826/article/details/122829104
里面有的内容可能你不需要,有的内容可以扩充。 这个是关于android手机情景模式设置的小例子。希望对大家有利
静音模式的类库及相关文件,具体使用方法参考个人博客(http://blog.csdn.net/weasleyqi)。
翻转静音简单的 Android 应用程序,如果您将手机面朝下放在桌子上,它会使您的手机静音。 我发现它非常有用,但从未尝试将其放在 android 市场上。
One Shot Filter Silent(一键静音相机)是一款Android平台静音拍照软件。提供了多种滤镜模式,一键成像。 特点: 彩色画笔,黑白,模煳,凋塑等多种滤镜效果。 静音拍照,让你尽情享受拍照的乐趣而不会...
本文为大家详细介绍下android系统如何在静音模式下关闭camera拍照声音,具体的实现方法如下,感兴趣的朋友可以参考下哈
g711a静音包 320个字节