SoFunction
Updated on 2025-03-11

Android implements circular menu floating window

Preface

There are four main steps to implement Android floating windows:

1. Declaration and application permissions
2. The controls required to build the floating window
3. Add controls to WindowManager
4. Update the layout of WindowManager if necessary

1. Authorization application

Need to declare permissions in

<uses-permission android:name=".SYSTEM_ALERT_WINDOW" />

When it is above 6.0 (now it is basically above 6.0), the user also needs to manually open the floating window permission.

int REQUEST_CODE = 520 ;  
    Intent intent= new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, ("package:" + getPackageName()));
    startActivityForResult(intent, REQUEST_CODE);

Because it will jump to the settings interface, it is best to pop up the prompt box first and wait until the user clicks to confirm before jumping.

For specific code, please refer to:

private static final int RESULT_CODE_BOX = 10023;
    @TargetApi(Build.VERSION_CODES.M)
    private void checkBoxPower() {
        if (!(mContext)) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, ("package:" + ()));//Authorization Application Page            (intent, RESULT_CODE_BOX);
        }
    }

    @TargetApi(Build.VERSION_CODES.M)
    public void onActivityResult(int requestCode, int resultCode, Intent data){
        if(requestCode == RESULT_CODE_BOX){
            if (!(mContext)) {
                (TAG,"Authorization failed");
            } else {
                (TAG,"Authorization Success");
                //Start the Service of the floating window                Intent intent = new Intent(mActivity, );
                (intent);
            }
        }
    }

To check whether there is permissions for floating windows, return true if permissions are already available.

2. Initialization of the floating window

For specific code, please refer to:

private WindowManager windowManager;
    private  layoutParams;
    //The initial position of the floating window    private static int FloatingInitialPosition_x = 50;
    private static int FloatingInitialPosition_y = 50;
    //Initialize the floating window    private void initFrame(){
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        layoutParams = new ();//The layout of windowManager
        if (.SDK_INT &gt;= 26) { //Above 8.0 can only use the TYPE_APPLICATION_OVERLAY window type to create floating windows             = .TYPE_APPLICATION_OVERLAY;
        } else {
             = .TYPE_PHONE;
        }

         = PixelFormat.RGBA_8888;//Set picture format         = .FLAG_NOT_TOUCH_MODAL | .FLAG_NOT_FOCUSABLE;
         =  | ;//The floating frame is in the layout position         = FloatingInitialPosition_x; //The x-coordinate of the initial position, relative to gravity         = FloatingInitialPosition_y;
         = .WRAP_CONTENT;//Specify length and width         = .WRAP_CONTENT;
        
        floatView = (getApplicationContext(), .float_box_view, null);
    }
    //Display the floating window    private View floatView;
    private void showFloatingWindow() {
        (floatView, layoutParams);
    }

The floating window needs to be displayed on other programs, so you need to obtain the WINDOW_SERVICE system service through the WindowManager, and then add the corresponding view into it.
When version 8.0 or above, the window type is modified to .TYPE_APPLICATION_OVERLAY;
One of the simplest floating windows ends here.

3. Drag function

This function is a very common function in floating windows. To implement this function, touch events are required.
For specific code, please refer to:

(new FloatingOnTouchListener()); //Sliding monitoring of the floating window    //Sliding monitoring    private class FloatingOnTouchListener implements  {
        private int x;
        private int y;
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            switch (()) {
                case MotionEvent.ACTION_DOWN:
                    x = (int) ();
                    y = (int) ();
                    break;
                case MotionEvent.ACTION_MOVE:
                    int nowX = (int) ();
                    int nowY = (int) ();
                    int movedX = nowX - x;
                    int movedY = nowY - y;
                    x = nowX;
                    y = nowY;
                     =  + movedX;
                     =  + movedY;
                    (floatView, layoutParams);
                    break;
                default:
                    break;
            }
            return false;
        }
    }

Just listen to the slide to make xy changes and refresh windowManager.
One thing to note here is that if you use OnTouchListener and setOnClickListener at the same time, each move will trigger the click event at the same time, so a judgment is needed here.

3. Only display in the application

The floating window does not need to be displayed on other programs or on the desktop. It only needs to be displayed in this APP.
One of the methods is to listen to whether the app is in the foreground, and if so, it will be displayed. Hide if not.
The app is no longer in the front desk, there may be three situations: 1. Exit normally. 2. The home button returns to the main interface. 3. Click the task key to switch to another program.
If you exit normally, as long as we destroy the floating window normally.
For home keys and multi-task keys, you need to monitor the keys. Then determine whether the current App is in the foreground. If not, it hides/destroys the floating window.
For the code to determine whether the current App is in the foreground, please refer to:

public static boolean isAppOnForeground(Context context) {
        ActivityManager activityManager = (ActivityManager) ()
                .getSystemService(Context.ACTIVITY_SERVICE);
        String packageName = ().getPackageName();
        //Get all running apps in Android device        List&lt;&gt; appProcesses = ();
        if (appProcesses == null)
            return false;
        for ( appProcess : appProcesses) {
            if ((packageName)
                    &amp;&amp;  == .IMPORTANCE_FOREGROUND) {
                return true;
            }
        }
        return false;
    }

The listening code for home key and multi-task key can be referenced:

InnerRecevier innerReceiver = new InnerRecevier();
        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        registerReceiver(innerReceiver, intentFilter);

    class InnerRecevier extends BroadcastReceiver {
        final String SYSTEM_DIALOG_REASON_KEY = "reason";
        final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
        final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = ();
            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
                String reason = (SYSTEM_DIALOG_REASON_KEY);
                if (reason != null) {
                    if ((SYSTEM_DIALOG_REASON_HOME_KEY)) {
                        (, "Home button is listened to", Toast.LENGTH_SHORT).show();
                    } else if ((SYSTEM_DIALOG_REASON_RECENT_APPS)) {
                        (, "Multi-task keys are listened to", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    }

Another way is to use ViewGroup. ViewGroup does not require permission to apply, it is displayed directly. (The ViewGroup method has no association with the above code)
If it is an Android SDK for unity games, you can directly get the top-level view and then load the view of the floating window. Because most unity games only have one activity.
For specific codes, you can refer to: (This can also be used as an advertisement container to fill in the advertisement. This sample code was used to fill in the advertisement at that time)

ViewGroup view = (ViewGroup )().getDecorView();//Get the top viewViewGroup bannerContainer=(ViewGroup) (AppActivity, .activity_banner_bottom, view).findViewById();//Add a layout for it(adVeiw);//Put the floating windowviewAdd in

If it is an ordinary APP, there is not only one activity. So the method needs to be used.
ActivityLifecycleCallbacks is a method for the Activity lifecycle monitoring interface. It includes a complete set of Activity's lifecycle callback methods. As long as an Activity triggers the declaration cycle, the callback of this interface will be triggered and the Activity object that triggers the lifecycle method will be transmitted back.
After getting the currently displayed Activity, use().getDecorView() to get the view group of the Activity. Then add the view of the floating window. When switching Activity, destroy the view of the floating window, and add the view of the floating window in the newly displayed Activity.

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.