Android如何實(shí)現(xiàn)鎖屏狀態(tài)下彈窗
前言
想在鎖屏上面實(shí)現(xiàn)彈窗,第一個(gè)想法就是利用 WindowManager 設(shè)置 Window 的 Flag,通過(guò)設(shè)置 Flag 的顯示優(yōu)先級(jí)來(lái)讓窗口顯示在鎖屏的上面。
接下來(lái)就是試驗(yàn)可能相關(guān)的 Window Type 屬性,驗(yàn)證該方案是否可行。
在嘗試各個(gè) Window Type 屬性之前需要明確各個(gè) Type 所需要的權(quán)限,下面是 com.android.internal.policy.impl.PhoneWindowManager.checkAddPermission 的源碼:
public int checkAddPermission(WindowManager.LayoutParams attrs) {
int type = attrs.type;
if (type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
|| type > WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) {
return WindowManagerImpl.ADD_OKAY;
}
String permission = null;
switch (type) {
case TYPE_TOAST:
// XXX right now the app process has complete control over
// this... should introduce a token to let the system
// monitor/control what they are doing.
break;
case TYPE_INPUT_METHOD:
case TYPE_WALLPAPER:
// The window manager will check these.
break;
case TYPE_PHONE:
case TYPE_PRIORITY_PHONE:
case TYPE_SYSTEM_ALERT:
case TYPE_SYSTEM_ERROR:
case TYPE_SYSTEM_OVERLAY:
permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW;
break;
default:
permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
}
if (permission != null) {
if (mContext.checkCallingOrSelfPermission(permission)
!= PackageManager.PERMISSION_GRANTED) {
return WindowManagerImpl.ADD_PERMISSION_DENIED;
}
}
return WindowManagerImpl.ADD_OKAY;
}
明顯不適合的 Type:TYPE_TOAST, TYPE_INPUT_METHOD, TYPE_WALLPAPER; 可能適合的 Type:TYPE_PHONE, TYPE_PRIORITY_PHONE, TYPE_SYSTEM_ALERT, TYPE_SYSTEM_ERROR, TYPE_SYSTEM_OVERLAY; 其它類型的 Type:
需要系統(tǒng)簽名權(quán)限:
android.Manifest.permission.INTERNAL_SYSTEM_WINDOW
而申請(qǐng)?jiān)摍?quán)限需要系統(tǒng)簽名,所以我們是無(wú)法獲取權(quán)限的。
TYPE_PHONE
/** * Window type: phone. These are non-application windows providing * user interaction with the phone (in particular incoming calls). * These windows are normally placed above all applications, but behind * the status bar. * In multiuser systems shows on all users' windows. */ public static final int TYPE_PHONE = FIRST_SYSTEM_WINDOW+2;
TYPE_PHONE 類型的窗口可以顯示在其它 APP 的上面,但不能顯示在鎖屏的上面,所以 PASS。
TYPE_PRIORITY_PHONE
/** * Window type: priority phone UI, which needs to be displayed even if * the keyguard is active. These windows must not take input * focus, or they will interfere with the keyguard. * In multiuser systems shows on all users' windows. */ public static final int TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7;
TYPE_PRIORITY_PHONE 類型的窗口可以顯示在其它 APP 的上面,但不能顯示在鎖屏的上面,所以 PASS。而且實(shí)際的行為和注釋并不相符,該類型的窗口是可以獲取交互事件的,具體原因待查。
TYPE_SYSTEM_ALERT
/** * Window type: system window, such as low power alert. These windows * are always on top of application windows. * In multiuser systems shows only on the owning user's window. */ public static final int TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW+3;
TYPE_SYSTEM_ALERT 類型的窗口可以顯示在其它 APP 的上面,但不能顯示在鎖屏的上面,所以 PASS。
TYPE_SYSTEM_OVERLAY
/** * Window type: system overlay windows, which need to be displayed * on top of everything else. These windows must not take input * focus, or they will interfere with the keyguard. * In multiuser systems shows only on the owning user's window. */ public static final int TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6;
TYPE_SYSTEM_OVERLAY 類型的窗口可以顯示在所有其它窗口的上面,包括鎖屏,而且不會(huì)影響它下面窗口的交互事件響應(yīng),但是該屬性窗口不能獲得焦點(diǎn),無(wú)法進(jìn)行交互(如果該窗口可以獲取焦點(diǎn),那么就可以用來(lái)抓取用戶的鎖屏密碼,出于安全考慮,系統(tǒng)是不會(huì)允許的),所以只能用來(lái)簡(jiǎn)單的展示內(nèi)容,如果需要交互的鎖屏彈窗,那么該屬性 PASS。
TYPE_SYSTEM_ERROR
/** * Window type: internal system error windows, appear on top of * everything they can. * In multiuser systems shows only on the owning user's window. */ public static final int TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+10;
在原生 ROM 5.1 下試驗(yàn)是可以顯示出來(lái)的,但根據(jù)注釋來(lái)看(appear on top of everything they can)不是在所有情況下都可以顯示在鎖屏上面的,而且像 MIUI 和 Flyme 等 ROM 默認(rèn)是屏蔽浮窗權(quán)限的,考慮到這點(diǎn),利用 WindowManager 添加浮窗的方式實(shí)現(xiàn)鎖屏彈窗的方案基本 PASS。
使用 Activity 的方式實(shí)現(xiàn)
首先需要對(duì) Activity 進(jìn)行如下設(shè)置
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
其中最主要也是必須要設(shè)置的就是:FLAG_SHOW_WHEN_LOCKED,顧名思義就是鎖屏下顯示該 Activity。而其它幾個(gè) Flag 包括:解鎖、保持屏幕常亮、點(diǎn)亮屏幕可以根據(jù)具體的需求選擇設(shè)置。
在 AndroidManifest.xml 中聲明 Activity
同樣該 Activity 也需要在 AndroidManifest.xml 中聲明,聲明時(shí)需注意添加 android:excludeFromRecents="true" 屬性,是為了將該 Activity 從最近任務(wù)列表中去除,否則用戶會(huì)覺(jué)得很奇怪。還有因?yàn)檫@個(gè) Activity 會(huì)整個(gè)蓋在鎖屏上面,而且就算設(shè)置成背景透明,鎖屏界面也不會(huì)顯示在下面(系統(tǒng)主要是出于安全考慮),所以需要考慮下該 Activity 的背景,這里為了顯示不要太突兀將主題設(shè)為壁紙。
<activity android:name=".LockScreenActivity"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
android:theme="@android:style/Theme.Wallpaper.NoTitleBar"/>
啟動(dòng) Activity
由于該 Activity 是為了在鎖屏的情況下顯示的,所以啟動(dòng) Activity 時(shí)不要忘了判斷手機(jī)是否處于鎖屏狀態(tài),可以通過(guò)下面這種方式判斷鎖屏狀態(tài):
KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if (km.inKeyguardRestrictedInputMode()) {
// 處于鎖屏狀態(tài)
}
總結(jié)
以上就是在Android中實(shí)現(xiàn)鎖屏狀態(tài)下彈窗效果的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家開(kāi)發(fā)Android的時(shí)候能有所幫助,如果有疑問(wèn)歡迎大家留言討論。
- Android 仿小米鎖屏實(shí)現(xiàn)九宮格解鎖功能(無(wú)需圖片資源)
- Android喚醒、解鎖屏幕代碼實(shí)例
- 設(shè)置Android系統(tǒng)永不鎖屏永不休眠的方法
- Android屏幕鎖屏彈窗的正確姿勢(shì)DEMO詳解
- Android編程實(shí)現(xiàn)禁止系統(tǒng)鎖屏與解鎖亮屏的方法
- Android編程實(shí)現(xiàn)一鍵鎖屏的方法
- android禁止鎖屏保持常亮(示例代碼)
- Android系統(tǒng)永不鎖屏永不休眠的方法
- Android 監(jiān)聽(tīng)鎖屏、解鎖、開(kāi)屏 功能代碼
- android九宮格鎖屏控件使用詳解
相關(guān)文章
Android側(cè)滑效果簡(jiǎn)單實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了Android側(cè)滑效果簡(jiǎn)單實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Android中Item實(shí)現(xiàn)點(diǎn)擊水波紋效果
這篇文章主要給大家介紹了關(guān)于Android中Item實(shí)現(xiàn)點(diǎn)擊水波紋效果的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位Android開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11
PullToRefreshListView實(shí)現(xiàn)多條目加載上拉刷新和下拉加載
這篇文章主要為大家詳細(xì)介紹了PullToRefreshListView實(shí)現(xiàn)多條目加載上拉刷新和下拉加載,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
比較完整的android MP3 LRC歌詞滾動(dòng)高亮顯示(附源碼)
比較完整的android MP3 LRC歌詞滾動(dòng)高亮顯示(附源碼)。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-11-11
Android實(shí)現(xiàn)APP歡迎頁(yè)面簡(jiǎn)單制作思路
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)APP歡迎頁(yè)面簡(jiǎn)單制作思路,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08
android實(shí)現(xiàn)可上下回彈的scrollview
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)可上下回彈的scrollview,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
如何自己實(shí)現(xiàn)Android View Touch事件分發(fā)流程
這篇文章主要介紹了如何自己實(shí)現(xiàn)Android View Touch事件分發(fā)流程,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-03-03
SimpleCommand框架介紹以及簡(jiǎn)單使用(一)
這篇文章主要為大家詳細(xì)介紹了SimpleCommand框架以及簡(jiǎn)單使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
OpenGL Shader實(shí)例分析(7)雪花飄落效果
這篇文章主要為大家詳細(xì)介紹了OpenGL Shader實(shí)例分析第7篇,實(shí)現(xiàn)雪花飄落效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02

