android源碼探索之定制android關(guān)機界面的方法
本文實例講述了android源碼探索之定制android關(guān)機界面的方法。分享給大家供大家參考。具體如下:
在Android系統(tǒng)中,長按Power鍵默認會彈出對話框讓你選擇“飛行模式”,“靜音”,“關(guān)機”等功能。如下圖所示:

但這些功能都對Android-x86和其他終端產(chǎn)品就沒什么必要了。本文就簡單介紹下如何定制關(guān)機界面。
我的目標(biāo)是長按Power鍵,將會關(guān)機,彈出“設(shè)備將要關(guān)機”選擇對話框。如果可以選擇“是”關(guān)機,和“否”返回系統(tǒng)。
按照android源碼定制要點中提到的,首先你要對整個系統(tǒng)有全面的了解,找到彈出原來這個選擇框的代碼,它在這里:
<pre name="code" class="java">frameworks\policies\base\phone\com\android\internal\policy\impl\PhoneWindowManager.java
顯示對話框調(diào)用的代碼如下:
Runnable mPowerLongPress = new Runnable() {
public void run() {
mShouldTurnOffOnKeyUp = false;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
showGlobalActionsDialog();
}
};
調(diào)用showGlobalActionsDialog方法之后將會聚到有“飛行模式”、“靜音”、“關(guān)機”等選項的對話框。
找到這里,我們就知道該做什么了!干掉它,換成我們想要的關(guān)機代碼,就大功告成了!既然這樣,事不宜遲,讓我們趕快到showGloabalActionDialog方法中看看關(guān)機的部分在哪里!
showGlobalActionsDialog的實現(xiàn)部分在這里:
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就是關(guān)鍵了,看看它是怎么被createDialog創(chuàng)建出來的吧,仍然在這個文件中:
/**
* 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;
}
};
<span style="color:#ff0000;">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) {
</span><span style="color:#3333ff;"><u>public void onPress() {
// shutdown by making sure radio and power are handled accordingly.
ShutdownThread.shutdown(mContext, true);
}</u></span><span style="color:#ff0000;">
public boolean showDuringKeyguard() {
return true;
}
public boolean showBeforeProvisioning() {
return true;
}</span>
});
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;
}
看看我們發(fā)現(xiàn)了什么??!藍色的部分就是關(guān)機調(diào)用的函數(shù)了??!shutdown方法的第二個參數(shù)標(biāo)識是否彈出詢問對話框。你可以選擇需要(true)或者不需要(false)。這里我保守一點,還是選個true吧,萬一不小心按到關(guān)機鍵呢,呵呵。。。
也就是說,只要我們用
替換掉前面的
就可以大功告成了!還等什么!我們修改
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);
}
};
好了,大功告成了??!
是不是就這樣完了呢?發(fā)現(xiàn)編譯不過。。。
細節(jié)很重要?。?/p>
原來ShutdownThread.shutdown(mContext, true)的引用包沒加進來??!幸好有g(shù)cc。。。
將上面這個包加到
frameworks\policies\base\phone\com\android\internal\policy\impl\PhoneWindowManager.java
中,再次編譯,通過,YES!
看看我們的戰(zhàn)果吧:

是不是感覺到源碼定制的快感和成就感了呢?
這僅僅只是個開始,好戲還在后頭呢??!哈哈
希望本文所述對大家的Android程序設(shè)計有所幫助。
相關(guān)文章
Android框架Volley使用:ImageRequest請求實現(xiàn)圖片加載
這篇文章主要介紹了Android框架Volley使用:ImageRequest請求實現(xiàn)圖片加載的相關(guān)知識,非常不錯,具有一定的參考借鑒價值 ,需要的朋友可以參考下2019-05-05
Android實現(xiàn)創(chuàng)意LoadingView動畫效果
這篇文章主要介紹了Android實現(xiàn)創(chuàng)意LoadingView動畫效果的相關(guān)資料,需要的朋友可以參考下2016-02-02
Android 開發(fā)使用PopupWindow實現(xiàn)加載等待界面功能示例
這篇文章主要介紹了Android 開發(fā)使用PopupWindow實現(xiàn)加載等待界面功能,結(jié)合實例形式分析了Android使用PopupWindow組件實現(xiàn)加載等待界面功能相關(guān)布局與功能實現(xiàn)技巧,需要的朋友可以參考下2020-05-05
Android自定義View實現(xiàn)圓形環(huán)繞效果
這篇文章主要為大家詳細介紹了Android自定義View實現(xiàn)圓形環(huán)繞效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-01-01

