Android 2.3.7 锁屏中添加指纹识别锁屏总结

 

最近在2.3.7版本上添加一种新的锁屏方式,指纹识别。搞了两个多星期,总算搞定了,下面总结一下:

首先最让人头疼的就是android原生的锁屏框架--Keyguard  虽然到现在也没完全摸清楚这个框架,不过还是要简单记录一下,方便日后参考。

源文件路径主要有两个:

             frameworks\base\policy\src\com\android\internal\policy\impl\   ---->锁屏框架

             frameworks\base\core\java\com\android\internal\widget\          ----> 提供了一些的自定义View

锁屏界面有两种组成,一种是滑屏的 如下图

另外一种是需要图案、密码或者PIN来解锁

\frameworks\base\policy\src\com\android\internal\policy\impl\目录下

第一种界面是LockScreen.java类

第二种界面是UnLockScreen.java类 分为以下三种:

图案解锁----PatternUnlockScreen.java类

PIN开锁界面 ---- SimUnlockScreen.java 类

密码开锁界面 ---- PasswordUnlockScreen.java类

自定义LinearLayout 在frameworks\policies\base\core\res\res\layout下

当锁屏时候,首先显示LockScreen界面,接着判断是否开启了UnLockScreen界面,如果设置了UnLockScreen界面,则进入对应的

    UnLockScreen界面去解锁,才算成功解锁。但,存在一种特殊的情况,就是假如我们选择了图案  UnLockScreen界面,是不会

    显示LockScreen界面,而只会显示UnLockScreen界面。

我们知道, 任何一种界面都是由各种View/ViewGroup(当然包括自定义的)组成的,然后根据系统对应的状态值的改变去更新

  这些View的显示状态,锁屏界面自然也是如此。锁屏界面的实现最顶层是采用了FrameLayout去控制的,当然内部也嵌套了很

  多层,内嵌层数的增多的一点好处就是我们可以分开而治,具体针对每层去做相应的更新。难处就是看代码看的很头疼。

 

锁屏机制的类结构说明:

1、 LockPatternKeyguardView 继承至FrameLayout :作为LockScreen和UnLockScreen的载体,用来控制显示LockScreen还是UnLockScreen界面。

 1、 KeyguardScreen 类    接口    


       功能:该接口的主要功能是为每个需要显示的界面:LockScreen或者UnLockScreen定义了四个方法,使其在不同的状态能够

          得到相应处理。优点就是:   利用设计原则的面向接口编程,减少对具体对象的依赖。

      路径:\frameworks\base\policy\src\com\android\internal\policy\impl\KeyguardScreen.java

     其源代码释义如下:

  1. /** 
  2.  * Common interface of each {@link android.view.View} that is a screen of 
  3.  * {@link LockPatternKeyguardView}. 
  4.  */   
  5. public interface KeyguardScreen {  
  6.     /** Return true if your view needs input, so should allow the soft 
  7.      * keyboard to be displayed. */  
  8.     boolean needsInput(); //View是否需要输入数值,即该界面需要键盘输入数值    
  9.     /** This screen is no longer in front of the user.*/  
  10.     void onPause();//当该界面不处于前台界面时调用,包括处于GONE或者该界面即将被remove掉   
  11.     /** This screen is going to be in front of the user. */  
  12.     void onResume();//相对于onPause()方法,当该界面不处于前台界面时调用,处于VISIBLE状态时调用   
  13.     /** This view is going away; a hook to do cleanup. */  
  14.     void cleanUp();//该界面即将被remove掉 ,即不在需要   
  15. }  
/**
 * Common interface of each {@link android.view.View} that is a screen of
 * {@link LockPatternKeyguardView}.
 */ 
public interface KeyguardScreen {
    /** Return true if your view needs input, so should allow the soft
     * keyboard to be displayed. */
    boolean needsInput(); //View是否需要输入数值,即该界面需要键盘输入数值 
    /** This screen is no longer in front of the user.*/
    void onPause();//当该界面不处于前台界面时调用,包括处于GONE或者该界面即将被remove掉
    /** This screen is going to be in front of the user. */
    void onResume();//相对于onPause()方法,当该界面不处于前台界面时调用,处于VISIBLE状态时调用
    /** This view is going away; a hook to do cleanup. */
    void cleanUp();//该界面即将被remove掉 ,即不在需要
}


   2、KeyguardScreenCallback类  接口


      功能:每个需要显示的界面:LockScreen或者UnLockScreen都保存了该对象的唯一实例,用来向控制界面汇报情况。

      路径:frameworks\base\policy\src\com\android\internal\policy\impl\KeyguardScreenCallback.java

       其源代码释义如下:

  1. /** Within a keyguard, there may be several screens that need a callback 
  2.  * to the host keyguard view. 
  3.  */   
  4. public interface KeyguardScreenCallback extends KeyguardViewCallback {  
  5.     /** Transition to the lock screen*/  
  6.     void goToLockScreen();  //当前界面跳转为LockScreen ,而不是UnLockScreen   
  7.     /** Transition to the unlock screen.*/  
  8.     void goToUnlockScreen();//LockScreen成功开锁 ,是否需要显示UnLockScreen,否则,直接开锁成功。   
  9.     //忘记了开锁图案,即我们需要跳转到Google 账户去开锁。   
  10.     void forgotPattern(boolean isForgotten);  
  11.     boolean isSecure();//当前机器是否安全,例如:设置了图案、密码开锁等      
  12.     //该函数还不太懂,可能是是否只需要验证UnlockScreen界面,即可成功开锁。   
  13.     boolean isVerifyUnlockOnly();  
  14.     /**Stay on me, but recreate me (so I can use a different layout).*/  
  15.     void recreateMe(Configuration config); //重新根据手机当前状态,显示对应的Screen.   
  16.     /** Take action to send an emergency call. */  
  17.     void takeEmergencyCallAction();  //紧急呼叫时的处理行为.   
  18.   
  19.     /** Report that the user had a failed attempt to unlock with password or pattern.*/  
  20.     void reportFailedUnlockAttempt(); //在UnLockScreen界面登陆失败时处理   
  21.   
  22.     /** Report that the user successfully entered their password or pattern.*/  
  23.     void reportSuccessfulUnlockAttempt();//在UnLockScreen界面登陆成功时处理   
  24.   
  25.     /** Report whether we there's another way to unlock the device. 
  26.      * @return true */  
  27.     boolean doesFallbackUnlockScreenExist();  
  28. }  
