定制Android设备的关机对话框
使用Android系统的手机设备,在长按电源开关后会出现一个对话框:静音模式,数据网络模式(数据流开关),飞行模式,关机。对于MIPS设备我们并不需要太多选项,关机是否就可以。
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方法显示对话框。
void showGlobalActionsDialog() {
if (mGlobalActions == null) {
mGlobalActions = new GlobalActions(mContext);
}
final boolean keyguardShowing = mKeyguardMediator.isShowingAndNotHidden();
mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
//对话框的内容在GlobalActions中被创建
if (keyguardShowing) {
// since it took two seconds of long press to bring this up,
// poke the wake lock so they have some time to see the dialog.
mKeyguardMediator.pokeWakelock();
}
}
现在不是要显示对话框而是是否进行关机操作,所以把调用用showGlobalActionsDialog()方法的代码注释。改为关机操作的代码:
frameworks\policies\base\phone\com\android\internal\policy\impl\GlobalActions.java
修改创建对话框的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;
}
};
对话框列表项,当选择对话框中的关机时将调用ShutdownThread.shutdown()方法,参数true表示关机操作
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;
}
所以要实现关机操作只需要调用ShutdownThread的shutdown()并传入第二个参数为false。
对于实现长按电源开关后只显示是否关机操作,在PhoneWindowManager.java的代码中直接调用shutdown() 完成:
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, false);
}
};
这些可以根据自己的需要进行修改定制。比如加入重启系统的选项:
在代码mItems = Lists.newArrayList( 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){。。。。。}
new SinglePressAction( com.android.internal.R.drawable.ic_lock_power_off, R.string.global_action_reboot_off //自己加入的系统字符串){
public void onPress() {
// shutdown by making sure radio and power are handled accordingly.
ShutdownThread.reboot(mContext, "" , true ); //第二个参数不知道是什么
} ...............其他和关机一样
}
);
reboot方法源码:
/**
* Request a clean shutdown, waiting for subsystems to clean up their
* state etc. Must be called from a Looper thread in which its UI
* is shown.
*
* @param context Context used to display the shutdown progress dialog.
* @param reason code to pass to the kernel (e.g. "recovery"), or null.
* 第二个参数是一个String,如果这个String是NULL的话,就是正常重 启,如果是recovery,系统重启进入(恢复)recovery mode。
@param confirm true if user confirmation is needed before shutting down.
*/
public static void reboot(final Context context, String reason, boolean confirm) {
mReboot = true;
mRebootReason = reason;
shutdown(context, confirm);//关机
}