mGlobalActions.showDialog,来显示关机、飞行、重启等界面选项。
而我们需要在GlobalActions.java中创建一个重启的选项。下面我们从GlobalActions中的createDialog节选一段代码:
mItems = new ArrayList();
String[] defaultActions = mContext.getResources().getStringArray(
com.android.internal.R.array.config_globalActionsList);//读取配置文件中config_globalActionsList内容,下面详细介绍
ArraySet addedKeys = new ArraySet();
for (int i = 0; i < defaultActions.length; i++) {
String actionKey = defaultActions[i];
if (addedKeys.contains(actionKey)) {
// If we already have added this, don't add it again.
continue;
}
if (GLOBAL_ACTION_KEY_POWER.equals(actionKey)) {
mItems.add(new PowerAction());
} else if (GLOBAL_ACTION_KEY_AIRPLANE.equals(actionKey)) {
mItems.add(mAirplaneModeOn);
else if (GLOBAL_ACTION_KEY_REBOOT.equals(actionKey)) {//我们自己添加了一个重启功能,在config文件中找到reboot这一项就添加这个reboot
mItems.add(new RebootAction());
} else if (GLOBAL_ACTION_KEY_BUGREPORT.equals(actionKey)) {
if (Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0 && isCurrentUserOwner()) {
mItems.add(getBugReportAction());
}
} else if (GLOBAL_ACTION_KEY_SILENT.equals(actionKey)) {
if (mShowSilentToggle) {
mItems.add(mSilentModeAction);
}
} else if (GLOBAL_ACTION_KEY_USERS.equals(actionKey)) {
if (SystemProperties.getBoolean("fw.power_user_switcher", false)) {
addUsersToMenu(mItems);
}
} else if (GLOBAL_ACTION_KEY_SETTINGS.equals(actionKey)) {
mItems.add(getSettingsAction());
} else if (GLOBAL_ACTION_KEY_LOCKDOWN.equals(actionKey)) {
mItems.add(getLockdownAction());
} else {
Log.e(TAG, "Invalid global action key " + actionKey);
}
// Add here so we don't add more than one.
addedKeys.add(actionKey);
}
我们自己还需要新建一个RebootAction,我们看下代码:
private final class RebootAction extends SinglePressAction {
private RebootAction() {
super(com.android.internal.R.drawable.ic_lock_restart,//界面图片和内容
R.string.global_action_restart);
}
public void onPress() {
mWindowManagerFuncs.reboot(true);//长按重启
}
public boolean showDuringKeyguard() {
return true;
}
public boolean showBeforeProvisioning() {
return true;
}
}
还有需要在资源文件中添加一些内容:
需要在core/res/res/values-zh-rCN/strings.xml中添加如下:
"重新启动"
"您要重新启动手机吗?"
"您的手机会重新启动。"
"重新启动"
在core/res/res/values/strings.xml中
Restart
"Would you like to restart?"
"Your phone will restart."
"Restart"
在core/res/res/values/symbols.xml中
还需要添加一个图标的图片
diff --git a/core/res/res/drawable-hdpi/ic_lock_restart.png b/core/res/res/drawable-hdpi/ic_lock_restart.png
diff --git a/core/res/res/drawable-ldpi/ic_lock_restart.png b/core/res/res/drawable-ldpi/ic_lock_restart.png
diff --git a/core/res/res/drawable-mdpi/ic_lock_restart.png b/core/res/res/drawable-mdpi/ic_lock_restart.png
diff --git a/core/res/res/drawable-xhdpi/ic_lock_restart.png b/core/res/res/drawable-xhdpi/ic_lock_restart.png
最后我们需要在core/res/res/values/config.xml中增加几个选项来打开重启等功能
- power
- bugreport
- users
- airplane
//飞行模式
- reboot
//新增重启功能
而上面再GlobalActions中添加的reboot,需要在WindowManagerPolicy新增接口
public void shutdown(boolean confirm);
public void rebootSafeMode(boolean confirm);
public void reboot(boolean confirm);//新增的接口
并且最总在WindowManagerService中实现:
@Override
public void reboot(boolean confirm) {
Log.d(TAG,"reboot confirm:" + confirm);
ShutdownThread.reboot(mContext, null, confirm);
}
最后调用ShutdownThread的reboot函数。
public static void reboot(final Context context, String reason, boolean confirm) {
mReboot = true;//这个参数最后决定是重启还是关机
mRebootSafeMode = false;
mRebootReason = reason;
shutdownInner(context, confirm);
}
下面主要看下ShutdownThread的shutdownInner这个函数,主要是创建弹出框,以及开启线程执行关机或重启。
static void shutdownInner(final Context context, boolean confirm) {
synchronized (sIsStartedGuard) {
if (sIsStarted) {
Log.d(TAG, "Request to shutdown already running, returning.");
return;
}
}
final int longPressBehavior = context.getResources().getInteger(
com.android.internal.R.integer.config_longPressOnPowerBehavior);
final int resourceId = mRebootSafeMode
? com.android.internal.R.string.reboot_safemode_confirm
: (longPressBehavior == 2
? com.android.internal.R.string.shutdown_confirm_question
: com.android.internal.R.string.shutdown_confirm);
Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);
final int resourceIdMsg;
final int resourceIdTitle;
if(mReboot){//这段是我们添加的,根据不同选项创建不同的界面
resourceIdTitle = com.android.internal.R.string.restart;
resourceIdMsg = longPressBehavior == 2
? com.android.internal.R.string.restart_confirm_question
: com.android.internal.R.string.restart_confirm;
}
else if(mRebootSafeMode){
resourceIdTitle = com.android.internal.R.string.reboot_safemode_title;
resourceIdMsg = com.android.internal.R.string.reboot_safemode_confirm;
}
else {
resourceIdTitle = com.android.internal.R.string.power_off;
resourceIdMsg = longPressBehavior == 2
? com.android.internal.R.string.shutdown_confirm_question
: com.android.internal.R.string.shutdown_confirm;
}
if (confirm) {//这个参数决定是否需要弹出对话框
final CloseDialogReceiver closer = new CloseDialogReceiver(context);
if (sConfirmDialog != null) {
sConfirmDialog.dismiss();
}
sConfirmDialog = new AlertDialog.Builder(context)//这边弹出一个对话框也将其进行了修改,主要是显示
.setTitle(resourceIdTitle)
.setMessage(resourceIdMsg)
.setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
beginShutdownSequence(context);//当确认了调用beginShutdownSequence函数,执行关机或重启。
}
})
.setNegativeButton(com.android.internal.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//set the mReboot to default value for next time.
mReboot = false;//不确认就直接结束了,不调用beginShutdownSequence
}
})
.create();
closer.dialog = sConfirmDialog;
sConfirmDialog.setOnDismissListener(closer);
sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
sConfirmDialog.show();
} else {//当不需要确认框弹出,直接调用beginShutdownSequence函数,执行关机或重启。
beginShutdownSequence(context);
}
}
beginShutdownSequence最后会调用sInstance.start();开启线程
因此会到run接口,而run接口最后又会调用rebootOrShutdown,根据reboot是重启还是关机。
public static void rebootOrShutdown(boolean reboot, String reason) {
if (reboot) {
Log.i(TAG, "Rebooting, reason: " + reason);
try {
PowerManagerService.lowLevelReboot(reason);//重启
} catch (Exception e) {
Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);
}
} else if (SHUTDOWN_VIBRATE_MS > 0) {
// vibrate before shutting down
Vibrator vibrator = new SystemVibrator();
try {
vibrator.vibrate(SHUTDOWN_VIBRATE_MS, VIBRATION_ATTRIBUTES);
} catch (Exception e) {
// Failure to vibrate shouldn't interrupt shutdown. Just log it.
Log.w(TAG, "Failed to vibrate during shutdown.", e);
}
// vibrator is asynchronous so we need to wait to avoid shutting down too soon.
try {
Thread.sleep(SHUTDOWN_VIBRATE_MS);
} catch (InterruptedException unused) {
}
}
// Shutdown power
Log.i(TAG, "Performing low-level shutdown...");
PowerManagerService.lowLevelShutdown();//关机
}
这样整个添加重启功能就结束了。