實現鎖屏的方法,其實上網一搜一大把,無非是告訴你在Screen Off
的時候啓動某個Activity,同時把Keyguard
禁用掉,可是一般狀況下,彷佛很難解決HOME
鍵能解鎖的這麼一個問題,今天咱們就來說一個方案,就是如何近乎完美的實現咱們的鎖屏。java
咱們知道,鎖屏的界面顯示是使用KeyguardViewManager
進行添加的,可是這個類屬於Android的內部類,咱們調用不到,它屬於com.android.internal.policy.impl
這個包,源碼地址:https://github.com/android/platform_frameworks_policies_base/blob/mast...android
咱們能夠看到它彷佛是使用WindowManager添加View的方式實現了鎖屏界面的添加,而不是使用傳統的Activity的方式。git
那麼使用WindowManager
是咱們可行的方案,它的好處就是能夠屏蔽Home鍵的觸發,同時能夠作一些特殊的動畫效果。github
咱們首先開啓一個Service
,在Service
中註冊SREEN_OFF
的廣播,觸發廣播的時候,使用WindowManager加入鎖屏頁面,實現鎖屏便可。
看下咱們的Receiver代碼:佈局
javaif (action.equals(Intent.ACTION_SCREEN_OFF)) { ViewParent viewParent = mContainer.getParent(); if (viewParent != null) { return; } mKeyguardLock.disableKeyguard(); WindowManager windowManager = (WindowManager)getSystemService(WINDOW_SERVICE); WindowManager.LayoutParams lp = generateLayoutParams(); windowManager.addView(mContainer, lp); } private WindowManager.LayoutParams generateLayoutParams() { WindowManager windowManager = (WindowManager)getSystemService(WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); Point size = new Point(); display.getSize(size); WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; lp.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; lp.x = 0; lp.y = 0; lp.format = PixelFormat.TRANSLUCENT; return lp; }
這裏主要的是須要設置WindowManager的佈局參數(LayoutParams),若是看WindowManager的源碼的話,咱們能夠看見它的TYPE有一個TYPE_KEYGUARD
,這就是系統鎖屏用的類型了,可是它不提供給外部使用,所以咱們只能使用級別比較高的TYPE_SYSTEM_ALERT
,覆蓋到鎖屏的上面。format
設置成TRANSLUCENT
的緣由是咱們須要和鎖屏交互的時候,鎖屏後面的界面要顯示出來,因此它是一個透明的層,這裏沒有辦法,咱們只能把一些交互的代碼放到須要添加的View層中進行處理。動畫
使用這種方式實現的鎖屏,能較好的和Launcher
或者其餘界面交互(包括漸變、過渡等),並且能使得咱們的鎖屏界面不響應HOME
鍵(使用Activity的方式的話,home會讓咱們進入到Launcher
裏)。code
更多的內容我正在探索,敬請期待。orm