android4.0自訂鎖屏總結【android鎖屏研究一】

來源:互聯網
上載者:User

       最近搬家了,從北京--->深圳,除了天氣有點不同外,其他的都差不多,工作性質和以前也類似!紀念一下自己的遷移。

                                                                                                              -----題外話

         轉載請表明出處:http://blog.csdn.net/wdaming1986/article/details/8837023

        好了,言歸正傳,說說鎖屏了,其實把鎖屏做成apk的形式,會引起很多問題的,導致不必要的麻煩,就像市場上的流行的Go鎖屏和91鎖屏也是會有一些問題的,只是影響不大,最好的做法是修改源碼,在源碼中定製自己的鎖屏,這樣一勞永逸;

首先做鎖屏考慮的事有以下四點;

        (1)替換掉系統的鎖屏,不能讓系統的鎖屏顯示出來;

        (2)屏蔽掉Home鍵盤,back鍵,menu鍵;

        (3)在其他介面或Launcher介面,長按home鍵,不能讓自己的鎖屏apk顯示在最近任務中;

        (4)每次開機顯示自己的鎖屏

 

        針對這四點一一做解答,不一定是完整的代碼,只是提供以下思路,有興趣的同學可以提出疑問;

         針對(1),這個比較容易,就調用disableKeyguard掉系統的就可以了;

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鍵的處理,我看網上有同學寫部落格了,有同學這麼處理:

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()方法中也有根據,請看真相:

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資料的定義如下:

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;

在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()方法中,

 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中配置

<category android:name="android.intent.category.HOME" />

這個屬性,然後先清除系統啟動的預設設定,就是選擇系統點擊Home鍵啟動哪個home,設定為啟動自己的鎖屏,然後再設定解鎖後啟動那個案頭,這個自己處理下邏輯就可以了,大致思路就是這個樣子的;


             針對(4),這個Go鎖屏還有91鎖屏處理的都不太理想,回頭我想到好的思路再更新,大致思路是:監聽開機廣播, <action android:name="android.intent.action.BOOT_COMPLETED"/>,這個寫一個MYBootCompletedReceiver類,作用是disable掉系統的鎖屏,然後啟動自己的鎖屏的服務,監聽螢幕亮和滅的廣播,這個螢幕亮和滅的廣播要動態監聽;大家有好的思路或見解可以留言討論?

                                                                 做一個激情四射的程式員!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.