android 添加按(power键)电源键结束通话(挂断电话)
首先我们发现现在我们所用的android智能手机大部分都有当你在打电话时按power键来挂断电话,一般都是在设置中。
我主要是在原生源码中添加这一功能,主要用于学习。。。。先看一张图:
看到那个按电源键挂断电话吧,那就是我所添加的,本来原生源码中是没有这一栏的。。。。。
大概思路:
首先我先添加这一个checkboxPreference,然后将是否选择这一功能的值(0和1)存到data/data/com.android.providers.settings
/databases/settings.db数据库的system表中
,然后再根据数据库表中的值在PhoneWindownManager.java中去处理。
具体过程:
首先找到setting的源码,在源码下我们要找到通话设置,在seting.xml中我们能找到
android:key="call_settings"
settings:icon="@drawable/ic_settings_call"
android:title="@string/call_settings_title">
android:action="android.intent.action.MAIN"
android:targetPackage="com.android.phone"
android:targetClass="com.android.phone.CallFeaturesSetting" />
这个call_settings就是我们在setting(设置)中看到的通话设置,但是我们却不能在settings中的源码中找到关于call_settings的布局文件, 因此我们需要找到它,其实这个布局文件是在package/app/Phone中,也就是在Phone这个app源码的资源文件中。
因此我们在Phone的资源文件下能找到Call_feature_setting.xml文件如下:
xmlns:phone="http://schemas.android.com/apk/res/com.android.phone"
android:title="@string/call_settings">
android:key="button_fdn_key"
android:title="@string/fdn"
android:summary="@string/sum_fdn"
android:persistent="false">
android:targetPackage="com.android.phone"
android:targetClass="com.android.phone.FdnSetting" />
android:key="button_voicemail_category_key"
android:title="@string/voicemail"
android:persistent="false">
android:key="button_voicemail_provider_key"
android:title="@string/voicemail_provider"
android:summary="@string/sum_voicemail_choose_provider"
android:defaultValue=""
android:persistent="true"
/>
android:title="@string/voicemail_settings"
android:persistent="false">
android:key="button_voicemail_key"
android:title="@string/voicemail_settings_number_label"
android:persistent="false"
android:dialogTitle="@string/voicemail"
phone:confirmMode="confirm"
android:singleLine="true"
android:autoText="false" />
。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。
因此我们可以在最前面添加一个checkboxPreference
android:key="press_power_end_call_key"
android:title="@string/press_power_end_call"
android:persistent="false"/>
变成:
xmlns:phone="http://schemas.android.com/apk/res/com.android.phone"
android:title="@string/call_settings">
android:key="press_power_end_call_key"
android:title="@string/press_power_end_call"
android:persistent="false"/>
android:key="button_fdn_key"
android:title="@string/fdn"
android:summary="@string/sum_fdn"
android:persistent="false">
android:targetPackage="com.android.phone"
android:targetClass="com.android.phone.FdnSetting" />
。。。。。。。
。。。。。。。
。。。。。。。
在这里有自己定义的:
android:title="@string/press_power_end_call"
所以我们要在资源的string.xml文件中添加相关的信息:
在package/app/Phone/res/values/string.xml中添加:
press_power_end_call
在package/app/Phone/res/values-zh-rCN/string.xml中添加:
按电源键挂断电话
到这里就算添加好了UI上的东西,接下来就是代码了:
在package/app/Phone/src/com/android/phone下找到CallFeatureSetting.java文件,
在 public boolean onPreferenceChange(Preference preference, Object objValue) 方法中要增加一个如果选择了按power键挂电话的事件:
//add by xxnan
else if (preference == press_power_end_call) {
//如果勾选就将1存到system表的press_power_end_call中
Settings.System.putInt(getContentResolver(),
"press_power_end_call",
press_power_end_call.isChecked() ? 1 : 0);
//end by xxnan
在OnCreate添加如下代码之后:
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
if (DBG) log("Creating activity");
mPhone = PhoneFactory.getDefaultPhone();
addPreferencesFromResource(R.xml.call_feature_setting);
//add by xxnan
ContentResolver resolver = getContentResolver();
press_power_end_call= (CheckBoxPreference)findPreference(press_power_end_call_key);
press_power_end_call.setOnPreferenceChangeListener(this);
// 获的数据库system表里press_power_end_call的值,也就是是否选择了checkboxpreference
int press_power_end_call_key=Settings.System.getInt(getContentResolver(),
"press_power_end_call",0);
//如果得到的值是1,则下次打开setting的话,选项框要勾选
if(press_power_end_call_key==1)
press_power_end_call.setChecked(true);
//end by xxnan
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
// get buttons
PreferenceScreen prefSet = getPreferenceScreen();
mSubMenuVoicemailSettings = (EditPhoneNumberPreference)findPreference(BUTTON_VOICEMAIL_KEY);
。。。。。。。
。。。。。。。
这样就算差不多完成了到获取是否开启这一功能存放和取出到系统数据库中,接下来就是到framework/base/policy/src/com/android
/internal/policy/impl下的
PhoneWindowManager.java中去处理了,之前我们就有分析到PhoneWindowManager.java中的
public int interceptKeyBeforeQueueing(long whenNanos, int action, int flags, int keyCode, int scanCode, int policyFlags,
boolean isScreenOn)方法来接受按power键的事件,在这个方法里我们只需要添加很少代码:
原来代码是:
case KeyEvent.KEYCODE_POWER: {
result &= ~ACTION_PASS_TO_USER;
if (down) {
Log.i("xxnan","xxnan"+"xiaxiangnan");
ITelephony telephonyService = getTelephonyService();
boolean hungUp = false;
if (telephonyService != null) {
try {
if (telephonyService.isRinging()) {
// Pressing Power while there's a ringing incoming
// call should silence the ringer.
telephonyService.silenceRinger();
} else if ((mIncallPowerBehavior
& Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
&& telephonyService.isOffhook()) {
// Otherwise, if "Power button ends call" is enabled,
// the Power button will hang up any current active call.
hungUp = telephonyService.endCall();
}
} catch (RemoteException ex) {
Log.w(TAG, "ITelephony threw RemoteException", ex);
}
}
interceptPowerKeyDown(!isScreenOn || hungUp);
。。。。。。。。。。。。
。。。。。。。。。。。。
修改后:
case KeyEvent.KEYCODE_POWER: {
result &= ~ACTION_PASS_TO_USER;
if (down) {
Log.i("xxnan","xxnan"+"xiaxiangnan");
int end_call_key=Settings.System.getInt(mContext.getContentResolver(),
"press_power_end_call",0); //取出数据库中是否打开这一功能的值
Log.i("end_call_key","end_call_key="+end_call_key);
ITelephony telephonyService = getTelephonyService();
boolean hungUp = false;
if (telephonyService != null) {
try {
//如果是电话正在打且开启了这一功能,当按power键就挂掉电话
if (telephonyService.isRinging()&&end_call_key==1) {
// Pressing Power while there's a ringing incoming
// call should silence the ringer.
// telephonyService.silenceRinger();
hungUp=telephonyService.endCall();
} else if ((mIncallPowerBehavior
& Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
&& telephonyService.isOffhook()) {
// Otherwise, if "Power button ends call" is enabled,
// the Power button will hang up any current active call.
hungUp = telephonyService.endCall();
}
} catch (RemoteException ex) {
Log.w(TAG, "ITelephony threw RemoteException", ex);
}
}
interceptPowerKeyDown(!isScreenOn || hungUp);
。。。。。。。。。。。
。。。。。。。。。。。
由于我这个开发板上是不能插电话卡的也就没能实验成功,但是原理应该就这样的!
最后修改过的地方都要重新编译,那么我们要在源码下编译app下的Phone以及framework下的policy
最后生成的out/。。。/system/app/Phone.apk和out/。。。。/system/framework/android.policy.jar都要替换
手机里的相同(adb shell 进入你的手机,要有root权限)文件应该就可以了。相关阅读:
Android ListView 单条刷新方法实践及原理解析
jQuery学习笔记之jQuery.fn.init()的参数分析
适合新手的CSS网页布局小技巧整理
JS中实现简单Formatter函数示例代码
C#网页跳转方法总结
Symfony学习十分钟入门经典教程
linux grep正则表达式与grep用法详解
12个非常实用的JavaScript小技巧【推荐】
js给selected添加options的方法
win7任务栏只显示图标不显示文字设置方法介绍
浅析IE针对Ajax请求结果的缓存问题
php递归遍历删除文件的方法
Yii2隐藏frontend/web和backend/web的方法
Win10 10102预览版怎么卸载应用程序和添加功能?