android4.4的Keyguard心得

2024-09-05 09:32
文章标签 心得 android4.4 keyguard

本文主要是介绍android4.4的Keyguard心得,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在总结锁屏代码之前,有两个中心思想要铭记于心

A) KeyguardHostView就是我们最终所要展示的界面,所以不论用什么方法手段,都要将这个KeyguardHostView添加到窗口中,后续填充它,都是细节问题

B) 那么问题来了,通常我们将一个view添加到窗口中会用什么方法呢? 

        答案有两种 1 WindowManager.addView()  2 LayoutInflater.inflate(resID, parentView, true); 而在锁屏代码中这两种方法都有用到

-----------------------------------------------华丽丽的分割线-------------------------------------------------------------------

接下来用一张图来解释流程



-------------------------------又是可爱的分割线--------------------------------------------------------

从图中可以看到, 开机后首先从PhoneWindowManager的systemReady方法调用两个包装类(KeyguardServiceDelegate.java  KeyguardServiceWrapper.java)之后会调用到KeyguardService.java中的onSystemReady,进而调用锁屏代码的总调度使KeyguardViewMediator.java。它就是锁屏的CEO。做我们软件的都知道,CEO一般不会太牵涉代码问题,只管分配,协调工作,客户/供应链的沟通。在KeyguardViewMediator.java中的mExternallyEnabled变量就是总监与客户谈判的筹码,如果客户第三方通过KeyguardManager.diableKeyguard()方法禁用系统锁屏后,此变量会置为false,从而不会绘制系统锁屏界面,otherwise,将任务大手一甩直接丢给总经理KeyguardViewManager.java.具体代码如下:

[java]  view plain copy
  1. <span style="font-size:12px;">    /** 
  2.      * Enable the keyguard if the settings are appropriate. 
  3.      */  
  4.     private void doKeyguardLocked(Bundle options) {  
  5.         boolean isSimSecure = mUpdateMonitor.isSimPinSecure();  
  6.         ///M: if another app is disabling us (except Sim Secure), then don't show  
  7.         if ((!mExternallyEnabled && !isSimSecure)|| PowerOffAlarmManager.isAlarmBoot()) {  
  8.         if (DEBUG) KeyguardUtils.xlogD(TAG, "doKeyguard: not showing because externally disabled");  
  9.             return;  
  10.         }  
  11.         。。。  
  12.         showLocked(options);  
  13.     }  
  14.   
  15.     private void handleShow(Bundle options) {  
  16.         。。。  
  17.         mKeyguardViewManager.show(options);  
  18.         。。。  
  19.     }  
  20.   
  21.   
  22. 通过以上代码,所有的任务都已经落实到KeyguardViewManager.java的头上,接下来看看这个总经理是如何工作的  
  23.   
  24.   
  25.   
  26.  /** 
  27.      * Show the keyguard.  Will handle creating and attaching to the view manager 
  28.      * lazily. 
  29.      */  
  30.     public synchronized void show(Bundle options) {  
  31.         if (DEBUG) Log.d(TAG, "show(); mKeyguardView=" + mKeyguardView);  
  32.   
  33.         boolean enableScreenRotation = KeyguardUtils.shouldEnableScreenRotation(mContext);  
  34.         if (DEBUG) Log.d(TAG, "show() query screen rotation after");  
  35.   
  36.         /// M: Incoming Indicator for Keyguard Rotation @{  
  37.         KeyguardUpdateMonitor.getInstance(mContext).setQueryBaseTime();  
  38.         /// @}  
  39.         <span style="color:#FF0000;">maybeCreateKeyguardLocked(enableScreenRotation, false, options);</span>  
  40.           
  41.         if (DEBUG) Log.d(TAG, "show() maybeCreateKeyguardLocked finish");  
  42.           
  43.         maybeEnableScreenRotation(enableScreenRotation);  
  44.   
  45.         // Disable common aspects of the system/status/navigation bars that are not appropriate or  
  46.         // useful on any keyguard screen but can be re-shown by dialogs or SHOW_WHEN_LOCKED  
  47.         // activities. Other disabled bits are handled by the KeyguardViewMediator talking  
  48.         // directly to the status bar service.  
  49.         int visFlags = View.STATUS_BAR_DISABLE_HOME;  
  50.         if (shouldEnableTranslucentDecor()) {  
  51.             mWindowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS  
  52.                                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;  
  53.         }  
  54.         if (DEBUG) Log.d(TAG, "show:setSystemUiVisibility(" + Integer.toHexString(visFlags)+")");  
  55.         mKeyguardHost.setSystemUiVisibility(visFlags);  
  56.   
  57.         mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);  
  58.         mKeyguardHost.setVisibility(View.VISIBLE);  
  59.         <span style="color:#FF0000;">mKeyguardView.show();</span>  
  60.         mKeyguardView.requestFocus();  
  61.         if (DEBUG) Log.d(TAG, "show() exit; mKeyguardView=" + mKeyguardView);  
  62.     }  
  63. 关键代码所以全部贴出来分析分析吧,   
  64. <span style="color:#009900;">//有一点需要提前注意mKeyguardHost只是一个空View,mKeyguardView才是真正的KeyguardHostView</span>  
  65. boolean enableScreenRotation用来判断是否允许屏幕旋转,  
  66. KeyguardUpdateMonitor.getInstance(mContext).setQueryBaseTime();此行代码是为了重新设置query的时间,比如未接来电,未读短信等,之所以重新set是为了仿照  
  67. iphone手机,绘制锁屏时,查询未读信息/未接电话的数目是针对本次锁屏后收到的未读信息/未接电话  