/** Within a keyguard, there may be several screens that need a callback
 * to the host keyguard view.
 */ 
public interface KeyguardScreenCallback extends KeyguardViewCallback {
    /** Transition to the lock screen*/
    void goToLockScreen();  //当前界面跳转为LockScreen ,而不是UnLockScreen
    /** Transition to the unlock screen.*/
    void goToUnlockScreen();//LockScreen成功开锁 ,是否需要显示UnLockScreen,否则,直接开锁成功。
    //忘记了开锁图案,即我们需要跳转到Google 账户去开锁。
    void forgotPattern(boolean isForgotten);
    boolean isSecure();//当前机器是否安全,例如:设置了图案、密码开锁等   
    //该函数还不太懂,可能是是否只需要验证UnlockScreen界面,即可成功开锁。
    boolean isVerifyUnlockOnly();
    /**Stay on me, but recreate me (so I can use a different layout).*/
    void recreateMe(Configuration config); //重新根据手机当前状态,显示对应的Screen.
    /** Take action to send an emergency call. */
    void takeEmergencyCallAction();  //紧急呼叫时的处理行为.

    /** Report that the user had a failed attempt to unlock with password or pattern.*/
    void reportFailedUnlockAttempt(); //在UnLockScreen界面登陆失败时处理

    /** Report that the user successfully entered their password or pattern.*/
    void reportSuccessfulUnlockAttempt();//在UnLockScreen界面登陆成功时处理

    /** Report whether we there's another way to unlock the device.
     * @return true */
    boolean doesFallbackUnlockScreenExist();
}


      其唯一实现类位于LockPatternKeyguardView类的内部类(稍后讲到)。


   3、KeyguardViewCallback类  接口


         功能: 提供了一些接口用来接受用户操作Screen的结果。

         路径:frameworks\base\policy\src\com\android\internal\policy\impl\KeyguardViewCallback.java

         其源代码释义如下:

  1. /** 
  2.   * The callback used by the keyguard view to tell the {@link KeyguardViewMediator}  
  3.   * various things. 
  4.   */  
  5.  public interface KeyguardViewCallback {  
  6.   
  7.      /** Request the wakelock to be poked for the default amount of time. */  
  8.      void pokeWakelock();  //保存屏幕在一定时间内处于亮屏状况 , 默认时间为5s或者10s   
  9.      /** Request the wakelock to be poked for a specific amount of time.  */  
  10.      void pokeWakelock(int millis);//根据给定时间值,使屏幕在该事件段内保持亮屏状况   
  11.   
  12.      /** Report that the keyguard is done. 
  13.       * @param authenticated Whether the user securely got past the keyguard. 
  14.       *   the only reason for this to be false is if the keyguard was instructed 
  15.       *   to appear temporarily to verify the user is supposed to get past the 
  16.       *   keyguard, and the user fails to do so. */  
  17.      //成功的完成开锁,可以进入手机界面了。参数为ture表示是否正大光明的开锁,例如:图案正确,密码输入正确。   
  18.      void keyguardDone(boolean authenticated);   
  19.      /**Report that the keyguard is done drawing. */  
  20.      void keyguardDoneDrawing(); //整个锁屏界面draw()过程绘制完成时,回调该方法.   
  21.  }  
/**
  * The callback used by the keyguard view to tell the {@link KeyguardViewMediator} 
  * various things.
  */
 public interface KeyguardViewCallback {

     /** Request the wakelock to be poked for the default amount of time. */
     void pokeWakelock();  //保存屏幕在一定时间内处于亮屏状况 , 默认时间为5s或者10s
     /** Request the wakelock to be poked for a specific amount of time.  */
     void pokeWakelock(int millis);//根据给定时间值,使屏幕在该事件段内保持亮屏状况

     /** Report that the keyguard is done.
      * @param authenticated Whether the user securely got past the keyguard.
      *   the only reason for this to be false is if the keyguard was instructed
      *   to appear temporarily to verify the user is supposed to get past the
      *   keyguard, and the user fails to do so. */
     //成功的完成开锁,可以进入手机界面了。参数为ture表示是否正大光明的开锁,例如:图案正确,密码输入正确。
     void keyguardDone(boolean authenticated); 
     /**Report that the keyguard is done drawing. */
     void keyguardDoneDrawing(); //整个锁屏界面draw()过程绘制完成时,回调该方法.
 }


                      其唯一实现类是   KeyguardViewMediator类(稍后讲到)


    4、 KeyguardWindowController类 接口


         功能:提供通用 接口,判断该界面是否需要显示输入法窗口。

         其源代码释义如下:

  1. /** 
  2.  * Interface passed to the keyguard view, for it to call up to control 
  3.  * its containing window. 
  4.  */  
  5. public interface KeyguardWindowController {  
  6.     /** Control whether the window needs input -- that is if it has 
  7.      * text fields and thus should allow input method interaction. */  
  8.     void setNeedsInput(boolean needsInput);  //是否需要显示输入法,为true表示需要。该方法可以想上层报到是否需要显示输入法窗口   
  9. }  
