Search code examples
androidandroid-layoutandroid-intentandroid-fullscreen

Android - Remove fullscreen view added with addView


I have a widget that trough an Intent calls to this activity that it's onCreate method has the following code:

WindowManager wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mTopView = (ViewGroup) inflater.inflate(R.layout.screen_filter, null);

WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                PixelFormat.TRANSLUCENT);           

        params.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                |WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 
                |WindowManager.LayoutParams.FLAG_FULLSCREEN;

        getWindow().setAttributes(params);
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        wm.addView(mTopView, params);

That code creates an overlay that acts as a screen filter staying on top of every activity.

Problem is that I don't know how to remove it later.

Calling to wm.removeView(mTopView); gives an error

java.lang.IllegalArgumentException: View not attached to window manager

From what I understand I lose the reference to that View I add since I call it from a widget using an Intent. It's a state machine, one state adds this view and following states is supposed to remove it.

How can I remove it? Maybe some method allows me to search for all the added views and then delete them?

Any hint would be appreciated.


Solution

  • Since your using the window manager to show the alert view , you need to keep the instance of the view added.

    Create a service to add the view to window. So when the service is destroyed , you can remove the view from the window.

    Here is a sample code ..

    public class FloatingService extends Service {
    
    private WindowManager windowManager;
    private View floatingView;
    
    WindowManager.LayoutParams params;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    
    @Override
    public int onStartCommand(Intent intent, int flag, int startId)
    {
        // add window
        showAlert();
        return START_STICKY;
    }
    
    private void showAlert() {
        if(windowManager == null || floatingView == null) {
            windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
            floatingView = View.inflate(getBaseContext(),R.layout.floating_layout,null);
            // do your stuff to update the view in layout
            params = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.TYPE_PHONE,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    PixelFormat.TRANSLUCENT);
            params.gravity = Gravity.CENTER | Gravity.CENTER;
            windowManager.addView(floatingView, params);
        }
    }
    
    @Override
    public void onCreate() {
        super.onCreate();
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (floatingView != null) windowManager.removeView(floatingView);
    }