对于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. public void onPress() {
  6. // reboot
  7. mWindowManagerFuncs.reboot();
  8. }
  9. public boolean showDuringKeyguard() {
  10. return true;
  11. }
  12. public boolean showBeforeProvisioning() {
  13. return true;
  14. }
  15. });

上面的代码中使用了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">Reboot\u2026</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" />

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

Android 4.1.2系统添加重启功能的更多相关文章

  1. android4.2添加重启菜单项

    本文主要是针对android4.2关机菜单添加重启功能 A.关机提示 android4.2/frameworks/base/policy/src/com/android/internal/policy ...

  2. Android系统移植与调试之------->如何修改Android设备添加重启、飞行模式、静音模式等功能(二)

    今天要说的是为Android设备添加重启.飞行模式.静音模式按钮,客户需求中需要添加这项功能,在长按电源键弹出的菜单中没有这些选项,谨以此文记录自己添加这个功能的过程. 首先找到长按电源键弹出的对话框 ...

  3. Android调用系统关机与重启功能

    我是在android源码里编译的package/apps/,因为需要调用的关机接口是不对上层开放的,在eclipse里面不能调用. 我主要是介绍调用android的关机功能,因为在调试过程中,关机的一 ...

  4. 探索Android调用系统的分享功能

    非常多的应用为了应用的推广和传播都会使用"分享"的功能,点击分享button.就能将想要分享的内容或者图片分享至QQ空间.微博.微信朋友圈等实现了分享功能的应用.这篇文章主要是为了 ...

  5. 【转】Android Service被关闭后自动重启,解决被异常kill 服务

    http://www.kaifajie.cn/android/10182-2.html 每次调用startService(Intent)的时候,都会调用该Service对象的onStartComman ...

  6. Android6.0 源码修改之屏蔽系统短信功能和来电功能

    一.屏蔽系统短信功能 1.屏蔽所有短信 android 4.2 短信发送流程分析可参考这篇 戳这 源码位置 vendor\mediatek\proprietary\packages\apps\Mms\ ...

  7. 如何在本地搭建一个Android应用crashing跟踪系统-ACRA

    https://github.com/bboyfeiyu/android-tech-frontier/tree/master/others/%E5%A6%82%E4%BD%95%E5%9C%A8%E6 ...

  8. 嵌入式系统添加无线wifi模块

    开发环境:fl2440开发板,linux3.0内核,交叉编译器路径/opt/buildroot-2011.11/arm920t/usr/bin/arm-linux-,无线网卡RT3070 平时开发板联 ...

  9. Android端IM应用中的@人功能实现:仿微博、QQ、微信,零入侵、高可扩展

    本文由“猫爸iYao”原创分享,感谢作者. 1.引言 最近有个需求:评论@人(没错,就是IM聊天或者微博APP里的@人功能),就像下图这样:   ▲ 微信群聊界面里的@人功能    ▲ QQ群聊界面里 ...

随机推荐

  1. Spark技术内幕:Sort Based Shuffle实现解析

    在Spark 1.2.0中,Spark Core的一个重要的升级就是将默认的Hash Based Shuffle换成了Sort Based Shuffle,即spark.shuffle.manager ...

  2. FFmpeg的H.264解码器源代码简单分析:熵解码(Entropy Decoding)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  3. shell 参数列表的获取&shell使用的一些总结

    最近在修改公司的一些cron,自己也是第一次接触和学习shell.对于一些零散但是常用的知识点,做一点点的总结. 拿出一个方法说说吧,方法如下:(信息量挺大的,请耐心看下面的说明) trans_cou ...

  4. 仿淘宝购物车demo---增加和减少商品数量

    在上一篇博客中,小编简单的介绍了如何使用listview来实现购物车,但是仅仅是简单的实现了列表的功能,随之而来一个新的问题,买商品的时候,我们可能不止想买一件商品,想买多个,或许有因为某种原因点错了 ...

  5. android布局##TableLayout和FrameLayout-android学习之旅(十五)

    TableLayout 表格布局 tablelayout简介 表格布局有TableLayout代表,但是它的本质定义仍然是线性管理器.表格布局采用行和列来管理UI,但是不需要明确的定义多少行,多少列, ...

  6. 剑指Offer——全排列递归思路

    剑指Offer--全排列递归思路 前言 全排列,full permutation, 可以利用二叉树的遍历实现.二叉树的递归遍历,前中后都简洁的难以置信,但是都有一个共同特点,那就是一个函数里包含两次自 ...

  7. UNIX网络编程——客户/服务器程序设计示范(总结)

    (1)当系统负载较轻是,每来一个客户请求现场派生一个子进程为之服务的传统并发服务器程序模型就足够了.这个模型甚至可以与inetd结合使用,也就是inetd处理每个连接的接收.我们的其他意见是就重负荷运 ...

  8. Mat, IplImage, CvMat, Cvarr关系及元素获取

    自己目前正打算整理opencv数据结构之间关系,寻寻觅觅之间,发现这篇博文很全面,总结得很好,故转之.红色部分不对,自己已修改! 原文地址:http://blog.csdn.net/abcjennif ...

  9. Android进阶(七)数据存储

    Android 数据存储 1访问资源文件 直接将文件保存在设备的内部存储. 默认情况下,保存到内部存储的文件为私有的,其他应用程序不能访问它们,当用户卸载应用程序时,所保存的文件也一并删除.  1.1 ...

  10. Android官方命令深入分析之dmtracedump

    dmtracedump是一个根据log文件生成图形化调用堆栈的工具(除了Traceview之外). dmtracedump的用法: dmtracedump [-ho] [-s sortable] [- ...