您的位置:首页 > 移动开发 > Android开发

Android 4.1.2系统添加重启功能

2015-07-01 13:33 525 查看
转自: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

if (!mHasVibrator) {

mSilentModeAction = new SilentModeToggleAction();

} else {

mSilentModeAction = new SilentModeTriStateAction(mContext, mAudioManager, mHandler);

}

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 (mHasTelephony && 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) {

if (!mHasTelephony) return;

// 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;

}

};

onAirplaneModeChanged();

mItems = new ArrayList<Action>();

// first: power off

mItems.add(

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.

mWindowManagerFuncs.shutdown(true);

}

public boolean onLongPress() {

mWindowManagerFuncs.rebootSafeMode(true);

return true;

}

public boolean showDuringKeyguard() {

return true;

}

public boolean showBeforeProvisioning() {

return true;

}

});

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

mItems.add(

new SinglePressAction(

com.android.internal.R.drawable.ic_lock_power_off,

R.string.global_action_reboot) {

public void onPress() {

// reboot

mWindowManagerFuncs.reboot();

}

public boolean showDuringKeyguard() {

return true;

}

public boolean showBeforeProvisioning() {

return true;

}

});

上面的代码中使用了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 {

...

/**

* Switch the keyboard layout for the given device.

* Direction should be +1 or -1 to go to the next or previous keyboard layout.

*/

public void switchKeyboardLayout(int deviceId, int direction);

public void shutdown();

public void reboot();

public void rebootSafeMode();

}

然后在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);

}

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

@Override

public void reboot() {

ShutdownThread.reboot(mContext, null, true);

}

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

@Override

public void rebootSafeMode() {

ShutdownThread.rebootSafeMode(mContext, true);

}

接下来,为了在按下重启选项之后,能出现”重启“之类的提示,还需要修改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.

// any additional calls are just returned

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

: (mReboot ? com.android.internal.R.string.reboot_confirm :

com.android.internal.R.string.shutdown_confirm));

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

if (confirm) {

final CloseDialogReceiver
closer = new CloseDialogReceiver(context);

final AlertDialog dialog = new AlertDialog.Builder(context)

.setTitle(mRebootSafeMode

? com.android.internal.R.string.reboot_safemode_title

: (mReboot ? com.android.internal.R.string.reboot :

com.android.internal.R.string.power_off))

.setMessage(resourceId)

.setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int which) {

beginShutdownSequence(context);

}

})

.setNegativeButton(com.android.internal.R.string.no, null)

.create();

closer.dialog = dialog;

dialog.setOnDismissListener(closer);

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

dialog.show();

} else {

beginShutdownSequence(context);

}

}

private static void beginShutdownSequence(Context context) {

synchronized (sIsStartedGuard) {

if (sIsStarted) {

Log.d(TAG, "Shutdown
sequence already running, returning.");

return;

}

sIsStarted = true;

}

// 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(

PowerManager.PARTIAL_WAKE_LOCK, TAG + "-cpu");

sInstance.mCpuWakeLock.setReferenceCounted(false);

sInstance.mCpuWakeLock.acquire();

} catch (SecurityException e) {

Log.w(TAG, "No
permission to acquire wake lock", e);

sInstance.mCpuWakeLock = null;

}

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

sInstance.mScreenWakeLock = null;

if (sInstance.mPowerManager.isScreenOn()) {

try {

sInstance.mScreenWakeLock = sInstance.mPowerManager.newWakeLock(

PowerManager.FULL_WAKE_LOCK, TAG + "-screen");

sInstance.mScreenWakeLock.setReferenceCounted(false);

sInstance.mScreenWakeLock.acquire();

} catch (SecurityException e) {

Log.w(TAG, "No
permission to acquire wake lock", e);

sInstance.mScreenWakeLock = null;

}

}

// 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">Reboot\u2026</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" />

至此,全部修改完成,编译烧写即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: