当用户长按power键的时候,系统会在PhoneWindowManager中调用html
mGlobalActions.showDialog,来显示关机、飞行、重启等界面选项。java
而咱们须要在GlobalActions.Java中建立一个重启的选项。下面咱们从GlobalActions中的createDialog节选一段代码:android
[java] view plain copygit
- mItems = new ArrayList<Action>();
- String[] defaultActions = mContext.getResources().getStringArray(
- com.android.internal.R.array.config_globalActionsList);//读取配置文件中config_globalActionsList内容,下面详细介绍
-
- ArraySet<String> addedKeys = new ArraySet<String>();
- 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,咱们看下代码:app
[java] view plain copyasync
- 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;
- }
- }
还有须要在资源文件中添加一些内容:ide
须要在core/res/res/values-zh-rCN/strings.xml中添加以下:函数
[html] view plain copyui
- <string name="global_action_restart">"从新启动"</string>
- <string name="restart_confirm_question">"您要从新启动手机吗?"</string>
- <string name="restart_confirm">"您的手机会从新启动。"</string>
- <string name="restart">"从新启动"</string>
在core/res/res/values/strings.xml中this
[html] view plain copy
- <string name="global_action_restart">Restart</string>
- <string name="restart_confirm_question">"Would you like to restart?"</string>
- <string name="restart_confirm">"Your phone will restart."</string>
- <string name="restart">"Restart"</string>
在core/res/res/values/symbols.xml中
[html] view plain copy
- <java-symbol type="string" name="global_action_restart"/>
- <java-symbol type="string" name="restart_confirm_question"/>
- <java-symbol type="string" name="restart_confirm"/>
- <java-symbol type="string" name="restart"/>
- <java-symbol type="drawable" name="ic_lock_restart" />
还须要添加一个图标的图片
[html] view plain copy
- 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中增长几个选项来打开重启等功能
[html] view plain copy
- <string-array translatable="false" name="config_globalActionsList">
- <item>power</item>
- <item>bugreport</item>
- <item>users</item>
- <item>airplane</item>//飞行模式
- <item>reboot</item>//新增重启功能
- </string-array>
而上面再GlobalActions中添加的reboot,须要在WindowManagerPolicy新增接口
[java] view plain copy
- public void shutdown(boolean confirm);
- public void rebootSafeMode(boolean confirm);
- public void reboot(boolean confirm);//新增的接口
而且最总在WindowManagerService中实现:
[java] view plain copy
- @Override
- public void reboot(boolean confirm) {
- Log.d(TAG,"reboot confirm:" + confirm);
- ShutdownThread.reboot(mContext, null, confirm);
- }
最后调用ShutdownThread的reboot函数。
[java] view plain copy
- public static void reboot(final Context context, String reason, boolean confirm) {
- mReboot = true;//这个参数最后决定是重启仍是关机
- mRebootSafeMode = false;
- mRebootReason = reason;
- shutdownInner(context, confirm);
- }
下面主要看下ShutdownThread的shutdownInner这个函数,主要是建立弹出框,以及开启线程执行关机或重启。
[java] view plain copy
- 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();//关机
- }
这样整个添加剧启功能就结束了。