[置顶]android源码定制之初探--定制android关机界面

 

LouisWang

转载请注明出处:http://blog.csdn.net/louiswangbing/article/details/6688240

上一篇文章中讲到android源码定制要点,说了个大概的方法和方向,现在,就来实战一下。

在Android系统中,长按Power键默认会弹出对话框让你选择“飞行模式”,“静音”,“关机”等功能。如下图所示:


但这些功能都对Android-x86和其他终端产品就没什么必要了。本文就简单介绍下如何定制关机界面。

我的目标是长按Power键,将会关机,弹出“设备将要关机”选择对话框。如果可以选择“是”关机,和“否”返回系统。 

按照android源码定制要点中提到的,首先你要对整个系统有全面的了解,找到弹出原来这个选择框的代码,它在这里:

  1. <pre name="code" class="java">frameworks\policies\base\phone\com\android\internal\policy\impl\PhoneWindowManager.java    


显示对话框调用的代码如下:

  1. Runnable mPowerLongPress = new Runnable() {    
  2.     public void run() {    
  3.         mShouldTurnOffOnKeyUp = false;    
  4.         performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);    
  5.         sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);    
  6.         showGlobalActionsDialog();    
  7.     }    
  8. };    

调用showGlobalActionsDialog方法之后将会聚到有“飞行模式”、“静音”、“关机”等选项的对话框。

找到这里,我们就知道该做什么了!干掉它,换成我们想要的关机代码,就大功告成了!既然这样,事不宜迟,让我们赶快到showGloabalActionDialog方法中看看关机的部分在哪里!

showGlobalActionsDialog的实现部分在这里:

  1. frameworks\policies\base\phone\com\android\internal\policy\impl\GlobalAction.java  

我们进去看看:

  1. public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {  
  2.     mKeyguardShowing = keyguardShowing;  
  3.     mDeviceProvisioned = isDeviceProvisioned;  
  4.     if (mDialog == null) {  
  5.         mStatusBar = (StatusBarManager)mContext.getSystemService(Context.STATUS_BAR_SERVICE);  
  6.         mDialog = createDialog();  
  7.     }  
  8.     prepareDialog();  
  9.   
  10.     mStatusBar.disable(StatusBarManager.DISABLE_EXPAND);  
  11.     mDialog.show();  
  12. }  

