android源碼定製之初探–定製android關機介面

來源:互聯網
上載者:User

LouisWang

轉載請註明出處:http://blog.csdn.net/louiswangbing/article/details/6688240

上一篇文章中講到android源碼定製要點,說了個大概的方法和方向,現在,就來實戰一下。

在Android系統中,長按Power鍵預設會彈出對話方塊讓你選擇“飛航模式”,“靜音”,“關機”等功能。如所示:


但這些功能都對Android-x86和其他終端產品就沒什麼必要了。本文就簡單介紹下如何定製關機介面。

我的目標是長按Power鍵,將會關機,彈出“裝置將要關機”選擇對話方塊。如果可以選擇“是”關機,和“否”返回系統。 

按照android源碼定製要點中提到的,首先你要對整個系統有全面的瞭解,找到彈出原來這個選擇框的代碼,它在這裡:

frameworks\policies\base\phone\com\android\internal\policy\impl\PhoneWindowManager.java  

顯示對話方塊調用的代碼如下:

    Runnable mPowerLongPress = new Runnable() {          public void run() {              mShouldTurnOffOnKeyUp = false;              performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);              sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);              showGlobalActionsDialog();          }      };  

調用showGlobalActionsDialog方法之後將會聚到有“飛航模式”、“靜音”、“關機”等選項的對話方塊。

找到這裡,我們就知道該做什麼了!幹掉它,換成我們想要的關機代碼,就大功告成了!既然這樣,事不宜遲,讓我們趕快到showGloabalActionDialog方法中看看關機的部分在哪裡!

showGlobalActionsDialog的實現部分在這裡:

frameworks\policies\base\phone\com\android\internal\policy\impl\GlobalAction.java

我們進去看看:

    public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {        mKeyguardShowing = keyguardShowing;        mDeviceProvisioned = isDeviceProvisioned;        if (mDialog == null) {            mStatusBar = (StatusBarManager)mContext.getSystemService(Context.STATUS_BAR_SERVICE);            mDialog = createDialog();        }        prepareDialog();        mStatusBar.disable(StatusBarManager.DISABLE_EXPAND);        mDialog.show();    }

我們可以很清楚的看到,這裡建立了一個mDialog,然後prepare接著就show了它,那麼,這個mDialog就是關鍵了,看看它是怎麼被createDialog建立出來的吧,仍然在這個檔案中:

    /**     * Create the global actions dialog.     * @return A new dialog.     */    private AlertDialog createDialog() {        mSilentModeToggle = new ToggleAction(                R.drawable.ic_lock_silent_mode,                R.drawable.ic_lock_silent_mode_off,                R.string.global_action_toggle_silent_mode,                R.string.global_action_silent_mode_on_status,                R.string.global_action_silent_mode_off_status) {            void willCreate() {                // XXX: FIXME: switch to ic_lock_vibrate_mode when available                mEnabledIconResId = (Settings.System.getInt(mContext.getContentResolver(),                        Settings.System.VIBRATE_IN_SILENT, 1) == 1)                    ? R.drawable.ic_lock_silent_mode_vibrate                    : R.drawable.ic_lock_silent_mode;            }            void onToggle(boolean on) {                if (on) {                    mAudioManager.setRingerMode((Settings.System.getInt(mContext.getContentResolver(),                        Settings.System.VIBRATE_IN_SILENT, 1) == 1)                        ? AudioManager.RINGER_MODE_VIBRATE                        : AudioManager.RINGER_MODE_SILENT);                } else {                    mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);                }            }            public boolean showDuringKeyguard() {                return true;            }            public boolean showBeforeProvisioning() {                return false;            }        };        mAirplaneModeOn = new ToggleAction(                R.drawable.ic_lock_airplane_mode,                R.drawable.ic_lock_airplane_mode_off,                R.string.global_actions_toggle_airplane_mode,                R.string.global_actions_airplane_mode_on_status,                R.string.global_actions_airplane_mode_off_status) {            void onToggle(boolean on) {                if (Boolean.parseBoolean(                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {                    mIsWaitingForEcmExit = true;                    // Launch ECM exit dialog                    Intent ecmDialogIntent =                            new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);                    ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                    mContext.startActivity(ecmDialogIntent);                } else {                    changeAirplaneModeSystemSetting(on);                }            }            @Override            protected void changeStateFromPress(boolean buttonOn) {                // In ECM mode airplane state cannot be changed                if (!(Boolean.parseBoolean(                        SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {                    mState = buttonOn ? State.TurningOn : State.TurningOff;                    mAirplaneState = mState;                }            }            public boolean showDuringKeyguard() {                return true;            }            public boolean showBeforeProvisioning() {                return false;            }        };        mItems = Lists.newArrayList(                // silent mode                mSilentModeToggle,                // next: airplane mode                mAirplaneModeOn,                // last: power off                new SinglePressAction(                        com.android.internal.R.drawable.ic_lock_power_off,                        R.string.global_action_power_off) {                    public void onPress() {                        // shutdown by making sure radio and power are handled accordingly.                        ShutdownThread.shutdown(mContext, true);                    }                    public boolean showDuringKeyguard() {                        return true;                    }                    public boolean showBeforeProvisioning() {                        return true;                    }                });        mAdapter = new MyAdapter();        final AlertDialog.Builder ab = new AlertDialog.Builder(mContext);        ab.setAdapter(mAdapter, this)                .setInverseBackgroundForced(true)                .setTitle(R.string.global_actions);        final AlertDialog dialog = ab.create();        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);        if (!mContext.getResources().getBoolean(                com.android.internal.R.bool.config_sf_slowBlur)) {            dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,                    WindowManager.LayoutParams.FLAG_BLUR_BEHIND);        }        dialog.setOnDismissListener(this);        return dialog;    }

看看我們發現了什麼!!藍色的部分就是關機調用的函數了!!shutdown方法的第二個參數標識是否彈出詢問對話方塊。你可以選擇需要(true)或者不需要(false)。這裡我保守一點,還是選個true吧,萬一不小心按到關機鍵呢,呵呵。。。

也就是說,只要我們用

ShutdownThread.shutdown(mContext, true);

替換掉前面的

showGlobalActionsDialog();  

就可以大功告成了!還等什麼!我們修改

frameworks\policies\base\phone\com\android\internal\policy\impl\PhoneWindowManager.java  

的原始碼如下:

    Runnable mPowerLongPress = new Runnable() {        public void run() {            mShouldTurnOffOnKeyUp = false;            performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);            sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);            //showGlobalActionsDialog();            ShutdownThread.shutdown(mContext, true);         }    };

好了,大功告成了!!

是不是就這樣完了呢?發現編譯不過。。。

細節很重要!!

原來ShutdownThread.shutdown(mContext, true)的引用包沒加進來!!幸好有gcc。。。

import com.android.internal.app.ShutdownThread;

將上面這個包加到

frameworks\policies\base\phone\com\android\internal\policy\impl\PhoneWindowManager.java  

中,再次編譯,通過,YES!

看看我們的戰果吧:


是不是感覺到源碼定製的快感和成就感了呢?

這僅僅只是個開始,好戲還在後頭呢!!哈哈

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.