/**
 * Interface passed to the keyguard view, for it to call up to control
 * its containing window.
 */
public interface KeyguardWindowController {
    /** Control whether the window needs input -- that is if it has
     * text fields and thus should allow input method interaction. */
    void setNeedsInput(boolean needsInput);  //是否需要显示输入法,为true表示需要。该方法可以想上层报到是否需要显示输入法窗口
}

         其唯一实现类是KeyguardViewManager类(稍后讲到)。

       

    5、KeyguardViewManager类 


        功能:包装了WindowManager功能了,提供了添加、删除锁屏界面的功能。

          其源代码释义如下:     

  1.  public class KeyguardViewManager implements KeyguardWindowController {  
  2.      ...  
  3.      private WindowManager.LayoutParams mWindowLayoutParams;  
  4.      private boolean mNeedsInput = false//是否需要输入法 , 默认不需要   
  5.   
  6.      private FrameLayout mKeyguardHost;   //该ViewGroup作为顶层View,作为WindowManager添加至窗口   
  7.      private KeyguardViewBase mKeyguardView; //具体窗口内容。   
  8.      //以上两种的关系相当于DecorView和我们Activity内设置的资源文件一样   
  9.   
  10.      private boolean mScreenOn = false//是否处于亮屏状态   
  11.      //构造函数,初始化各种属性   
  12.      public KeyguardViewManager(Context context, ViewManager viewManager,  
  13.              KeyguardViewCallback callback, KeyguardViewProperties keyguardViewProperties, KeyguardUpdateMonitor updateMonitor) {  
  14.         ...  
  15.      }  
  16.      /** 
  17.       * Helper class to host the keyguard view. 
  18.       */  
  19.      private static class KeyguardViewHost extends FrameLayout {  
  20.          ... //KeyguardViewHost类   
  21.      }  
  22.   
  23.      /** 
  24.       * Show the keyguard.  Will handle creating and attaching to the view manager 
  25.       * lazily. 
  26.       */  //显示锁屏界面   
  27.      public synchronized void show() {         
  28.          if (mKeyguardHost == null) {  
  29.              ...  
  30.              mViewManager.addView(mKeyguardHost, lp);  
  31.          }  
  32.          if (mKeyguardView == null) {  
  33.              ...  
  34.              mKeyguardHost.addView(mKeyguardView, lp);  
  35.              if (mScreenOn) {  
  36.                  mKeyguardView.onScreenTurnedOn();  
  37.              }  
  38.          }  
  39.         ...  
  40.      }  
  41.      ...  
  42.   
  43.      /*** Hides the keyguard view */  
  44.      public synchronized void hide() { //隐藏锁屏界面,也就是说我们成功的解锁了   
  45.          if (mKeyguardHost != null) {  
  46.              mKeyguardHost.setVisibility(View.GONE);  
  47.                  ...  
  48.              }  
  49.      }  
  50.      //锁屏界面是否处于显示状态   
  51.      public synchronized boolean isShowing() {  
  52.          return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE);  
  53.      }  
  54.  }  
  55.   
  56.   
  57. }  
  58.         
 public class KeyguardViewManager implements KeyguardWindowController {
	 ...
     private WindowManager.LayoutParams mWindowLayoutParams;
     private boolean mNeedsInput = false; //是否需要输入法 , 默认不需要

     private FrameLayout mKeyguardHost;   //该ViewGroup作为顶层View,作为WindowManager添加至窗口
     private KeyguardViewBase mKeyguardView; //具体窗口内容。
     //以上两种的关系相当于DecorView和我们Activity内设置的资源文件一样

     private boolean mScreenOn = false; //是否处于亮屏状态
     //构造函数,初始化各种属性
     public KeyguardViewManager(Context context, ViewManager viewManager,
             KeyguardViewCallback callback, KeyguardViewProperties keyguardViewProperties, KeyguardUpdateMonitor updateMonitor) {
        ...
     }
     /**
      * Helper class to host the keyguard view.
      */
     private static class KeyguardViewHost extends FrameLayout {
         ... //KeyguardViewHost类
     }

     /**
      * Show the keyguard.  Will handle creating and attaching to the view manager
      * lazily.
      */  //显示锁屏界面
     public synchronized void show() {       
         if (mKeyguardHost == null) {
             ...
             mViewManager.addView(mKeyguardHost, lp);
         }
         if (mKeyguardView == null) {
             ...
             mKeyguardHost.addView(mKeyguardView, lp);
             if (mScreenOn) {
                 mKeyguardView.onScreenTurnedOn();
             }
         }
        ...
     }
     ...

     /*** Hides the keyguard view */
     public synchronized void hide() { //隐藏锁屏界面,也就是说我们成功的解锁了
         if (mKeyguardHost != null) {
             mKeyguardHost.setVisibility(View.GONE);
                 ...
             }
     }
     //锁屏界面是否处于显示状态
     public synchronized boolean isShowing() {
         return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE);
     }
 }


}
      


 

   6、 KeyguardUpdateMonitor.java类 


       功能:该类的主要功能就是根据监视系统状态值的改变(例如:时间、SIM卡状态、电池电量;使用广播监听),根据这种状态

           值的改变回调监听了该状态信息的对象实例。

       其源代码释义如下:     

  1. public class KeyguardUpdateMonitor {  
  2.     ...  
  3.     private int mFailedAttempts = 0;  //当前登录事,已经失败的次数   
  4.     private ArrayList<InfoCallback> mInfoCallbacks; //保存所有监听对象 InfoCallback   
  5.     private ArrayList<SimStateCallback> mSimStateCallbacks ; //保存所有监听对象  SimStateCallback   
  6.     private static class SimArgs {  //Sim状态信息   
  7.       ...  
  8.     }  
  9.     /** 
  10.      * Callback for general information relevant to lock screen. 
  11.      */  
  12.     interface InfoCallback {  
  13.         //电池电量信息改变:参数含义分别如下:是否显示电量信息  、 是否插入电影充电、 当前电池电量值   
  14.         void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel);  
  15.         void onTimeChanged(); //时间发生了改变   
  16.         //网络运营商状态发生了改变 ,例如从中国移动2G变为中国移动3G,或者无服务等 ;   
  17.         void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn);   
  18.         /** Called when the ringer mode changes. */  
  19.         void onRingerModeChanged(int state);  
  20.         /** 电话状态发生了改变  值可能为:EXTRA_STATE_IDLE、EXTRA_STATE_RINGING、EXTRA_STATE_OFFHOOK*/  
  21.         void onPhoneStateChanged(String newState);  
  22.     }  
  23.     /** Callback to notify of sim state change. */  
  24.     interface SimStateCallback {  
  25.         void onSimStateChanged(IccCard.State simState); //Sim卡信息发生了改变,例如有正常状况变为ABSENT/MISSING状态   
  26.     }  
  27.   
  28.     /*** Register to receive notifications about general keyguard information 
  29.      * (see {@link InfoCallback}. */  
  30.     public void registerInfoCallback(InfoCallback callback) {  
  31.         if (!mInfoCallbacks.contains(callback)) {  
  32.             mInfoCallbacks.add(callback);  //注册一个监听器   
  33.         } ...  
  34.     }  
  35.    ...  
  36.  }  
