In the previous article, I introduced it to youAndroid program development imitates the new version of QQ under-screen pop-up function. Today, through this article, I will share with you the correct posture of the Android lock screen popup window.
Recently, I am working on the function of the screen lock screen floating window, so I searched for a lot of relevant information about Android screen lock screen on the Internet. Given that the information on the Internet is fragmented, I will sort it out and summarize it here. This article will analyze the screen lock screen from the following two points:
1. How to monitor the system screen lock screen
2. How to pop up a floating window on the lock screen interface
How to monitor the system screen lock screen
After summary, the lock screen of the monitoring system can be used in the following two ways:
1) Direct code judgment
2) Receive broadcast
1) Direct code judgment
There are two ways to judge the code:
a) Through the isScreenOn method of PowerManager, the code is as follows:
PowerManager pm = (PowerManager) (Context.POWER_SERVICE); //If true, it means the screen is "lit", otherwise the screen is "dark".boolean isScreenOn = ();
Here we need to explain:
The screen "bright" means there are two states: a. Unlocked screen b. It is currently in an unlocked state. Both states screens are illuminated;
The screen is "dark", which means that the screen is currently black.
b) Through the inKeyguardRestrictedInputMode method of KeyguardManager, the code is as follows:
KeyguardManager mKeyguardManager = (KeyguardManager) (Context.KEYGUARD_SERVICE); boolean flag = ();
After the test, the flag is summarized as:
If flag is true, there are two states: a. The screen is black. b. It is currently in the lock screen state.
If flag is false, it means that the screen is not locked at present
Note: The above two methods can also be called through the reflection mechanism.
The reflection code is as follows:
private static Method mReflectScreenState; try { mReflectScreenState = (isScreenOn, new Class[] {}); PowerManager pm = (PowerManager) (Activity.POWER_SERVICE); boolean isScreenOn= (Boolean) (pm); } catch (Exception e) { () }
2) Receive broadcast
When the Android system lock screen or screen lights up or the screen is unlocked, the corresponding broadcast will be sent inside the system. We only need to monitor the broadcast.
The pseudo-code for registering a broadcast is as follows:
private ScreenBroadcastReceiver mScreenReceiver; private class ScreenBroadcastReceiver extends BroadcastReceiver { private String action = null; @Override public void onReceive(Context context, Intent intent) { action = (); if (Intent.ACTION_SCREEN_ON.equals(action)) { // Open the screen} else if (Intent.ACTION_SCREEN_OFF.equals(action)) { // Lock screen} else if (Intent.ACTION_USER_PRESENT.equals(action)) { // Unlock} } } private void startScreenBroadcastReceiver() { IntentFilter filter = new IntentFilter(); (Intent.ACTION_SCREEN_ON); (Intent.ACTION_SCREEN_OFF); (Intent.ACTION_USER_PRESENT); (mScreenReceiver, filter); }
How to pop up a floating window on the lock screen interface
I actually know the method of monitoring the system screen. Then the next step is to pop up the floating frame when the screen is locked. There are two ways to implement this:
1) Use WindowManager
2) Use Activity
The current situation is that using both methods can be achieved on real machines. If netizens find any problems, they can leave a message in the blog
1) Use WindowManager
The code is as follows:
private void init(Context mContext) { = mContext; mWindowManager = (WindowManager) (Context.WINDOW_SERVICE); // Update the floating window position parametersDisplayMetrics dm = new DisplayMetrics(); // Get screen information().getMetrics(dm); mScreenWidth = ; mScreenHeight = ; = new (); // Set window typeif (.SDK_INT >= Build.VERSION_CODES.KITKAT) { = .TYPE_TOAST; } else { = .TYPE_PHONE; } // Set the image format, the effect is transparent background = PixelFormat.RGBA_8888; // Set the floating window to be non-focusable (to realize the operation of other visible windows except floating windows) = .FLAG_NOT_FOCUSABLE; // Adjust the docking position displayed on the floating window to set the left side? = | ; mScreenHeight = ().getHeight(); // Set the initial values of x and y with the upper left corner of the screen as the origin, relative to gravity = 0; = mScreenHeight / 2; // Set the length and width data of the floating window = LayoutParams.WRAP_CONTENT; = LayoutParams.WRAP_CONTENT; addView(createView(mContext)); (this, mWmParams); mTimer = new Timer(); hide(); }
The main configuration of WindowManager is the above code. It should be explained here that the type of type has the following values:
Application window。 public static final int FIRST_APPLICATION_WINDOW = 1; All program windows“base”window,其他Application window都显示在它上面。 public static final int TYPE_BASE_APPLICATION =1; 普通应用功能程序window。tokenMust be set toActivityoftoken,以指出该window属谁。 public static final int TYPE_APPLICATION = 2; 用于应用程序启动时所显示ofwindow。Do not use this type of application itself。 It is used to let the system display some information,直到应用程序可以开启自己ofwindow。 public static final int TYPE_APPLICATION_STARTING = 3; Application window结束。 public static final int LAST_APPLICATION_WINDOW = 99; sonwindow。sonwindowofZ序和坐标空间都依赖于他们of宿主window。 public static final int FIRST_SUB_WINDOW = 1000; 面板window,显示于宿主window上层。 public static final int TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW; 媒体window,For example video。显示于宿主window下层。 public static final int TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW+1; Application windowofson面板。显示于所有面板windowof上层。(GUIof一般规律,cross“son”cross靠上) public static final int TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW +2; Dialog Box。类似于面板window,绘制类似于顶层window,而不是宿主ofsonwindow。 public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW +3; Media Information。显示在媒体层和程序window之间,Need to be transparent(translucent)Effect。(For example, display subtitles) public static final int TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW +4; sonwindow结束。( End of types of sub-windows ) public static final int LAST_SUB_WINDOW = 1999; 系统window。Non-application creation。 public static final int FIRST_SYSTEM_WINDOW = 2000; Status bar。只能有一个Status bar;It's at the top of the screen,其他window都位于它下方。 public static final int TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW; Search bar。只能有一个Search bar;It's on top of the screen。 public static final int TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1; 电话window。It is used for telephone interaction(Especially call in)。It's on top of all applications,Status bar之下。 public static final int TYPE_PHONE = FIRST_SYSTEM_WINDOW+2; System prompts。它总是出现在Application windowAbove。 public static final int TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW +3; 锁屏window。 public static final int TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW +4; 信息window。For displaytoast。 public static final int TYPE_TOAST = FIRST_SYSTEM_WINDOW +5; 系统顶层window。Show on everything else。此window不能获得输入焦点,Otherwise, it will affect the lock screen。 public static final int TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW +6; Phone priority,Displayed when locking screen。此window不能获得输入焦点,Otherwise, it will affect the lock screen。 public static final int TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW +7; 系统Dialog Box。(For example, the volume adjustment box)。 public static final int TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW +8; 锁屏时显示ofDialog Box。 public static final int TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW +9; Internal system error message,Show on all content。 public static final int TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW +10; 内部输入法window,Shown in NormalUIAbove。应用程序可重新布局以免被此window覆盖。 public static final int TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW +11; 内部输入法Dialog Box,显示于当前输入法windowAbove。 public static final int TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW +12; 墙纸window。 public static final int TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW +13; Status barof滑动面板。 public static final int TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW +14; 系统window结束。 public static final int LAST_SYSTEM_WINDOW = 2999;
If you want the floating window to be on top of the lock screen, use TYPE_SYSTEM_ERROR as it appears on top of everything.
2) Use Activity
Activity settings
Activity needs to make the following settings before pop-up windows can be popped up when locked.
First, the onCreate method, which requires adding 4 flags, as follows:
protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); final Window win = getWindow(); (.FLAG_SHOW_WHEN_LOCKED | .FLAG_DISMISS_KEYGUARD | .FLAG_KEEP_SCREEN_ON | .FLAG_TURN_SCREEN_ON); // My own code}
As the name suggests, the four logos are displayed in the lock screen state, unlock, keep the screen bright and open the screen. This way, when the Activity is started, it will unlock and display on the screen.
Then in the file, the following attributes need to be added to the declaration of the activity:
<activity android:name="." android:launchMode="singleInstance" android:excludeFromRecents="true" android:taskAffinity="" android:theme="@android:style/"/>
For layout files, the view to be displayed is centered and the background is transparent. Since the background is already set as the background of the wallpaper, the background of the desktop is displayed. If the background is set to the default white, it will cause a piece of white to appear behind the pop-up window, which looks ugly. If the background is set to transparent, the unlocked interface will be displayed behind the pop-up window (even if there is a lock screen password, the unlocked interface will be displayed), which will also affect the visual effect.
Start the lock screen popup window during broadcast
We set up a pop-up window that only pops up under the lock screen, but it is not suitable for pop-up this window under the non-lock screen (you can try it, the effect will be very strange). Generally, a broadcast receiver is registered. After receiving the specified broadcast, it is determined whether a pop-up window is needed. Therefore, in the reception code of BroadcastReceiver, you need to first determine whether it is in the lock screen state:
@Override public void onReceive(Context context, Intent intent) { (LOG_TAG, ()); KeyguardManager km = (KeyguardManager) (Context.KEYGUARD_SERVICE); if (()) { Intent alarmIntent = new Intent(context, ); (Intent.FLAG_ACTIVITY_NEW_TASK); (alarmIntent); } }
The KeyguardManager class is used here to manage the lock screen. After 4.1, the API of this class has added a method of isKeyguardLocked() to determine whether to lock the screen. However, before 4.1, we can only use the inKeyguardRestrictedInputMode() method. If true, it is the lock screen state. It should be noted that the context in which the Activity is started in the broadcast may not be an Activity object, so you need to add the NEW_TASK flag, otherwise an error may be reported during startup. We can combine the previous system to send the broadcast and then perform the corresponding floating window pop-up processing.
Rewrite the onNewIntent method
The screen is lit again. If the activity does not exit but the screen lock key is manually pressed, the screen will not be called when the current broadcast receiver starts it again, so we need to add a code to wake up the screen in the activity, using the power lock here. It can be added in onNewIntent(Intent intent) because it will be called. It can also be added in other suitable lifecycle methods. Add the code as follows:
PowerManager pm = (PowerManager) (Context.POWER_SERVICE); if (!()) { wl = (PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright"); (); (); }
Finally, add the following permissions
<uses-permission android:name=".DISABLE_KEYGUARD"/> <uses-permission android:name=".WAKE_LOCK"/>
The first one is required to unlock the screen, and the second one is required to apply for a power lock.
The above is a detailed explanation of the correct posture of the Android screen lock screen popup window introduced by the editor. I hope it will be helpful to everyone. If you have any questions, please leave me a message. The editor will reply you in time. Thank you very much for your support for my website!