当前位置: 代码迷 >> Android >> 替android增加重启菜单
  详细解决方案

替android增加重启菜单

热度:109   发布时间:2016-05-01 11:10:52.0
为android增加重启菜单
转自:http://blog.csdn.net/zzp16/article/details/7829063
?
一、Android系统重启的实现方式
1、广播方式
之前的博文介绍过这种方式《使用广播实现的Android关机及重启》,注意应用要在源码中编译,并且应用需要系统权限。
?
2、通过init.rc启动系统服务来运行sh文件
a.重启shell文件(system_reboot.sh),放在system/etc/目录下
[java]?view plaincopy
  1. #!/system/bin/sh????
  2. reboot??
b.init.rc中加入一个Service的定义
[java] view plaincopy
  1. service?system_reboot?/system/etc/system_reboot.sh??
  2. ??oneshot??
  3. ??disabled??
c.启动系统服务
[java] view plaincopy
  1. SystemProperties.set("ctl.start",?"system_reboot");??


3、直接代码中执行命令行
需要取得root权限
[java]?view plaincopy
  1. Process?proc?=?Runtime.getRuntime().exec(cmd);??

? ? 以上三种方法可以实现重启,但现在需要实现长按关机键提示对话框中有重启选项,这就设计修改系统源码,感觉修改源码,是个很难的工作,其实找到关机提示框的代码位置,一切都变得很简单。
?
二、修改源码定制重启功能
1、跟踪长按Power键相关代码
? ? 首先要了解长按电源键弹出对话框的相关源码位置,通过跟踪找到PhoneWindowManager.java中有截断长按电源键的方法,继续跟踪代码找到Runnable?mPowerLongPress?= new Runnable(),在该runnable里边调用showGlobalActionsDialog()方法便是显示长按power键弹出的关机提示对话框,如果你的机器是原生态的,默认提示“飞行模式”,“静音”和“关机”选项。
? ? ?showGlobalActionsDialog创建关机对话框的代码在GlobalActions.java里边,主要代码如下:
?
[java]?view plaincopy
  1. private?AlertDialog?createDialog()?{??
  2. ……??
  3. mItems?=?new?ArrayList<Action>();??
  4. ??
  5. ????????//?first:?power?off??
  6. ????????mItems.add(??
  7. ????????????new?SinglePressAction(??
  8. ????????????????????com.android.internal.R.drawable.ic_lock_power_off,??
  9. ????????????????????R.string.global_action_power_off)?{??
  10. ??
  11. ????????????????public?void?onPress()?{??
  12. ????????????????????//?shutdown?by?making?sure?radio?and?power?are?handled?accordingly.??
  13. ????????????????????ShutdownThread.shutdown(mContext,?true);??
  14. ????????????????}??
  15. ??
  16. ????????????????public?boolean?showDuringKeyguard()?{??
  17. ????????????????????return?true;??
  18. ????????????????}??
  19. ??
  20. ????????????????public?boolean?showBeforeProvisioning()?{??
  21. ????????????????????return?true;??
  22. ????????????????}??
  23. ????????????});??
  24. ??
  25. ????????//?next:?airplane?mode??
  26. ????????mItems.add(mAirplaneModeOn);??
  27. ??
  28. ????????//?last:?silent?mode??
  29. ????????if?(SHOW_SILENT_TOGGLE)?{??
  30. ????????????mItems.add(mSilentModeAction);??
  31. ????????}??
  32. ……??
  33. }??
?
2、重启方法
? ? 跟踪源码到此处,需要加入重启部分的源码也是往AlertDialog?添加多一项,显示部分的代码直接造这power off即可,需要加入重启逻辑的代码直接修改回调方法onPress里边(上边代码粗体部分),一开始,我尝试了前文中提示的三种方法中的方法一和方法三均行不通,后来也没再进一步排查原因,估计权限问题。
? ? 本打算使用方法二再尝试一下,突然想到为何不去看看关机的逻辑代码ShutdownThread.shutdown(),打开ShutdownThread.java,很快就发现源码里边也有reboot的实现方法,如下:
? ??
[java]?view plaincopy
  1. /**?
  2. ?????*?Request?a?clean?shutdown,?waiting?for?subsystems?to?clean?up?their?
  3. ?????*?state?etc.??Must?be?called?from?a?Looper?thread?in?which?its?UI?
  4. ?????*?is?shown.?
  5. ?????*?
  6. [email protected]utdown?progress?dialog.?
  7. [email protected](e.g.?"recovery"),?or?null.?
  8. [email protected]eeded?before?shutting?down.?
  9. ?????*/??
  10. ????public?static?void?reboot(final?Context?context,?String?reason,?boolean?confirm){??
  11. ?????……??
  12. ?????}??
