国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android如何實現鎖屏狀態下彈窗

2019-12-12 05:41:40
字體:
來源:轉載
供稿:網友

前言

想在鎖屏上面實現彈窗,第一個想法就是利用 WindowManager 設置 Window Flag,通過設置 Flag 的顯示優先級來讓窗口顯示在鎖屏的上面。

接下來就是試驗可能相關的 Window Type 屬性,驗證該方案是否可行。

在嘗試各個 Window Type 屬性之前需要明確各個 Type 所需要的權限,下面是 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;}

明顯不適合的 TypeTYPE_TOAST, TYPE_INPUT_METHOD, TYPE_WALLPAPER; 可能適合的 TypeTYPE_PHONE, TYPE_PRIORITY_PHONE, TYPE_SYSTEM_ALERT, TYPE_SYSTEM_ERROR, TYPE_SYSTEM_OVERLAY; 其它類型的 Type

需要系統簽名權限:

android.Manifest.permission.INTERNAL_SYSTEM_WINDOW

而申請該權限需要系統簽名,所以我們是無法獲取權限的。

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。而且實際的行為和注釋并不相符,該類型的窗口是可以獲取交互事件的,具體原因待查。

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 類型的窗口可以顯示在所有其它窗口的上面,包括鎖屏,而且不會影響它下面窗口的交互事件響應,但是該屬性窗口不能獲得焦點,無法進行交互(如果該窗口可以獲取焦點,那么就可以用來抓取用戶的鎖屏密碼,出于安全考慮,系統是不會允許的),所以只能用來簡單的展示內容,如果需要交互的鎖屏彈窗,那么該屬性 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 下試驗是可以顯示出來的,但根據注釋來看(appear on top of everything they can)不是在所有情況下都可以顯示在鎖屏上面的,而且像 MIUI 和 Flyme 等 ROM 默認是屏蔽浮窗權限的,考慮到這點,利用 WindowManager 添加浮窗的方式實現鎖屏彈窗的方案基本 PASS。

使用 Activity 的方式實現

首先需要對 Activity 進行如下設置

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); }

其中最主要也是必須要設置的就是:FLAG_SHOW_WHEN_LOCKED,顧名思義就是鎖屏下顯示該 Activity。而其它幾個 Flag 包括:解鎖、保持屏幕常亮、點亮屏幕可以根據具體的需求選擇設置。

在 AndroidManifest.xml 中聲明 Activity

同樣該 Activity 也需要在 AndroidManifest.xml 中聲明,聲明時需注意添加 android:excludeFromRecents="true" 屬性,是為了將該 Activity 從最近任務列表中去除,否則用戶會覺得很奇怪。還有因為這個 Activity 會整個蓋在鎖屏上面,而且就算設置成背景透明,鎖屏界面也不會顯示在下面(系統主要是出于安全考慮),所以需要考慮下該 Activity 的背景,這里為了顯示不要太突兀將主題設為壁紙。

<activity android:name=".LockScreenActivity"      android:launchMode="singleInstance"      android:excludeFromRecents="true"      android:theme="@android:style/Theme.Wallpaper.NoTitleBar"/>

啟動 Activity

由于該 Activity 是為了在鎖屏的情況下顯示的,所以啟動 Activity 時不要忘了判斷手機是否處于鎖屏狀態,可以通過下面這種方式判斷鎖屏狀態:

KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);if (km.inKeyguardRestrictedInputMode()) {  // 處于鎖屏狀態}

總結

以上就是在Android中實現鎖屏狀態下彈窗效果的全部內容,希望本文的內容對大家開發Android的時候能有所幫助,如果有疑問歡迎大家留言討論。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 湾仔区| 丁青县| 鸡东县| 故城县| 施秉县| 绥德县| 吕梁市| 渭南市| 丹棱县| 东山县| 靖州| 广德县| 旺苍县| 千阳县| 凤冈县| 得荣县| 鄱阳县| 诸城市| 南岸区| 将乐县| 惠水县| 勃利县| 玉门市| 彩票| 卓资县| 丹巴县| 禹城市| 拜城县| 亳州市| 扶沟县| 衡南县| 天水市| 启东市| 乌拉特中旗| 克山县| 红桥区| 武夷山市| 错那县| 惠水县| 牟定县| 绥阳县|