public class KeyguardUpdateMonitor {
    ...
    private int mFailedAttempts = 0;  //当前登录事,已经失败的次数
    private ArrayList<InfoCallback> mInfoCallbacks; //保存所有监听对象 InfoCallback
    private ArrayList<SimStateCallback> mSimStateCallbacks ; //保存所有监听对象  SimStateCallback
    private static class SimArgs {  //Sim状态信息
      ...
    }
    /**
     * Callback for general information relevant to lock screen.
     */
    interface InfoCallback {
    	//电池电量信息改变:参数含义分别如下:是否显示电量信息  、 是否插入电影充电、 当前电池电量值
        void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel);
        void onTimeChanged(); //时间发生了改变
        //网络运营商状态发生了改变 ,例如从中国移动2G变为中国移动3G,或者无服务等 ;
        void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn); 
        /** Called when the ringer mode changes. */
        void onRingerModeChanged(int state);
        /** 电话状态发生了改变  值可能为:EXTRA_STATE_IDLE、EXTRA_STATE_RINGING、EXTRA_STATE_OFFHOOK*/
        void onPhoneStateChanged(String newState);
    }
    /** Callback to notify of sim state change. */
    interface SimStateCallback {
        void onSimStateChanged(IccCard.State simState); //Sim卡信息发生了改变,例如有正常状况变为ABSENT/MISSING状态
    }

    /*** Register to receive notifications about general keyguard information
     * (see {@link InfoCallback}. */
    public void registerInfoCallback(InfoCallback callback) {
        if (!mInfoCallbacks.contains(callback)) {
            mInfoCallbacks.add(callback);  //注册一个监听器
        } ...
    }
   ...
 }



     7, LockPatternKeyguardView类  (自定义ViewGroup)

           功能:作为LockScreen和UnLockScreen界面的载体,控制显示哪个界面。

             其源代码释义如下:     

  1. public class LockPatternKeyguardView extends KeyguardViewBase {  
  2.     ...  
  3.     private View mLockScreen;  
  4.     private View mUnlockScreen;  
  5.   
  6.     private boolean mScreenOn = false;//是否亮屏   
  7.   
  8.     enum Mode {  
  9.         //当前显示界面的Mode Lock 或者UnLock   
  10.     }  
  11.     enum UnlockMode {  
  12.         ...//开锁界面的几种不同Mode    
  13.     }  
  14.     //构造函数   
  15.     public LockPatternKeyguardView( ...) {       
  16.         //KeyguardScreenCallback的实现对象   
  17.         mKeyguardScreenCallback = new KeyguardScreenCallback() {  
  18.            ...  
  19.         };  
  20.         ...  
  21.     }  
  22.     public void reset() {  
  23.        ...//重置显示界面   
  24.     }  
  25.     private void recreateLockScreen() {  
  26.     ...//重新构建LockScreen   
  27.     }  
  28.     private void recreateUnlockScreen() {  
  29.        ...//重新构建UnlockScreen   
  30.     }  
  31.     private void recreateScreens() {  
  32.        ...//重新构建该视图   
  33.     }  
  34.     public void verifyUnlock() {  
  35.        ...   
  36.     }  
  37.     public void cleanUp() {  
  38.     ... //清理资源对象   
  39.     }  
  40.     private boolean isSecure() {  
  41.        ...//手机设置是否处于安全状态   
  42.     }  
  43.     private void updateScreen(final Mode mode) {  
  44.        ...//根据参数(Lock/unLock),判断显示为LockScreen或者UnlockScreen界面   
  45.     }  
  46.     View createLockScreen() {  
  47.     ...//创建lockScreen   
  48.     }  
  49.     View createUnlockScreenFor(UnlockMode unlockMode) {  
  50.        ...//根据不同的Unlock Mode , 创建不同的UnlockScreen   
  51.     }  
  52.     private Mode getInitialMode() {  
  53.        ...//得到初始化的状态Mode (lock or unlock).   
  54.     }  
  55.     /** Given the current state of things, what should the unlock screen be? */  
  56.     private UnlockMode getUnlockMode() {  
  57.        ...//返回开锁的状态Unlock Mode   
  58.     }  
  59.     private void showTimeoutDialog() {  
  60.         ... //输入密码超过一定次数时,提示30s后在登录的对话框   
  61.     }  
  62.     private void showAlmostAtAccountLoginDialog() {  
  63.        ... //显示Google 账户登录对话框   
  64.     }  
  65. }  
 public class LockPatternKeyguardView extends KeyguardViewBase {
     ...
     private View mLockScreen;
     private View mUnlockScreen;

     private boolean mScreenOn = false;//是否亮屏

     enum Mode {
         //当前显示界面的Mode Lock 或者UnLock
     }
     enum UnlockMode {
         ...//开锁界面的几种不同Mode 
     }
     //构造函数
     public LockPatternKeyguardView( ...) {     
         //KeyguardScreenCallback的实现对象
         mKeyguardScreenCallback = new KeyguardScreenCallback() {
            ...
         };
         ...
     }
     public void reset() {
        ...//重置显示界面
     }
     private void recreateLockScreen() {
    	...//重新构建LockScreen
     }
     private void recreateUnlockScreen() {
        ...//重新构建UnlockScreen
     }
     private void recreateScreens() {
        ...//重新构建该视图
     }
     public void verifyUnlock() {
        ... 
     }
     public void cleanUp() {
    	... //清理资源对象
     }
     private boolean isSecure() {
        ...//手机设置是否处于安全状态
     }
     private void updateScreen(final Mode mode) {
        ...//根据参数(Lock/unLock),判断显示为LockScreen或者UnlockScreen界面
     }
     View createLockScreen() {
    	...//创建lockScreen
     }
     View createUnlockScreenFor(UnlockMode unlockMode) {
        ...//根据不同的Unlock Mode , 创建不同的UnlockScreen
     }
     private Mode getInitialMode() {
        ...//得到初始化的状态Mode (lock or unlock).
     }
     /** Given the current state of things, what should the unlock screen be? */
     private UnlockMode getUnlockMode() {
        ...//返回开锁的状态Unlock Mode
     }
     private void showTimeoutDialog() {
         ... //输入密码超过一定次数时,提示30s后在登录的对话框
     }
     private void showAlmostAtAccountLoginDialog() {
        ... //显示Google 账户登录对话框
     }
 }



       8、KeyguardViewBase类 抽象类  (自定义ViewGroup)


 

            功能:为LockPatternKeyguardView提供了一组通用的方法 。需要值得注意的方法就是他对某些KeyEvent的监听,

      当他消费监听到这些KeyEvent,我们的App就监听不到这些KeyEvent了 。常用的有KEYEVENT_VOLUME_UP/DOWN等。

 

  1. public abstract class KeyguardViewBase extends FrameLayout {  
  2.      ...  
  3.   @Override  
  4.     public boolean dispatchKeyEvent(KeyEvent event) {  
  5.         ...  
  6.         if (interceptMediaKey(event)) {  
  7.             return true;  
  8.         }  
  9.         return super.dispatchKeyEvent(event);  
  10.     }  
  11.   
  12.     private boolean interceptMediaKey(KeyEvent event) {  
  13.         final int keyCode = event.getKeyCode();  
  14.         if (event.getAction() == KeyEvent.ACTION_DOWN) {  
  15.             switch (keyCode) {  
  16.                 ...//more keyevent   
  17.                 case KeyEvent.KEYCODE_VOLUME_UP:  
  18.                 case KeyEvent.KEYCODE_VOLUME_DOWN: {  
  19.                     ...  
  20.                     // Don't execute default volume behavior   
  21.                     return true//直接返回不在向下传递处理   
  22.                 }  
  23.             }  
  24.         }   
  25.         return false;  
  26.     }  
  27.  }  
