As shown in the picture, the app has a function, the user sets a time, when the popup window prompt. Add a view by calling addView(View, para) with the WindowManager object.

WindowManager wm = (WindowManager) context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE); para.type = WindowManager.LayoutParams.TYPE_PHONE; . Check whether the SYSTEM_ALERT_WINDOW permission is granted. wm.addView(view, para);Copy the code

It has been working well before, but recently I upgraded the test machine to 8.0, but found that it crashed directly:

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?Copy the code

However, my app did run in the foreground at this time. After searching, I found that on 8.0, the SYSTEM_ALERT_WINDOW privilege could not display alert Windows above other applications and system Windows for TYPE_PHONE and other window types. Instead, you need a new window type called TYPE_APPLICATION_OVERLAY.

The official documents are as follows:

Applications with the SYSTEM_ALERT_WINDOW privilege can no longer use the following window types to display alert Windows above other applications and system Windows: TYPE_PHONE TYPE_PRIORITY_PHONE TYPE_SYSTEM_ALERT TYPE_SYSTEM_OVERLAY TYPE_SYSTEM_ERROR Instead, Applications must use a new window type called TYPE_APPLICATION_OVERLAY. When using the TYPE_APPLICATION_OVERLAY window type to display your application's reminder window, keep in mind the following features of the new window type: Your application's reminder window is always displayed below key system Windows such as the status bar and input methods. The system can move or resize Windows that use the TYPE_APPLICATION_OVERLAY window type to improve the screen appearance. By opening the notification bar, the user can access Settings to prevent the application from displaying a reminder window using the TYPE_APPLICATION_OVERLAY window type.Copy the code

So add a judgment when setting type:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            para.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            para.type = WindowManager.LayoutParams.TYPE_PHONE;
        }Copy the code