最近搬家了,從北京--->深圳,除了天氣有點不同外,其他的都差不多,工作性質和以前也類似!紀念一下自己的遷移。
-----題外話
轉載請表明出處: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掉系統的鎖屏,然後啟動自己的鎖屏的服務,監聽螢幕亮和滅的廣播,這個螢幕亮和滅的廣播要動態監聽;大家有好的思路或見解可以留言討論?
做一個激情四射的程式員!