天天看點

android 添加按電源鍵結束通話

首先我們發現現在我們所用的android智能手機大部分都有當你在打電話時按power鍵來挂斷電話,一般都是在設定中。

我主要是在原生源碼中添加這一功能,主要用于學習。。。。先看一張圖:

android 添加按電源鍵結束通話

看到那個按電源鍵挂斷電話吧,那就是我所添加的,本來原生源碼中是沒有這一欄的。。。。。

大概思路:

首先我先添加這一個checkboxpreference,然後将是否選擇這一功能的值(0和1)存到data/data/com.android.providers.settings

/databases/settings.db資料庫的system表中

,然後再根據資料庫表中的值在phonewindownmanager.java中去處理。

具體過程:

首先找到setting的源碼,在源碼下我們要找到通話設定,在seting.xml中我們能找到

[java] view

plaincopy

<span style="font-size:14px;"> <com.android.settings.iconpreferencescreen  

            android:key="call_settings"  

            settings:icon="@drawable/ic_settings_call"  

            android:title="@string/call_settings_title">  

            <intent  

                android:action="android.intent.action.main"  

                android:targetpackage="com.android.phone"  

                android:targetclass="com.android.phone.callfeaturessetting" />  

        </com.android.settings.iconpreferencescreen></span>  

這個call_settings就是我們在setting(設定)中看到的通話設定,但是我們卻不能在settings中的源碼中找到關于call_settings的布局檔案,

是以我們需要找到它,其實這個布局檔案是在package/app/phone中,也就是在phone這個app源碼的資源檔案中。

是以我們在phone的資源檔案下能找到call_feature_setting.xml檔案如下:

<span style="font-size:14px;"><preferencescreen xmlns:android="http://schemas.android.com/apk/res/android"  

    xmlns:phone="http://schemas.android.com/apk/res/com.android.phone"  

        android:title="@string/call_settings">          

    <preferencescreen  

        android:key="button_fdn_key"  

        android:title="@string/fdn"  

        android:summary="@string/sum_fdn"  

        android:persistent="false">  

        <intent android:action="android.intent.action.main"  

            android:targetpackage="com.android.phone"  

            android:targetclass="com.android.phone.fdnsetting" />  

    </preferencescreen>  

    <preferencecategory  

        android:key="button_voicemail_category_key"  

        android:title="@string/voicemail"  

      <listpreference  

          android:key="button_voicemail_provider_key"  

          android:title="@string/voicemail_provider"  

          android:summary="@string/sum_voicemail_choose_provider"  

          android:defaultvalue=""  

          android:persistent="true"  

      />  

      <preferencescreen android:key="button_voicemail_setting_key"  

            android:title="@string/voicemail_settings"  

            android:persistent="false">  

            <!-- note for all com.android.phone.editphonenumberpreference objects  

           the last several attributes are for use with the edittext field  

           in the dialog.  these attributes are forwarded to that field  

           when the edittext is created.  the attributes include:  

             1. android:singleline  

             2. android:autotext  

             3. android:background -->  

              <com.android.phone.editphonenumberpreference  

                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" />  

      </preferencescreen>  

  </preferencecategory>  

。。。。。。。。。。。。。。。。。。  

。。。。。。。。。。。。。。。。。  

</span>  

是以我們可以在最前面添加一個checkboxpreference

<span style="font-size:14px;"><checkboxpreference  

        android:key="press_power_end_call_key"  

        android:title="@string/press_power_end_call"   

        android:persistent="false"/></span>  

變成:

        android:title="@string/call_settings">  

     <checkboxpreference  

        android:persistent="false"/>  

。。。。。。。  

。。。。。。。</span>  

在這裡有自己定義的:

android:title="@string/press_power_end_call" 

是以我們要在資源的string.xml檔案中添加相關的資訊:

在package/app/phone/res/values/string.xml中添加:

<string name="press_power_end_call">press_power_end_call</string>

在package/app/phone/res/values-zh-rcn/string.xml中添加:

<string name="press_power_end_call" msgid="4676390750360727396">按電源鍵挂斷電話</string>

到這裡就算添加好了ui上的東西,接下來就是代碼了:

在package/app/phone/src/com/android/phone下找到callfeaturesetting.java檔案,

在 public boolean onpreferencechange(preference preference, object objvalue) 方法中要增加一個如果選擇了按power鍵挂電話

的事件:

<span style="font-size:14px;">//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       </span>  

在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);  

。。。。。。。。。。。。  

修改後:

               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);  

                            //如果是電話正在打且開啟了這一功能,當按power鍵就挂掉電話    

                            if (telephonyservice.isringing()&&end_call_key==1) {  

                               // telephonyservice.silenceringer();                        

                              hungup=telephonyservice.endcall();  

。。。。。。。。。。。  

由于我這個開發闆上是不能插電話卡的也就沒能實驗成功,但是原理應該就這樣的!

最後修改過的地方都要重新編譯,那麼我們要在源碼下編譯app下的phone以及framework下的policy

最後生成的out/。。。/system/app/phone.apk和out/。。。。/system/framework/android.policy.jar都要替換

手機裡的相同(adb shell 進入你的手機,要有root權限)檔案應該就可以了。