? ?该方法的使用直接看注释知道,reboot方法的后两个参数解释如下:
?????reason ?如果值为是null,正常重启;如果是recovery,系统重启进入recovery mode
?????confirm true显示关机提示框,需要用户【确认】;false不显示提示框,直接关机
?
3、代码修改
a.在关机提示框中加入重启选项
? ? 弄清楚关机相关的源码,直接在GlobalActions.java的createDialog方法中加入如下代码即可:
?
[java]?view plaincopy
  1. ...??
  2. ext:?reboot?global_action_reboot??
  3. ??mItems.add(??
  4. ???new?SinglePressAction(??
  5. ??????????????com.android.internal.R.drawable.ic_lock_power_off,??
  6. ??????????????R.string.global_action_reboot)?{??
  7. ??
  8. ??????????public?void?onPress()?{??
  9. ????????//?reboot??
  10. ???????????ShutdownThread.reboot(mContext,null,false);????????????????
  11. ??????????}??
  12. ??
  13. ??????????public?boolean?showDuringKeyguard()?{??
  14. ??????????????return?true;??
  15. ??????????}??
  16. ??
  17. ??????????public?boolean?showBeforeProvisioning()?{??
  18. ??????????????return?true;??
  19. ??????????}??
  20. ??????});??
b.修改重启提示框,以区分关机提示框
? 因为提示框默认是“关机”,在ShutdownThread.java的beginShutdownSequence(context)方法中代码修改如下:
[java]?view plaincopy
  1. /*/?
  2. //修改前:?
  3. ……?
  4. ?pd.setTitle(context.getText(com.android.internal.R.string.power_off));?
  5. ?pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));?
  6. ……?
  7. /*/??
  8. //修改后:??
  9. ……??
  10. if(mReboot){?????//?reboot?progress??
  11. ?????????pd.setTitle(context.getText(com.android.internal.R.string.global_action_reboot));??
  12. ?????????pd.setMessage(context.getText(com.android.internal.R.string.reboot_progress));??
  13. ?????}else{??????????//?shutdown?progress??
  14. ?????????pd.setTitle(context.getText(com.android.internal.R.string.power_off));??
  15. ?????????pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));??
  16. ?????}??
  17. ……??
  18. //*/??




? ? ?重启功能实现了,但是不能到此结束,定制Android系统的重启功能,添加选项和修改重启提示框时加入了“重启”和“正在重启”的字符串,所以会涉及到在系统资源文件中添加新的字符串,源码中资源文件涉及到的多国语言直接忽略,我只在values/strings.xml和values-zh-rCN/strings.xml两个文件中加入对应的字符串
[html]?view plaincopy
  1. <string?name="global_action_reboot">重启</string>??
  2. <string?name="reboot_progress">"正在重启..."</string>??


c.最后编译
因为修改涉及到系统资源文件又涉及到policy.jar包,经过多次尝试,正确的编译顺序如下:
步骤1.编译frameworks/base/res,在out/target/product/X设备名X/system/framework/目录下生成framework-res.apk
步骤2.编译frameworks/base/,在o同样目录下生成framework.jar包(不能忽略,不然步骤3编译报错)
步骤3.编译frameworks/base/policy,在同样目录下生成policy.jar包
?
?
附录:
本例源码以Android 4.0.4为准(2.3一样),关机相关的源码路径:
ics/frameworks/base/policy/src/com/android/internal/policy/impl/目录下:
PhoneWindowManager.java
GlobalActions.java
?
ics/frameworks/base/core/java/com/android/internal/app/目录下:
ShutdownThread.java
?
?
PS:4.1.1 关机相关方法位置有些变化
源码已经把关机的接口整合到:
public class?WindowManagerService?extends IWindowManager.Stub
? ? ? ? implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs{...}中
不过可以直接使用:
import com.android.server.pm.ShutdownThread;
?
ShutdownThread.shutdown(mContext, true);
ShutdownThread.rebootSafeMode(mContext, true);
?
文件路径:
Android4.1.1/jb/frameworks/base/services/java/com/android/server/pm/
ShutdownThread.java
?
Android4.1.1/jb/frameworks/base/services/java/com/android/server/wm
WindowManagerService.java
?
...
  相关解决方案