標籤:
轉載請表明出處:http://blog.csdn.net/wdaming1986/article/details/8837023
好了,言歸正傳,說說鎖屏了,其實把鎖屏做成apk的形式,會引起很多問題的,導致不必要的麻煩,就像市場上的流行的Go鎖屏和91鎖屏也是會有一些問題的,只是影響不大,最好的做法是修改源碼,在源碼中定製自己的鎖屏,這樣一勞永逸;
首先做鎖屏考慮的事有以下四點;
(1)替換掉系統的鎖屏,不能讓系統的鎖屏顯示出來;
(2)屏蔽掉Home鍵盤,back鍵,menu鍵;
(3)在其他介面或Launcher介面,長按home鍵,不能讓自己的鎖屏apk顯示在最近任務中;
(4)每次開機顯示自己的鎖屏
針對這四點一一做解答,不一定是完整的代碼,只是提供以下思路,有興趣的同學可以提出疑問;
針對(1),這個比較容易,就調用disableKeyguard掉系統的就可以了;
[java] view plaincopyprint?
- mKeyguardManager = (KeyguardManager)Class.this.getSystemService(Context.KEYGUARD_SERVICE);
- mKeyguardLock = mKeyguardManager.newKeyguardLock("my_lockscreen");
- mKeyguardLock.disableKeyguard();
注意:在Manifext.xml中加入許可權:
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
針對(2),這個Home鍵的處理,我看網上有同學寫部落格了,有同學這麼處理:
[java] view plaincopyprint?
- public class LockLayer {
- private Activity mActivty;
- private WindowManager mWindowManager;
- private View mLockView;
- private LayoutParams mLockViewLayoutParams;
- private static LockLayer mLockLayer;
- private boolean isLocked;
-
- public static synchronized LockLayer getInstance(Activity act){
- if(mLockLayer == null){
- mLockLayer = new LockLayer(act);
- }
- return mLockLayer;
- }
-
- private LockLayer(Activity act) {
- mActivty = act;
- init();
- }
-
- private void init(){
- isLocked = false;
- mWindowManager = mActivty.getWindowManager();
- mLockViewLayoutParams = new LayoutParams();
- mLockViewLayoutParams.width = LayoutParams.MATCH_PARENT;
- mLockViewLayoutParams.height = LayoutParams.MATCH_PARENT;
- //實現關鍵
- mLockViewLayoutParams.type = LayoutParams.TYPE_SYSTEM_ERROR;
- //apktool value,這個值具體是哪個變數還請網友幫忙
- mLockViewLayoutParams.flags = 1280;
- }
- public synchronized void lock() {
- if(mLockView!=null&&!isLocked){
- mWindowManager.addView(mLockView, mLockViewLayoutParams);
- }
- isLocked = true;
- }
- public synchronized void unlock() {
- if(mWindowManager!=null&&isLocked){
- mWindowManager.removeView(mLockView);
- }
- isLocked = false;
- }
- public synchronized void setLockView(View v){
- mLockView = v;
- }
- }
原理:是把這個view當成系統的錯誤的view,
這個在PhoneWindowManager.java中的interceptKeyBeforeDispatching()方法中也有根據,請看真相:
[java] view plaincopyprint?
- final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
- for (int i=0; i<typeCount; i++) {
- if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
- // don‘t do anything, but also don‘t pass it to the app
- return -1;
- }
- }
看注釋:如果設定了這兩個屬性的其中一個,就不做任何處理,home鍵不對這個app生效;
而WINDOW_TYPES_WHERE_HOME_DOESNT_WORK資料的定義如下:
[java] view plaincopyprint?
- private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = {
- WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
- WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
- };
這下你就明白為什麼上述代碼設定為TYPE_SYSTEM_ERROR,其實設定為TYPE_SYSTEM_ALERT也可以的。
再來看看sdk文檔有解釋說明,
Window type: internal system error windows, appear on top of everything they can. In multiuser systems shows only on the owning user‘s window.
這個error的view在所有的view的最上面,所以就可以達到屏蔽home鍵的效果了;
問題來了:在這個介面長按power鍵,關機介面也彈不出來了,這個我實驗過,所以這個方法不可取;
還有同學說這麼做:
private static final int FLAG_HOMEKEY_DISPATCHED = 0x80000000;
[java] view plaincopyprint?
- 在app 的你要屏蔽home 鍵的activity 中,只需要添加該標誌就可以了
-
- this.getWindow().setFlags(FLAG_HOMEKEY_DISPATCHED, FLAG_HOMEKEY_DISPATCHED);
-
- 如果要使home 鍵有效,再 clearFlags 即可。
-
- getWindow().clearFlags(WindowManager.LayoutParams.FLAG_HOMEKEY_DISPATCHED);
注意:以上代碼要加在setContentView()之前才行;
這個代碼來源於PhoneWindowManager.java這個類的interceptKeyBeforeDispatching()方法中,
[html] view plaincopyprint?
- if ((flag & WindowManager.LayoutParams.FLAG_HOMEKEY_DISPATCHED) != 0) {
- // the window wants to handle the home key, so dispatch it to it.
- return 0;
- }
這樣設定,有的同學感覺好用,有的同學感覺不好用;
原因:android4.0的源碼的PhoneWindowManager.java沒有添加上述代碼,所以不起作用,
而4.1的源碼PhoneWindowManager.java中有這個代碼,所以好用,這個請大家看看對應的源碼是否有上述代碼;
針對(3),這個就模仿Go鎖屏和91鎖屏,在啟動鎖屏的activity中配置
[java] view plaincopyprint?
- <category android:name="android.intent.category.HOME" />
這個屬性,然後先清除系統啟動的預設設定,就是選擇系統點擊Home鍵啟動哪個home,設定為啟動自己的鎖屏,然後再設定解鎖後啟動那個案頭,這個自己處理下邏輯就可以了,大致思路就是這個樣子的;
針對(4),這個Go鎖屏還有91鎖屏處理的都不太理想,回頭我想到好的思路再更新,大致思路是:監聽開機廣播, <action android:name="android.intent.action.BOOT_COMPLETED"/>,這個寫一個MYBootCompletedReceiver類,作用是disable掉系統的鎖屏,然後啟動自己的鎖屏的服務,監聽螢幕亮和滅的廣播,這個螢幕亮和滅的廣播要動態監聽;大家有好的思路或見解可以留言討論?
android4.0 鎖屏實現(轉)