[java]  view plain copy
  1. maybeCreateKeyguardLocked(enableScreenRotation, false, options); 我擦~终于到关键代码了,此方法就是真正创建锁屏的方法,来一睹芳容吧  
  2.     private void maybeCreateKeyguardLocked(boolean enableScreenRotation, boolean force,  
  3.             Bundle options) {  
  4.         if (mKeyguardHost != null) {  
  5.             mKeyguardHost.saveHierarchyState(mStateContainer);  
  6.         }  
  7.   
  8.         if (mKeyguardHost == null) {  
  9.             if (DEBUG) Log.d(TAG, "keyguard host is null, creating it...");  
  10.   
  11.             <span style="color:#990000;">mKeyguardHost = new ViewManagerHost(mContext);</span>  
  12.   
  13.             int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN  
  14.                     | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR  
  15.                     | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN  
  16.                     | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;  
  17.   
  18.             if (!mNeedsInput) {  
  19.                 flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;  
  20.             }  
  21.   
  22.             final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;  
  23.             final int type = WindowManager.LayoutParams.TYPE_KEYGUARD;  
  24.             WindowManager.LayoutParams lp = new WindowManager.LayoutParams(  
  25.                     stretch, stretch, type, flags, PixelFormat.TRANSLUCENT);  
  26.             lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;  
  27.             lp.windowAnimations = R.style.Animation_LockScreen;  
  28.             lp.screenOrientation = enableScreenRotation ?  
  29.                     ActivityInfo.SCREEN_ORIENTATION_USER : ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;  
  30.   
  31.             if (ActivityManager.isHighEndGfx()) {  
  32.                 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;  
  33.                 lp.privateFlags |=  
  34.                         WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;  
  35.             }  
  36.             lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY;  
  37.             /// M: Poke user activity when operating Keyguard  
  38.             //lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;  
  39.             lp.setTitle("Keyguard");  
  40.             mWindowLayoutParams = lp;  
  41.             ///M: skip add KeyguardHost into viewManager in AT case  
  42.             if (!KeyguardViewMediator.isKeyguardInActivity) {  
  43.                 <span style="color:#CC0000;">mViewManager.addView(mKeyguardHost, lp);</span>  
  44.             } else {  
  45.                 if (DEBUG) Log.d(TAG, "skip add mKeyguardHost into mViewManager for testing");  
  46.             }  
  47.             KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mBackgroundChanger);  
  48.         }  
  49.   
  50.        /// M: If force and keyguardView is not null, we should relase memory hold by old keyguardview  
  51.         if (force && mKeyguardView != null) {  
  52.             mKeyguardView.cleanUp();  
  53.         }  
  54.         if (force || mKeyguardView == null) {  
  55.                 mKeyguardHost.setCustomBackground(null);  
  56.                 mKeyguardHost.removeAllViews();  
  57.                 <span style="color:#CC0000;">inflateKeyguardView(options);</span>  
  58.                 mKeyguardView.requestFocus();  
  59.         }  
  60.         updateUserActivityTimeoutInWindowLayoutParams();  
  61.         mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);  
  62.   
  63.         mKeyguardHost.restoreHierarchyState(mStateContainer);  
  64.     }  
