«

Android 4.1.2系统添加重启功能

时间:2024-3-2 19:28     作者:韩俊     分类: Android


转自:http://blog.chinaunix.net/uid-20729605-id-3779071.html


对于Android的的手机或者平板长期使用,感觉会出现慢的情况,所以偶尔还是需要重启一下,而长按电源键弹出的菜单又没有重启选项,所以特在此记录自己添加这个功能的过程。

首先关机的那个弹出菜单是在frameworks/base/policy/src/com/android/internal/policy/impl/GlobalActions.java这个文件中创建的:



/**

  • Create the global actions dialog.

  • @return A new dialog.

    */

private GlobalActionsDialog createDialog() {

// Simple toggle style if there's no vibrator, otherwise use a tri-state<br style="word-wrap:break-word">

if (!mHasVibrator) {<br style="word-wrap:break-word">

    mSilentModeAction = new SilentModeToggleAction();<br style="word-wrap:break-word">

} else {<br style="word-wrap:break-word">

    mSilentModeAction = new SilentModeTriStateAction(mContext, mAudioManager, mHandler);<br style="word-wrap:break-word">

}<br style="word-wrap:break-word">

mAirplaneModeOn = new ToggleAction(<br style="word-wrap:break-word">

        R.drawable.ic_lock_airplane_mode,<br style="word-wrap:break-word">

        R.drawable.ic_lock_airplane_mode_off,<br style="word-wrap:break-word">

        R.string.global_actions_toggle_airplane_mode,<br style="word-wrap:break-word">

        R.string.global_actions_airplane_mode_on_status,<br style="word-wrap:break-word">

        R.string.global_actions_airplane_mode_off_status) {<br style="word-wrap:break-word">


    void onToggle(boolean on) {<br style="word-wrap:break-word">

        if (mHasTelephony &amp;&amp; Boolean.parseBoolean(<br style="word-wrap:break-word">

                SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {<br style="word-wrap:break-word">

            mIsWaitingForEcmExit = true;<br style="word-wrap:break-word">

            // Launch ECM exit dialog<br style="word-wrap:break-word">

            Intent ecmDialogIntent =<br style="word-wrap:break-word">

                    new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);<br style="word-wrap:break-word">

            ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);<br style="word-wrap:break-word">

            mContext.startActivity(ecmDialogIntent);<br style="word-wrap:break-word">

        } else {<br style="word-wrap:break-word">

            changeAirplaneModeSystemSetting(on);<br style="word-wrap:break-word">

        }<br style="word-wrap:break-word">

    }<br style="word-wrap:break-word">


    @Override<br style="word-wrap:break-word">

    protected void changeStateFromPress(boolean buttonOn) {<br style="word-wrap:break-word">

        if (!mHasTelephony) return;<br style="word-wrap:break-word">


        // In ECM mode airplane state cannot be changed<br style="word-wrap:break-word">

        if (!(Boolean.parseBoolean(<br style="word-wrap:break-word">

                SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {<br style="word-wrap:break-word">

            mState = buttonOn ? State.TurningOn : State.TurningOff;<br style="word-wrap:break-word">

            mAirplaneState = mState;<br style="word-wrap:break-word">

        }<br style="word-wrap:break-word">

    }<br style="word-wrap:break-word">


    public boolean showDuringKeyguard() {<br style="word-wrap:break-word">

        return true;<br style="word-wrap:break-word">

    }<br style="word-wrap:break-word">


    public boolean showBeforeProvisioning() {<br style="word-wrap:break-word">

        return false;<br style="word-wrap:break-word">

    }<br style="word-wrap:break-word">

};<br style="word-wrap:break-word">

onAirplaneModeChanged();<br style="word-wrap:break-word">


mItems = new ArrayList&lt;Action&gt;();<br style="word-wrap:break-word">


// first: power off<br style="word-wrap:break-word">

mItems.add(<br style="word-wrap:break-word">

    new SinglePressAction(<br style="word-wrap:break-word">

            com.android.internal.R.drawable.ic_lock_power_off,<br style="word-wrap:break-word">

            R.string.global_action_power_off) {<br style="word-wrap:break-word">


        public void onPress() {<br style="word-wrap:break-word">

            // shutdown by making sure radio and power are handled accordingly.<br style="word-wrap:break-word">

            mWindowManagerFuncs.shutdown(true);<br style="word-wrap:break-word">

        }<br style="word-wrap:break-word">


        public boolean onLongPress() {<br style="word-wrap:break-word">

            mWindowManagerFuncs.rebootSafeMode(true);<br style="word-wrap:break-word">

            return true;<br style="word-wrap:break-word">

        }<br style="word-wrap:break-word">


        public boolean showDuringKeyguard() {<br style="word-wrap:break-word">

            return true;<br style="word-wrap:break-word">

        }<br style="word-wrap:break-word">


        public boolean showBeforeProvisioning() {<br style="word-wrap:break-word">

            return true;<br style="word-wrap:break-word">

        }<br style="word-wrap:break-word">

    });

我们可以看到mItems.add函数是添加一个选项,该菜单的第一个选项就是关机选项,我们可以在此之后添加重启选项,代码如下:


mItems.add(

new SinglePressAction(<br style="word-wrap:break-word">

    com.android.internal.R.drawable.ic_lock_power_off,<br style="word-wrap:break-word">

    R.string.global_action_reboot) { <br style="word-wrap:break-word">

 <br style="word-wrap:break-word">

    public void onPress() { <br style="word-wrap:break-word">

        // reboot <br style="word-wrap:break-word">

        mWindowManagerFuncs.reboot();<br style="word-wrap:break-word">

    } <br style="word-wrap:break-word">

     <br style="word-wrap:break-word">

    public boolean showDuringKeyguard() { <br style="word-wrap:break-word">

        return true;<br style="word-wrap:break-word">

    } <br style="word-wrap:break-word">

     <br style="word-wrap:break-word">

    public boolean showBeforeProvisioning() { <br style="word-wrap:break-word">

        return true; <br style="word-wrap:break-word">

    } <br style="word-wrap:break-word">

});

上面的代码中使用了mWindowManagerFuncs.reboot函数和R.string.global_action_reboot资源,因此我们需要该资源并实现reboot函数。

首先在frameworks/base/core/java/android/view/WindowManagerPolicy.java中添加reboot接口:


/**

  • Interface for calling back in to the window manager that is private

  • between it and the policy.

    */

public interface WindowManagerFuncs {


...<br style="word-wrap:break-word">


/**<br style="word-wrap:break-word">

 * Switch the keyboard layout for the given device.<br style="word-wrap:break-word">

 * Direction should be &#43;1 or -1 to go to the next or previous keyboard layout.<br style="word-wrap:break-word">

 */<br style="word-wrap:break-word">

public void switchKeyboardLayout(int deviceId, int direction);<br style="word-wrap:break-word">


public void shutdown();<br style="word-wrap:break-word">

public void reboot(); <br style="word-wrap:break-word">

public void rebootSafeMode();<br style="word-wrap:break-word">

}

然后在frameworks/base/services/java/com/android/server/wm/WindowManagerService.java中实现该接口:


// Called by window manager policy. Not exposed externally.

@Override

public void shutdown() {

ShutdownThread.shutdown(mContext, true);<br style="word-wrap:break-word">

}


// Called by window manager policy. Not exposed externally.

@Override

public void reboot() {

ShutdownThread.reboot(mContext, null, true);<br style="word-wrap:break-word">

}


// Called by window manager policy. Not exposed externally.

@Override

public void rebootSafeMode() {

ShutdownThread.rebootSafeMode(mContext, true);<br style="word-wrap:break-word">

}

接下来,为了在按下重启选项之后,能出现”重启“之类的提示,还需要修改frameworks/base/services/java/com/android/server/pm/ShutdownThread.java中的shutdownInner函数和beginShutdownSequence函数:


static void shutdownInner(final Context context, boolean confirm) {

// ensure that only one thread is trying to power down.<br style="word-wrap:break-word">

// any additional calls are just returned<br style="word-wrap:break-word">

synchronized (sIsStartedGuard) {<br style="word-wrap:break-word">

    if (sIsStarted) {<br style="word-wrap:break-word">

        Log.d(TAG, &quot;Request

to shutdown already running, returning.");

        return;<br style="word-wrap:break-word">

    }<br style="word-wrap:break-word">

}<br style="word-wrap:break-word">


final int longPressBehavior = context.getResources().getInteger(<br style="word-wrap:break-word">

                com.android.internal.R.integer.config_longPressOnPowerBehavior);<br style="word-wrap:break-word">

final int resourceId = mRebootSafeMode<br style="word-wrap:break-word">

        ? com.android.internal.R.string.reboot_safemode_confirm<br style="word-wrap:break-word">

        : (longPressBehavior == 2<br style="word-wrap:break-word">

                ? com.android.internal.R.string.shutdown_confirm_question<br style="word-wrap:break-word">

                : (mReboot ? com.android.internal.R.string.reboot_confirm :<br style="word-wrap:break-word">

                    com.android.internal.R.string.shutdown_confirm));<br style="word-wrap:break-word">


Log.d(TAG, &quot;Notifying

thread to start shutdown longPressBehavior=" + longPressBehavior);


if (confirm) {<br style="word-wrap:break-word">

    final CloseDialogReceiver

closer = new CloseDialogReceiver(context);

    final AlertDialog dialog = new AlertDialog.Builder(context)<br style="word-wrap:break-word">

            .setTitle(mRebootSafeMode<br style="word-wrap:break-word">

                    ? com.android.internal.R.string.reboot_safemode_title<br style="word-wrap:break-word">

                    : (mReboot ? com.android.internal.R.string.reboot :<br style="word-wrap:break-word">

                        com.android.internal.R.string.power_off))<br style="word-wrap:break-word">

            .setMessage(resourceId)<br style="word-wrap:break-word">

            .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {<br style="word-wrap:break-word">

                public void onClick(DialogInterface dialog, int which) {<br style="word-wrap:break-word">

                    beginShutdownSequence(context);<br style="word-wrap:break-word">

                }<br style="word-wrap:break-word">

            })<br style="word-wrap:break-word">

            .setNegativeButton(com.android.internal.R.string.no, null)<br style="word-wrap:break-word">

            .create();<br style="word-wrap:break-word">

    closer.dialog = dialog;<br style="word-wrap:break-word">

    dialog.setOnDismissListener(closer);<br style="word-wrap:break-word">

    dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);<br style="word-wrap:break-word">

    dialog.show();<br style="word-wrap:break-word">

} else {<br style="word-wrap:break-word">

    beginShutdownSequence(context);<br style="word-wrap:break-word">

}<br style="word-wrap:break-word">

}


private static void beginShutdownSequence(Context context) {

synchronized (sIsStartedGuard) {

   if (sIsStarted) {<br style="word-wrap:break-word">

       Log.d(TAG, &quot;Shutdown

sequence already running, returning.");

       return;<br style="word-wrap:break-word">

   }<br style="word-wrap:break-word">

   sIsStarted = true;<br style="word-wrap:break-word">

}


// throw up an indeterminate system dialog to indicate radio is

// shutting down.

ProgressDialog pd = new ProgressDialog(context);

pd.setTitle(context.getText(com.android.internal.R.string.power_off));

pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));

pd.setIndeterminate(true);

pd.setCancelable(false);

pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);


pd.show();


sInstance.mContext = context;

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


// make sure we never fall asleep again

sInstance.mCpuWakeLock = null;

try {

   sInstance.mCpuWakeLock = sInstance.mPowerManager.newWakeLock(<br style="word-wrap:break-word">

           PowerManager.PARTIAL_WAKE_LOCK, TAG &#43; &quot;-cpu&quot;);<br style="word-wrap:break-word">

   sInstance.mCpuWakeLock.setReferenceCounted(false);<br style="word-wrap:break-word">

   sInstance.mCpuWakeLock.acquire();<br style="word-wrap:break-word">

} catch (SecurityException e) {

   Log.w(TAG, &quot;No

permission to acquire wake lock", e);

   sInstance.mCpuWakeLock = null;<br style="word-wrap:break-word">

}


// also make sure the screen stays on for better user experience

sInstance.mScreenWakeLock = null;

if (sInstance.mPowerManager.isScreenOn()) {

   try {<br style="word-wrap:break-word">

       sInstance.mScreenWakeLock = sInstance.mPowerManager.newWakeLock(<br style="word-wrap:break-word">

               PowerManager.FULL_WAKE_LOCK, TAG &#43; &quot;-screen&quot;);<br style="word-wrap:break-word">

       sInstance.mScreenWakeLock.setReferenceCounted(false);<br style="word-wrap:break-word">

       sInstance.mScreenWakeLock.acquire();<br style="word-wrap:break-word">

   } catch (SecurityException e) {<br style="word-wrap:break-word">

       Log.w(TAG, &quot;No

permission to acquire wake lock", e);

       sInstance.mScreenWakeLock = null;<br style="word-wrap:break-word">

   }<br style="word-wrap:break-word">

}


// start the thread that initiates shutdown

sInstance.mHandler = new Handler() {

};

sInstance.start();

}

至此关于代码部分的改动全部完成,接下来就需要添加使用到的资源了,就是前面用到的字符串。首先需要在frameworks/base/core/res/res/values/strings.xml中添加一下字符串:


<string name="reboot">Reboot</string>

<string name="reboot_progress">Rebootu2026</string>

<string name="reboot_confirm" product="tablet">Your
tablet will reboot.</string>

<string name="reboot_confirm" product="default">Your
phone will reboot.</string>

<!-- label for item that reboot in phone options dialog -->

<string name="global_action_reboot">Reboot</string>

而后需要在frameworks/base/core/res/res/values/public.xml中声明这些资源,否则编译的时候会出现找不到该资源的错误。


<java-symbol type="string" name="reboot" />

<java-symbol type="string" name="reboot_confirm" />

<java-symbol type="string" name="reboot_progress" />

<java-symbol type="string" name="global_action_reboot" />

至此,全部修改完成,编译烧写即可。

标签: android

热门推荐