我们可以很清楚的看到,这里新建了一个mDialog,然后prepare接着就show了它,那么,这个mDialog就是关键了,看看它是怎么被createDialog创建出来的吧,仍然在这个文件中:

  1. /** 
  2.  * Create the global actions dialog. 
  3.  * @return A new dialog. 
  4.  */  
  5. private AlertDialog createDialog() {  
  6.     mSilentModeToggle = new ToggleAction(  
  7.             R.drawable.ic_lock_silent_mode,  
  8.             R.drawable.ic_lock_silent_mode_off,  
  9.             R.string.global_action_toggle_silent_mode,  
  10.             R.string.global_action_silent_mode_on_status,  
  11.             R.string.global_action_silent_mode_off_status) {  
  12.   
  13.         void willCreate() {  
  14.             // XXX: FIXME: switch to ic_lock_vibrate_mode when available   
  15.             mEnabledIconResId = (Settings.System.getInt(mContext.getContentResolver(),  
  16.                     Settings.System.VIBRATE_IN_SILENT, 1) == 1)  
  17.                 ? R.drawable.ic_lock_silent_mode_vibrate  
  18.                 : R.drawable.ic_lock_silent_mode;  
  19.         }  
  20.   
  21.         void onToggle(boolean on) {  
  22.             if (on) {  
  23.                 mAudioManager.setRingerMode((Settings.System.getInt(mContext.getContentResolver(),  
  24.                     Settings.System.VIBRATE_IN_SILENT, 1) == 1)  
  25.                     ? AudioManager.RINGER_MODE_VIBRATE  
  26.                     : AudioManager.RINGER_MODE_SILENT);  
  27.             } else {  
  28.                 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);  
  29.             }  
  30.         }  
  31.   
  32.         public boolean showDuringKeyguard() {  
  33.             return true;  
  34.         }  
  35.   
  36.         public boolean showBeforeProvisioning() {  
  37.             return false;  
  38.         }  
  39.     };  
  40.   
  41.     mAirplaneModeOn = new ToggleAction(  
  42.             R.drawable.ic_lock_airplane_mode,  
  43.             R.drawable.ic_lock_airplane_mode_off,  
  44.             R.string.global_actions_toggle_airplane_mode,  
  45.             R.string.global_actions_airplane_mode_on_status,  
  46.             R.string.global_actions_airplane_mode_off_status) {  
  47.   
  48.         void onToggle(boolean on) {  
  49.             if (Boolean.parseBoolean(  
  50.                     SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {  
  51.                 mIsWaitingForEcmExit = true;  
  52.                 // Launch ECM exit dialog   
  53.                 Intent ecmDialogIntent =  
  54.                         new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);  
  55.                 ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  56.                 mContext.startActivity(ecmDialogIntent);  
  57.             } else {  
  58.                 changeAirplaneModeSystemSetting(on);  
  59.             }  
  60.         }  
  61.   
  62.         @Override  
  63.         protected void changeStateFromPress(boolean buttonOn) {  
  64.             // In ECM mode airplane state cannot be changed   
  65.             if (!(Boolean.parseBoolean(  
  66.                     SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {  
  67.                 mState = buttonOn ? State.TurningOn : State.TurningOff;  
  68.                 mAirplaneState = mState;  
  69.             }  
  70.         }  
  71.   
  72.         public boolean showDuringKeyguard() {  
  73.             return true;  
  74.         }  
  75.   
  76.         public boolean showBeforeProvisioning() {  
  77.             return false;  
  78.         }  
  79.     };  
  80.   
  81.     <span style="color:#ff0000;">mItems = Lists.newArrayList(  
  82.             // silent mode   
  83.             mSilentModeToggle,  
  84.             // next: airplane mode   
  85.             mAirplaneModeOn,  
  86.             // last: power off   
  87.             new SinglePressAction(  
  88.                     com.android.internal.R.drawable.ic_lock_power_off,  
  89.                     R.string.global_action_power_off) {  
  90.   
  91.                 </span><span style="color:#3333ff;"><u>public void onPress() {  
  92.                     // shutdown by making sure radio and power are handled accordingly.   
  93.                     ShutdownThread.shutdown(mContext, true);  
  94.                 }</u></span><span style="color:#ff0000;">  
  95.   
  96.                 public boolean showDuringKeyguard() {  
  97.                     return true;  
  98.                 }  
  99.   
  100.                 public boolean showBeforeProvisioning() {  
  101.                     return true;  
  102.                 }</span>  
  103.             });  
  104.   
  105.     mAdapter = new MyAdapter();  
  106.   
  107.     final AlertDialog.Builder ab = new AlertDialog.Builder(mContext);  
  108.   
  109.     ab.setAdapter(mAdapter, this)  
  110.             .setInverseBackgroundForced(true)  
  111.             .setTitle(R.string.global_actions);  
  112.   
  113.     final AlertDialog dialog = ab.create();  
  114.     dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);  
  115.     if (!mContext.getResources().getBoolean(  
  116.             com.android.internal.R.bool.config_sf_slowBlur)) {  
  117.         dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,  
  118.                 WindowManager.LayoutParams.FLAG_BLUR_BEHIND);  
  119.     }  
  120.   
  121.     dialog.setOnDismissListener(this);  
  122.   
  123.     return dialog;  
  124. }  

看看我们发现了什么!!蓝色的部分就是关机调用的函数了!!shutdown方法的第二个参数标识是否弹出询问对话框。你可以选择需要(true)或者不需要(false)。这里我保守一点,还是选个true吧,万一不小心按到关机键呢,呵呵。。。

也就是说,只要我们用

  1. <span style="color:#3333ff;">ShutdownThread.shutdown(mContext, true);</span>  

替换掉前面的

  1. showGlobalActionsDialog();    

就可以大功告成了!还等什么!我们修改

  1. frameworks\policies\base\phone\com\android\internal\policy\impl\PhoneWindowManager.java    

的源代码如下:

  1. Runnable mPowerLongPress = new Runnable() {  
  2.     public void run() {  
  3.         mShouldTurnOffOnKeyUp = false;  
  4.         performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);  
  5.         sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);  
  6.         //showGlobalActionsDialog();   
  7.         ShutdownThread.shutdown(mContext, true);   
  8.     }  
  9. };  

好了,大功告成了!!

是不是就这样完了呢?发现编译不过。。。

细节很重要!!

原来ShutdownThread.shutdown(mContext, true)的引用包没加进来!!幸好有gcc。。。

  1. import com.android.internal.app.ShutdownThread;  

将上面这个包加到
  1. frameworks\policies\base\phone\com\android\internal\policy\impl\PhoneWindowManager.java    

中,再次编译,通过,YES!

看看我们的战果吧:


是不是感觉到源码定制的快感和成就感了呢?

这仅仅只是个开始,好戏还在后头呢!!哈哈


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章