zoukankan      html  css  js  c++  java
  • Android 4.1.2系统添加重启功能

    对于Android的的手机或者平板长期使用,感觉会出现慢的情况,所以偶尔还是需要重启一下,而长按电源键弹出的菜单又没有重启选项,所以特在此记录自己添加这个功能的过程。
    首先关机的那个弹出菜单是在frameworks/base/policy/src/com/android/internal/policy/impl/GlobalActions.java这个文件中创建的:

    点击(此处)折叠或打开

    1. /**
    2.  * Create the global actions dialog.
    3.  * @return A new dialog.
    4.  */
    5. private GlobalActionsDialog createDialog() {
    6.     // Simple toggle style if there's no vibrator, otherwise use a tri-state
    7.     if (!mHasVibrator) {
    8.         mSilentModeAction = new SilentModeToggleAction();
    9.     } else {
    10.         mSilentModeAction = new SilentModeTriStateAction(mContext, mAudioManager, mHandler);
    11.     }
    12.     mAirplaneModeOn = new ToggleAction(
    13.             R.drawable.ic_lock_airplane_mode,
    14.             R.drawable.ic_lock_airplane_mode_off,
    15.             R.string.global_actions_toggle_airplane_mode,
    16.             R.string.global_actions_airplane_mode_on_status,
    17.             R.string.global_actions_airplane_mode_off_status) {

    18.         void onToggle(boolean on) {
    19.             if (mHasTelephony && Boolean.parseBoolean(
    20.                     SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
    21.                 mIsWaitingForEcmExit = true;
    22.                 // Launch ECM exit dialog
    23.                 Intent ecmDialogIntent =
    24.                         new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);
    25.                 ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    26.                 mContext.startActivity(ecmDialogIntent);
    27.             } else {
    28.                 changeAirplaneModeSystemSetting(on);
    29.             }
    30.         }

    31.         @Override
    32.         protected void changeStateFromPress(boolean buttonOn) {
    33.             if (!mHasTelephony) return;

    34.             // In ECM mode airplane state cannot be changed
    35.             if (!(Boolean.parseBoolean(
    36.                     SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {
    37.                 mState = buttonOn ? State.TurningOn : State.TurningOff;
    38.                 mAirplaneState = mState;
    39.             }
    40.         }

    41.         public boolean showDuringKeyguard() {
    42.             return true;
    43.         }

    44.         public boolean showBeforeProvisioning() {
    45.             return false;
    46.         }
    47.     };
    48.     onAirplaneModeChanged();

    49.     mItems = new ArrayList<Action>();

    50.     // first: power off
    51.     mItems.add(
    52.         new SinglePressAction(
    53.                 com.android.internal.R.drawable.ic_lock_power_off,
    54.                 R.string.global_action_power_off) {

    55.             public void onPress() {
    56.                 // shutdown by making sure radio and power are handled accordingly.
    57.                 mWindowManagerFuncs.shutdown(true);
    58.             }

    59.             public boolean onLongPress() {
    60.                 mWindowManagerFuncs.rebootSafeMode(true);
    61.                 return true;
    62.             }

    63.             public boolean showDuringKeyguard() {
    64.                 return true;
    65.             }

    66.             public boolean showBeforeProvisioning() {
    67.                 return true;
    68.             }
    69.         });
    我们可以看到mItems.add函数是添加一个选项,该菜单的第一个选项就是关机选项,我们可以在此之后添加重启选项,代码如下:

    1. mItems.add(
    2.     new SinglePressAction(
    3.         com.android.internal.R.drawable.ic_lock_power_off,
    4.         R.string.global_action_reboot) { 
    5.      
    6.         public void onPress() { 
    7.             // reboot 
    8.             mWindowManagerFuncs.reboot();
    9.         } 
    10.          
    11.         public boolean showDuringKeyguard() { 
    12.             return true;
    13.         } 
    14.          
    15.         public boolean showBeforeProvisioning() { 
    16.             return true; 
    17.         } 
    18.     });
    上面的代码中使用了mWindowManagerFuncs.reboot函数和R.string.global_action_reboot资源,因此我们需要该资源并实现reboot函数。
    首先在frameworks/base/core/java/android/view/WindowManagerPolicy.java中添加reboot接口:

    1. /**
    2.  * Interface for calling back in to the window manager that is private
    3.  * between it and the policy.
    4.  */
    5. public interface WindowManagerFuncs {

    6.     ...

    7.     /**
    8.      * Switch the keyboard layout for the given device.
    9.      * Direction should be +1 or -1 to go to the next or previous keyboard layout.
    10.      */
    11.     public void switchKeyboardLayout(int deviceId, int direction);

    12.     public void shutdown();
    13.     public void reboot(); 
    14.     public void rebootSafeMode();
    15. }
    然后在frameworks/base/services/java/com/android/server/wm/WindowManagerService.java中实现该接口:

    1. // Called by window manager policy. Not exposed externally.
    2. @Override
    3. public void shutdown() {
    4.     ShutdownThread.shutdown(mContext, true);
    5. }

    6. // Called by window manager policy. Not exposed externally.
    7. @Override
    8. public void reboot() {
    9.     ShutdownThread.reboot(mContext, null, true);
    10. }

    11. // Called by window manager policy. Not exposed externally. 
    12. @Override
    13. public void rebootSafeMode() {
    14.     ShutdownThread.rebootSafeMode(mContext, true);
    15. }
    接下来,为了在按下重启选项之后,能出现”重启“之类的提示,还需要修改frameworks/base/services/java/com/android/server/pm/ShutdownThread.java中的shutdownInner函数和beginShutdownSequence函数:

    1. static void shutdownInner(final Context context, boolean confirm) {
    2.     // ensure that only one thread is trying to power down.
    3.     // any additional calls are just returned
    4.     synchronized (sIsStartedGuard) {
    5.         if (sIsStarted) {
    6.             Log.d(TAG, "Request to shutdown already running, returning.");
    7.             return;
    8.         }
    9.     }

    10.     final int longPressBehavior = context.getResources().getInteger(
    11.                     com.android.internal.R.integer.config_longPressOnPowerBehavior);
    12.     final int resourceId = mRebootSafeMode
    13.             ? com.android.internal.R.string.reboot_safemode_confirm
    14.             : (longPressBehavior == 2
    15.                     ? com.android.internal.R.string.shutdown_confirm_question
    16.                     : (mReboot ? com.android.internal.R.string.reboot_confirm :
    17.                         com.android.internal.R.string.shutdown_confirm));

    18.     Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);

    19.     if (confirm) {
    20.         final CloseDialogReceiver closer = new CloseDialogReceiver(context);
    21.         final AlertDialog dialog = new AlertDialog.Builder(context)
    22.                 .setTitle(mRebootSafeMode
    23.                         ? com.android.internal.R.string.reboot_safemode_title
    24.                         : (mReboot ? com.android.internal.R.string.reboot :
    25.                             com.android.internal.R.string.power_off))
    26.                 .setMessage(resourceId)
    27.                 .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
    28.                     public void onClick(DialogInterface dialog, int which) {
    29.                         beginShutdownSequence(context);
    30.                     }
    31.                 })
    32.                 .setNegativeButton(com.android.internal.R.string.no, null)
    33.                 .create();
    34.         closer.dialog = dialog;
    35.         dialog.setOnDismissListener(closer);
    36.         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
    37.         dialog.show();
    38.     } else {
    39.         beginShutdownSequence(context);
    40.     }
    41. }

    42. private static void beginShutdownSequence(Context context) {
    43.    synchronized (sIsStartedGuard) {
    44.        if (sIsStarted) {
    45.            Log.d(TAG, "Shutdown sequence already running, returning.");
    46.            return;
    47.        }
    48.        sIsStarted = true;
    49.    }

    50.    // throw up an indeterminate system dialog to indicate radio is
    51.    // shutting down.
    52.    ProgressDialog pd = new ProgressDialog(context);
    53.    pd.setTitle(context.getText(com.android.internal.R.string.power_off));
    54.    pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
    55.    pd.setIndeterminate(true);
    56.    pd.setCancelable(false);
    57.    pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);

    58.    pd.show();

    59.    sInstance.mContext = context;
    60.    sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);

    61.    // make sure we never fall asleep again
    62.    sInstance.mCpuWakeLock = null;
    63.    try {
    64.        sInstance.mCpuWakeLock = sInstance.mPowerManager.newWakeLock(
    65.                PowerManager.PARTIAL_WAKE_LOCK, TAG + "-cpu");
    66.        sInstance.mCpuWakeLock.setReferenceCounted(false);
    67.        sInstance.mCpuWakeLock.acquire();
    68.    } catch (SecurityException e) {
    69.        Log.w(TAG, "No permission to acquire wake lock", e);
    70.        sInstance.mCpuWakeLock = null;
    71.    }

    72.    // also make sure the screen stays on for better user experience
    73.    sInstance.mScreenWakeLock = null;
    74.    if (sInstance.mPowerManager.isScreenOn()) {
    75.        try {
    76.            sInstance.mScreenWakeLock = sInstance.mPowerManager.newWakeLock(
    77.                    PowerManager.FULL_WAKE_LOCK, TAG + "-screen");
    78.            sInstance.mScreenWakeLock.setReferenceCounted(false);
    79.            sInstance.mScreenWakeLock.acquire();
    80.        } catch (SecurityException e) {
    81.            Log.w(TAG, "No permission to acquire wake lock", e);
    82.            sInstance.mScreenWakeLock = null;
    83.        }
    84.    }

    85.    // start the thread that initiates shutdown
    86.    sInstance.mHandler = new Handler() {
    87.    };
    88.    sInstance.start();
    89. }
    至此关于代码部分的改动全部完成,接下来就需要添加使用到的资源了,就是前面用到的字符串。首先需要在frameworks/base/core/res/res/values/strings.xml中添加一下字符串:

    1. <string name="reboot">Reboot</string>
    2. <string name="reboot_progress">Rebootu2026</string>
    3. <string name="reboot_confirm" product="tablet">Your tablet will reboot.</string>
    4. <string name="reboot_confirm" product="default">Your phone will reboot.</string>
    5. <!-- label for item that reboot in phone options dialog -->
    6. <string name="global_action_reboot">Reboot</string>
    而后需要在frameworks/base/core/res/res/values/public.xml中声明这些资源,否则编译的时候会出现找不到该资源的错误。

    1. <java-symbol type="string" name="reboot" />
    2. <java-symbol type="string" name="reboot_confirm" />
    3. <java-symbol type="string" name="reboot_progress" />
    4. <java-symbol type="string" name="global_action_reboot" />
    至此,全部修改完成,编译烧写即可。
  • 相关阅读:
    物联网操作系统HelloX V1.77(beta)版本发布
    对XX证券报关于物联网操作系统的几个问题的答复
    Android利用广播实现ViewPager中item之间的数据通信
    Android创建桌面快捷方式
    Android时间选择器对话框的使用
    Android数据库LitePal的存储操作
    Android创建数据表和LitePal的基本用法
    我的2014
    logstash 安装zabbix插件
    tag_on_failure => [] # prevent default _grokparsefailure tag on real records
  • 原文地址:https://www.cnblogs.com/liang123/p/6325384.html
Copyright © 2011-2022 走看看