一、引言
1、軟體項目概述
基于使用者使用app過程中,手機螢幕關閉後,重新點亮手機螢幕,能夠快速看見使用者的所需資訊的需求,來設計app的自定義鎖屏效果。
2、概述
本文檔就自定義鎖屏的實作進行講解。
二、自定義鎖屏的實作方案
1、方案一
1)、總體實作
在app需要時開啟一個service,在service中時刻監聽系統息屏(SCREEN_OFF)廣播,當螢幕熄滅時,Service監聽到廣播,開啟鎖屏頁Activity,在螢幕的最上層顯示。并在activity建立時隐藏掉系統鎖屏(有密碼的情況下是禁止不掉的)。
2)、詳細實作
(1)、開啟服務注冊廣播
//開啟服務
startService(this,LockScreenService.class);
//注冊螢幕熄滅廣播
IntentFiltermScreenOffFilter = new IntentFilter();
mScreenOffFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mScreenOffReceiver, mScreenOffFilter);
(2)、監聽廣播開啟鎖屏
if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Intent mLockIntent = new Intent(context, LockScreenActivity.class);
mLockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
startActivity(mLockIntent);
}
注意:将鎖屏Activity的啟動模式設定為singleTask,否則鎖屏Activity實質上還是建立在原來的App的task棧中(可以根據需求做修改)。
(3)、去掉系統鎖屏
在啟動自定義鎖屏的同時,去掉系統鎖屏。當然如果設定了系統鎖屏密碼,系統鎖屏是無法去掉的,具體代碼如下:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
FLAG_DISMISS_KEYGUARD用于去掉系統鎖屏頁。
FLAG_SHOW_WHEN_LOCKED使Activity在鎖屏時能夠顯示。
去掉系統鎖屏需要添權重限如下:
<uses-permissionandroid:name="android.permission.DISABLE_KEYGUARD" />
(4)、屏蔽Back和Menu鍵
重寫onKeyDown方法屏蔽,代碼如下:
public boolean onKeyDown(int keyCode,KeyEvent event) {
int key = event.getKeyCode();
switch (key) {
case KeyEvent.KEYCODE_BACK:
return true;
case KeyEvent.KEYCODE_MENU:
return true;
default:
break;
}
return super.onKeyDown(keyCode,event);
}
當熄滅螢幕後,就可以看到我們的自定義鎖屏頁了。
(5)、滑屏解鎖
當手指在螢幕上滑動時,攔截并處理滑動事件,使鎖屏頁随着手指運動,當超過一定距離,鎖屏消失,否則重新覆寫螢幕。
注意:需要給鎖屏Activity設定透明主題,否則滑動看不見背景頁面。
關鍵代碼如下:
publicboolean onTouchEvent(MotionEvent event) {
mWidth = getWidth();
int action = event.getAction();
float nx = event.getX();
switch (action) {
case MotionEvent.ACTION_DOWN:
mStartX = nx;
break;
case MotionEvent.ACTION_MOVE:
handleMoveView(nx);
break;
case MotionEvent.ACTION_UP:
caseMotionEvent.ACTION_CANCEL:
doMoveEvent(nx);
break;
}
return true;
}
mStartX:用來記錄滑動的起始位置。
handleMoveView():根據滑動的x軸距離,來控制view的移動。
doMoveEvent():根據結束位置和起始位置的距離,來判斷是否超過門檻值,如果超過了門檻值,view滑出螢幕,銷毀鎖屏;否則重新覆寫螢幕
(6)、近期任務不顯示鎖屏Activity
在清單檔案中,設定鎖屏Activity屬性:android:excludeFromRecents=”true”,讓鎖屏Activity不顯示在近期任務中。
3)、結論
這套方案完成鎖屏頁的實作,可以滿足使用者友善檢視運動狀态的需求。
2、方案二
1)、總體實作
同方案一。
2)、詳細實作
(1)步驟
詳細實作步驟同方案一,隻是加載布局的方式不同。
(2)加載布局
方案一調用Activity的setContentView()方法加載布局;
方案二将布局inflate()成View後設成系統錯誤的view。
原理:是把這個view當成系統的錯誤的view,sdk文檔解釋說明。
Window type: internal system error windows, appear on top of everything theycan. In multiuser systems shows only on the owning user's window.
關鍵代碼如下:
mWindowManager = (WindowManager)mContext.getApplicationContext().getSystemService("window");
mParams = new LayoutParams();
mParams.type = LayoutParams.TYPE_SYSTEM_ERROR;
mWindowManager.addView(mLockView, mParams);
3)、結論
這個error的view在所有的view的最上面,可以達到屏蔽home鍵的,Recent鍵以及下拉效果,并且長按power鍵,關機界面也彈不出來。這套方案同樣可以滿足使用者友善檢視詳細資訊的需求。
三、問題與總結
1、禁止Home鍵與Recent鍵
Home鍵與Recent鍵(調出最近打開應用的按鍵)的點選事件是在Framework層進行處理的,是以onKeyDown與dispatchKeyEvent都捕獲不到點選事件,是以無法屏蔽其點選效果。關于這兩個按鍵的屏蔽方法,網上用到了反射,有的是通過改變Window的标志位和Type等,總的來說,這些方法隻對部分Android版本有效,有的則無法編譯通過。是以無法在應用層屏蔽掉Home鍵以及Recent鍵。
2、總結
方案二雖然屏蔽掉了按鍵的響應,但也一定程度上影響了使用者體驗,例如:關機操作。是以不建議使用。
方案一在滿足使用者的需求的同時,并沒有影響到使用者的體驗。并且與市場上qq音樂,keep的鎖屏頁實作了相同的效果(并沒有對home鍵,Recent鍵以及下拉菜單做相應的處理),是以方案一比較合适。
代碼下載下傳
http://download.csdn.net/detail/chendeshan330/9916014