public abstract class KeyguardViewBase extends FrameLayout {
	 ...
  @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        ...
        if (interceptMediaKey(event)) {
            return true;
        }
        return super.dispatchKeyEvent(event);
    }

    private boolean interceptMediaKey(KeyEvent event) {
        final int keyCode = event.getKeyCode();
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            switch (keyCode) {
                ...//more keyevent
                case KeyEvent.KEYCODE_VOLUME_UP:
                case KeyEvent.KEYCODE_VOLUME_DOWN: {
                    ...
                    // Don't execute default volume behavior
                    return true; //直接返回不在向下传递处理
                }
            }
        } 
        return false;
    }
 }


 

   9、 KeyguardViewProperties.java 接口

                 功能:提供了创建界面的通用方法。

  1.   public interface KeyguardViewProperties {    
  2.     //创建一个KeyguardViewBase实例 , 实际是指LockPatternKeyguardView实例   
  3.     KeyguardViewBase createKeyguardView(Context context,  
  4.             KeyguardUpdateMonitor updateMonitor,  
  5.             KeyguardWindowController controller);  
  6.   
  7.     boolean isSecure();  
  8. }  
   public interface KeyguardViewProperties {  
	    //创建一个KeyguardViewBase实例 , 实际是指LockPatternKeyguardView实例
	    KeyguardViewBase createKeyguardView(Context context,
	            KeyguardUpdateMonitor updateMonitor,
	            KeyguardWindowController controller);

	    boolean isSecure();
	}

                

          其唯一实现类是是LockPatternKeyguardViewProperties类(稍后讲到)。


  10、LockPatternKeyguardViewProperties类 

                源代码释义如下:

  1. public class LockPatternKeyguardViewProperties implements KeyguardViewProperties {  
  2.    ...  
  3.    //创建一个LockPatternKeyguardView对象   
  4.    public KeyguardViewBase createKeyguardView(Context context,  
  5.            KeyguardUpdateMonitor updateMonitor,  
  6.            KeyguardWindowController controller) {  
  7.        return new LockPatternKeyguardView(context, updateMonitor,  
  8.                mLockPatternUtils, controller);  
  9.    }  
 public class LockPatternKeyguardViewProperties implements KeyguardViewProperties {
    ...
    //创建一个LockPatternKeyguardView对象
    public KeyguardViewBase createKeyguardView(Context context,
            KeyguardUpdateMonitor updateMonitor,
            KeyguardWindowController controller) {
        return new LockPatternKeyguardView(context, updateMonitor,
                mLockPatternUtils, controller);
    }
}

  //=============================================

  //  OK ,我知道你看的很纠结了,具体需要时参考源代码看是最明智的。

  //=============================================


    我知道代码贴的太多了,没办法,谁让它理解起来就那么费劲呢 ? 你可别犯愁,真正核心的类可还没出来。。


    12、KeyguardViewMediator核心类 ,该类是唯一实现了KeyguardViewCallback的类。

           功能:  功能:该类提供了一些接口,由PhoneWindowManager)去访问控制Keyguard.... 

           该类的初始化是在PolicyWindowManager的构造函数中创建的。如下:

  1. public class PhoneWindowManager implements WindowManagerPolicy {  
  2.    ...  
  3.   /** {@inheritDoc} */  //由SystemServer调用   
  4.   public void init(Context context, IWindowManager windowManager,  
  5.           LocalPowerManager powerManager) {  
  6.       ...//初始化该实例   
  7.       mKeyguardMediator = new KeyguardViewMediator(context, this, powerManager);  
  8.   }  
  9.  }  
  10.    
 public class PhoneWindowManager implements WindowManagerPolicy {
	   ...
	  /** {@inheritDoc} */  //由SystemServer调用
	  public void init(Context context, IWindowManager windowManager,
	          LocalPowerManager powerManager) {
	      ...//初始化该实例
	      mKeyguardMediator = new KeyguardViewMediator(context, this, powerManager);
	  }
  }
  


 

       参照源代码,把一些重要的属性和方法的大意给分析下:
 

  1. public class KeyguardViewMediator implements KeyguardViewCallback, KeyguardUpdateMonitor.SimStateCallback {  
  2.     private boolean mSystemReady;  //启动成功 由SystemServer调用   
  3.   
  4.     /**Used to keep the device awake while to ensure the keyguard finishes opening before 
  5.      * we sleep.*/ //在需要显示锁屏界面时,保持屏幕在某个时间段内为暗屏状态     
  6.     private PowerManager.WakeLock mShowKeyguardWakeLock;  
  7.     private KeyguardViewManager mKeyguardViewManager; //KeyguardViewManager实例   
  8.     /**  * External apps (like the phone app) can tell us to disable the keygaurd.*/  
  9.     //是否允许其他App禁止锁屏 , 例如来电时 禁止锁屏   
  10.     private boolean mExternallyEnabled = true;  
  11.     //处于锁屏状态 , 即显示锁屏   
  12.     private boolean mShowing = false;  
  13.     // true if the keyguard is hidden by another window   
  14.     private boolean mHidden = false//被其他窗口掩盖 , 例如来电时锁屏被掩盖   
  15.     private boolean mScreenOn = false// 是否亮屏   
  16.   
  17.     public KeyguardViewMediator(Context context, PhoneWindowManager callback,  
  18.             LocalPowerManager powerManager) {  
  19.         ...  
  20.         //构造相关实例对象   
  21.         mKeyguardViewProperties = new LockPatternKeyguardViewProperties(  
  22.                 new LockPatternUtils(mContext), mUpdateMonitor);  
  23.   
  24.         mKeyguardViewManager = new KeyguardViewManager(  
  25.                 context, WindowManagerImpl.getDefault(), this,  
  26.                 mKeyguardViewProperties, mUpdateMonitor);  
  27.         //解锁成功后发送的Intent   
  28.         mUserPresentIntent = new Intent(Intent.ACTION_USER_PRESENT);  
  29.         mUserPresentIntent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);  
  30.     }  
  31.     /** Called to let us know the screen was turned off. 
  32.      *   @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER}, 
  33.      *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT} or 
  34.      *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}. 
  35.      */  
  36.     //屏幕变灰暗  , 原因有如下:以及对应的逻辑处理。   
  37.     // 1、OFF_BECAUSE_OF_USER : 用户按下POWER键 , 当前是否处于锁屏界面,若是(mShowing)则重置显示界面,否则重新显示锁屏界面   
  38.     // 2、OFF_BECAUSE_OF_TIMEOUT : 屏幕超时,常见情况就是一段时间没有操作屏幕,手机处于灰暗状态。          处理行为:      
  39.     //     发送Action值为DELAYED_KEYGUARD_ACTION的广播,因为该类注册了该Intent广播,接受到时会调用doKeyguard()方法锁屏   
  40.     // 3、OFF_BECAUSE_OF_PROX_SENSOR:接打电话时,距离感应太近导致暗屏,此时由于PowerManager那儿已经处理了暗屏,不需要做任何事   
  41.     // 最后,如果以上逻辑都不成立,调用 doKeyguard()方法显示屏幕                          
  42.     public void onScreenTurnedOff(int why) {  
  43.        ...  
  44.     }  
  45.     /** 
  46.      * Let's us know the screen was turned on. 
  47.      */  
  48.     public void onScreenTurnedOn() {  
  49.         synchronized (this) {  
  50.             ...  
  51.             notifyScreenOnLocked();  //通知亮屏   
  52.         }  
  53.     }  
  54.     /** Enable the keyguard if the settings are appropriate. */  
  55.     private void doKeyguard() {  
  56.         synchronized (this) {  
  57.             ...  
  58.             showLocked();//显示锁屏界面   
  59.         }  
  60.     }  
  61.     //该方法的调用时机就是当按下POWER键时,系统会回调该方法 keyCode值一般为 26   
  62.     public boolean onWakeKeyWhenKeyguardShowingTq(int keyCode) {  
  63.         //操作按键是否能唤醒屏幕    
  64.         if (isWakeKeyWhenKeyguardShowing(keyCode)) {  
  65.             // give the keyguard view manager a chance to adjust the state of the   
  66.             // keyguard based on the key that woke the device before poking   
  67.             // the wake lock   
  68.             wakeWhenReadyLocked(keyCode);//开始唤醒屏幕咯   
  69.             return true;  
  70.         } else {  
  71.             return false;  
  72.         }  
  73.     }  
  74.     /** {@inheritDoc} */  //在一定时间内保存屏幕为亮屏状态   
  75.     public void pokeWakelock(int holdMs) {  
  76.         ...  
  77.     }  
  78.     //表示成功得分完成了解锁操作   
  79.     public void keyguardDone(boolean authenticated, boolean wakeup) {  
  80.         synchronized (this) {  
  81.             //发送给Handler 进行异步处理   
  82.             Message msg = mHandler.obtainMessage(KEYGUARD_DONE);  
  83.             msg.arg1 = wakeup ? 1 : 0;  
  84.             mHandler.sendMessage(msg);  
  85.             if (authenticated) {  
  86.                 mUpdateMonitor.clearFailedAttempts(); //清除错误登录次数   
  87.             }  
  88.             ...  
  89.         }  
  90.     }  
  91.     //Handler对象 , 异步处理   
  92.     private Handler mHandler = new Handler() {  
  93.         @Override  
  94.         public void handleMessage(Message msg) {  
  95.             switch (msg.what) {  
  96.               ...  //异步处理   
  97.             }  
  98.         }  
  99.     };  
  100.     //异步处理完成开锁成功   
  101.     private void handleKeyguardDone(boolean wakeup) {   
  102.         handleHide(); //释放该Keyguard对应的窗口   
  103.         mWakeLock.release();  
  104.         mContext.sendBroadcast(mUserPresentIntent); //解锁成功,发送Intent信息   
  105.     }  
  106.     //显示锁屏界面   
  107.     private void handleShow() {  
  108.         synchronized (KeyguardViewMediator.this) {  
  109.             ...  
  110.             mKeyguardViewManager.show();  
  111.             mShowing = true;  
  112.             ...  
  113.         }  
  114.     }  
  115.     private void handleHide() {  
  116.         synchronized (KeyguardViewMediator.this) {  
  117.             //去除锁屏界面对应的窗口   
  118.             mKeyguardViewManager.hide();  
  119.             mShowing = false;  
  120.            ...  
  121.         }  
  122.     }  
  123.     //设置状态栏enable状态 , 例如:能否被下拉等   
  124.     private void adjustStatusBarLocked() {  
  125.             ...  
  126.             // if the keyguard is shown, allow the status bar to open   
  127.             // only if the keyguard is insecure and is covered by another window   
  128.             boolean enable = !mShowing || (mHidden && !isSecure());  
  129.             mStatusBarManager.disable(enable ?StatusBarManager.DISABLE_NONE : StatusBarManager.DISABLE_EXPAND);  
  130.         }  
  131.     }  
  132. }  