此处红色代码中通过 mViewManager.addView(mKeyguardHost, lp); 将初始话的mKeyguardHost(空view)通过WindowManager.addView的方式添加到窗口之中
然后在通过 inflateKeyguardView(options); 方法将真正的KeyguardHostView也添加到mKeyguardHost中, 具体如何添加请看代码:

private void inflateKeyguardView(Bundle options) {
        /// M: add for power-off alarm @{
        int resId = R.id.keyguard_host_view;
         int layoutId = R.layout.keyguard_host_view;
        if(PowerOffAlarmManager.isAlarmBoot()){
            resId = R.id.power_off_alarm_host_view;
            layoutId = R.layout.mtk_power_off_alarm_host_view;
        }
        /// @}
        View v = mKeyguardHost.findViewById(resId);
        if (v != null) {
            mKeyguardHost.removeView(v);
        }
        /// M: Save new orientation
        mCreateOrientation = mContext.getResources().getConfiguration().orientation;
        mCreateScreenWidthDp = mContext.getResources().getConfiguration().screenWidthDp;
        mCreateScreenHeightDp = mContext.getResources().getConfiguration().screenHeightDp;
        
         final LayoutInflater inflater = LayoutInflater.from(mContext);
        View view = inflater.inflate(layoutId, mKeyguardHost, true);

        mKeyguardView = (KeyguardHostView) view.findViewById(resId);
        mKeyguardView.setLockPatternUtils(mLockPatternUtils);
        mKeyguardView.setViewMediatorCallback(mViewMediatorCallback);
        mKeyguardView.initializeSwitchingUserState(options != null &&
                options.getBoolean(IS_SWITCHING_USER));
        
        // HACK
        // The keyguard view will have set up window flags in onFinishInflate before we set
        // the view mediator callback. Make sure it knows the correct IME state.
        if (mViewMediatorCallback != null) {
            // Start of cube26 code
            if (mLockscreenNotifications)
                mNotificationView.setViewMediator(mViewMediatorCallback);
            // End of cube26 code
            
            KeyguardPasswordView kpv = (KeyguardPasswordView) mKeyguardView.findViewById(
                    R.id.keyguard_password_view);

            if (kpv != null) {
                mViewMediatorCallback.setNeedsInput(kpv.needsInput());
            }
        }

        if (options != null) {
            int widgetToShow = options.getInt(LockPatternUtils.KEYGUARD_SHOW_APPWIDGET,
                    AppWidgetManager.INVALID_APPWIDGET_ID);
            if (widgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
                mKeyguardView.goToWidget(widgetToShow);
            }
        }
    }
红色标记处,通过LayoutInflater.inflate(resId, parentView, true)的方式将 R.layout.keyguard_host_view 添加到mKeyguardHost这个空view中
自此真正的KeyguardHostView已经添加到窗口中,并且通过各中layoutparam将其显示在最上层,后续的就是如何将其显示,使用何种方式显示,比如Slide,Swipe,Password
等等,这些都是细节,后续博客中将继续分析
 
[java]  view plain copy
  1.   

这篇关于android4.4的Keyguard心得的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1138574

相关文章

招聘面试程序员的一些心得

         最近雅虎北研解散的消息触动了各大互联网公司 HR 的神经。公司里一下子面试的任务多了起来。正好借机会总结一下自己毕业后作面试官以来参与若干场技术面试的一点心得,分享一下。        当好一个面试官其实也很不容易,不但要练就一双火眼金睛,把优秀的人才和水货在短短的面试的几十分钟里分辨出来,同时面试官本身就是候选人观察公司的一个窗口。在面试中,面试官还要注意很多接人待