public class KeyguardViewMediator implements KeyguardViewCallback, KeyguardUpdateMonitor.SimStateCallback {
    private boolean mSystemReady;  //启动成功 由SystemServer调用

    /**Used to keep the device awake while to ensure the keyguard finishes opening before
     * we sleep.*/ //在需要显示锁屏界面时,保持屏幕在某个时间段内为暗屏状态  
    private PowerManager.WakeLock mShowKeyguardWakeLock;
    private KeyguardViewManager mKeyguardViewManager; //KeyguardViewManager实例
    /**  * External apps (like the phone app) can tell us to disable the keygaurd.*/
    //是否允许其他App禁止锁屏 , 例如来电时 禁止锁屏
    private boolean mExternallyEnabled = true;
    //处于锁屏状态 , 即显示锁屏
    private boolean mShowing = false;
    // true if the keyguard is hidden by another window
    private boolean mHidden = false; //被其他窗口掩盖 , 例如来电时锁屏被掩盖
    private boolean mScreenOn = false; // 是否亮屏

    public KeyguardViewMediator(Context context, PhoneWindowManager callback,
            LocalPowerManager powerManager) {
        ...
        //构造相关实例对象
        mKeyguardViewProperties = new LockPatternKeyguardViewProperties(
                new LockPatternUtils(mContext), mUpdateMonitor);

        mKeyguardViewManager = new KeyguardViewManager(
                context, WindowManagerImpl.getDefault(), this,
                mKeyguardViewProperties, mUpdateMonitor);
        //解锁成功后发送的Intent
        mUserPresentIntent = new Intent(Intent.ACTION_USER_PRESENT);
        mUserPresentIntent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
    }
    /** Called to let us know the screen was turned off.
     *   @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER},
     *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT} or
     *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}.
     */
    //屏幕变灰暗  , 原因有如下:以及对应的逻辑处理。
    // 1、OFF_BECAUSE_OF_USER : 用户按下POWER键 , 当前是否处于锁屏界面,若是(mShowing)则重置显示界面,否则重新显示锁屏界面
    // 2、OFF_BECAUSE_OF_TIMEOUT : 屏幕超时,常见情况就是一段时间没有操作屏幕,手机处于灰暗状态。          处理行为:   
    //     发送Action值为DELAYED_KEYGUARD_ACTION的广播,因为该类注册了该Intent广播,接受到时会调用doKeyguard()方法锁屏
    // 3、OFF_BECAUSE_OF_PROX_SENSOR:接打电话时,距离感应太近导致暗屏,此时由于PowerManager那儿已经处理了暗屏,不需要做任何事
    // 最后,如果以上逻辑都不成立,调用 doKeyguard()方法显示屏幕                       
    public void onScreenTurnedOff(int why) {
       ...
    }
    /**
     * Let's us know the screen was turned on.
     */
    public void onScreenTurnedOn() {
        synchronized (this) {
            ...
            notifyScreenOnLocked();  //通知亮屏
        }
    }
    /** Enable the keyguard if the settings are appropriate. */
    private void doKeyguard() {
        synchronized (this) {
            ...
            showLocked();//显示锁屏界面
        }
    }
    //该方法的调用时机就是当按下POWER键时,系统会回调该方法 keyCode值一般为 26
    public boolean onWakeKeyWhenKeyguardShowingTq(int keyCode) {
        //操作按键是否能唤醒屏幕 
        if (isWakeKeyWhenKeyguardShowing(keyCode)) {
            // give the keyguard view manager a chance to adjust the state of the
            // keyguard based on the key that woke the device before poking
            // the wake lock
            wakeWhenReadyLocked(keyCode);//开始唤醒屏幕咯
            return true;
        } else {
            return false;
        }
    }
    /** {@inheritDoc} */  //在一定时间内保存屏幕为亮屏状态
    public void pokeWakelock(int holdMs) {
        ...
    }
    //表示成功得分完成了解锁操作
    public void keyguardDone(boolean authenticated, boolean wakeup) {
        synchronized (this) {
            //发送给Handler 进行异步处理
            Message msg = mHandler.obtainMessage(KEYGUARD_DONE);
            msg.arg1 = wakeup ? 1 : 0;
            mHandler.sendMessage(msg);
            if (authenticated) {
                mUpdateMonitor.clearFailedAttempts(); //清除错误登录次数
            }
            ...
        }
    }
    //Handler对象 , 异步处理
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
              ...  //异步处理
            }
        }
    };
    //异步处理完成开锁成功
    private void handleKeyguardDone(boolean wakeup) { 
        handleHide(); //释放该Keyguard对应的窗口
        mWakeLock.release();
        mContext.sendBroadcast(mUserPresentIntent); //解锁成功,发送Intent信息
    }
    //显示锁屏界面
    private void handleShow() {
        synchronized (KeyguardViewMediator.this) {
            ...
            mKeyguardViewManager.show();
            mShowing = true;
            ...
        }
    }
    private void handleHide() {
        synchronized (KeyguardViewMediator.this) {
            //去除锁屏界面对应的窗口
            mKeyguardViewManager.hide();
            mShowing = false;
           ...
        }
    }
    //设置状态栏enable状态 , 例如:能否被下拉等
    private void adjustStatusBarLocked() {
            ...
            // if the keyguard is shown, allow the status bar to open
            // only if the keyguard is insecure and is covered by another window
            boolean enable = !mShowing || (mHidden && !isSecure());
            mStatusBarManager.disable(enable ?StatusBarManager.DISABLE_NONE : StatusBarManager.DISABLE_EXPAND);
        }
    }
}

 

     该类的很多方法都是由PhoneWindowManager调用访问的。


 

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值