qt和VS动态库调用心得

1 动态库调用 1.1 QT动态库调用 1.1.1 创建一个动态链接库步骤 1)create C++类库 2).pro文件里增加路径DESTDIR= ..\MyDebug 3)编译 注:主要的不同,两点:增加了一个***_global.h和class***SHARED_EXPORT   1.1.2 调用动态链接库 1).pro文件里增加DESTDIR= ..\MyDebug,也可

系统开发心得感想

系统总结 到现在也是写了几个小系统了图书管理,通讯录,atm。也有着不小的收获,对系统开发多少是有了点认识。 1.首先需要将大体的类和每个类所要实现的功能构思一下然后将其以用大体的代码写出来不需要实现只要把函数名写出来明白每个函数之间的功能,用什么容器来存储操作数据如何才能使代码更加简洁,以及做好类之间的联系(数据文件的存写保证数据的准确性)。 然后整理思路按顺序将具体的代码写出来每个函数功能怎样

今天改bug的心得和最近学习的一些体会

昨天晚上Dan给了我一个bug,说是我的写的代码有问题,需要fix,但是我的代码曾经是经过测试的,而且code review也过了,QA也测试通过了,他提出的一个概念Inbox File System,我根本就没有听说过。所以,我昨天觉得很冤枉,所以就回了,我之前修改的ticket,而且是通过的,这个inbox的东西根本没有在原来的JIRA上面提起过。然后lixin给我找出来,我原来代码中间有个t

异常处理相关心得

这段时间发现异常捕获是非常重要的一个机制,之前光埋头写代码了,如今想来,除了代码之外,解决问题的能力也是非常重要的,而如何解决问题,异常的捕获不可或缺 @RestControllerAdvice @RestControllerAdvice 主要用于全局异常处理,它通常能够捕获由@Controller、@RestController 标注的类中抛出的异常,并对其进行统一处理,意味着从线程池中抛

并发心得

java线程分析 [url]http://irving-wei.iteye.com/blog/1260346[/url] tomcat经常无故挂掉,该如何定位问题 [url]http://www.iteye.com/topic/1121756[/url]

android4.4+实现MD状态栏并全屏显示内容

material design如此之美,美到令人窒息~~(●'◡'●) 今天实现android4.4以上版本符合MD规范的状态栏,并可以全屏显示内容(即内容可以扩展到状态栏下)。 效果图: android4.4: android6.0: 好了,效果如上图所示,完美符合MD规范~~ 实现其实很简单: 1,首先new module com

【开发心得】筑梦上海:项目风云录(2)

特别声明 这个长篇终于开了头,工作的节奏也不能耽搁,暂时也不知道何时才能收尾。人生漫漫,即使没有雷军们的成功,但是也有自己的一些小确幸。 特别声明一下,虽然这个长篇是基于真实经历,但其中有些内容纯属虚构,切勿对号入座。 项目经理是备胎 接着上次造轮子的事情说,虽然有人造轮子了,但是熟悉业务的工作必须我亲自去做了,毕竟他们都没有经历过项目锤炼,甚至还有刚刚毕业的学生。 民营企业想招聘到好学

学习3D地图引擎开发技术心得

现在市场上关于学习3D技术的书籍很多,有很多写的确实很好。个人认为好书的话一本就够了,书太多看的头晕眼花的也消化不了。我从开始学习到现在开了不下百本的相关资料,但主要还是围绕着基本学习资料在看。重要的是把一本书上的东西吃透就行。先说说我是怎么学的,各位也帮着我指导一下。 <!--[if !supportLists]-->1,  <!--[endif]-->由于从没接触过3D之类的开发(不过以前就

关于数字存储和byte[]数组的一些心得

前言 最近做项目,发现一些规律,比如数字的存储和字符串的存储,先说数字吧,最常见的整数,就涉及反码和补码,根据这些规则,甚至我们自己也能造一种数据存储结构,比如1个字节8bit,在byte里面就是一半正数一半负数,但是在二进制却是我们不理解的一种方式。计算机存储都是字节存储,字符实际上也是字节,那么byte[]数组在很多时候就很关键,比如grpc算法那一期:grpc Java demo与Spri