Question

The following working code runs in a BroadcastReceiver that receives the BOOT_COMPLETED broadcast.

//Create a transparent, untouchable view and attach it to the system-level Window Manager
            //We will force this overlay into Landscape orientation.
            final View view = new View(context);
            int dimension = 0;
            int pixelFormat = PixelFormat.TRANSLUCENT;

            final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                    dimension, dimension,
                    WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                            | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    pixelFormat);
            params.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
            final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            wm.addView(view, params);

This is intended to force a device into Landscape mode for specialized use (not to be deployed on the Android market. This is only to be used on my devices.)

My issue is that occasionally the overlay will disappear. There doesn't seem to be a specific cause. It happens coming out of apps, or sometimes seemingly randomly. This sets it back to portrait mode and causes issues.

Is there a way that I can either prevent this or watch for it and reattach the view when it happens?

The target device is running 4.0.3

Était-ce utile?

La solution

What may be happening is that since your View is attached in a BroadcastReceiver, the app itself is then "stopped" for the rest of the time and when Android decides it needs memory, stops your it outright. This may not actually be the reason, since you do have a View always showing, but since it is not part of an Activity, the system might deal with it differently.

With that said here is what I would try to do:

Subclass your preferred View class and override onDetachedFromWindow() so it Logs/prints when the method is called. If, when this odd overlay disappearance occurs onDetachedFromWindow() is called, then determine a way to re-add the View to the WindowManager. You can send a broadcast to be picked up by a BroadcastReceiver, or create a Listener-like interface to dispatch the detached event. The interface would be then implemented by a long-running part of your app (a Service).

You could also see if the OrientationEvenListener does anything interesting when the overlay disappears.

If all else fails, you could re-add the View periodically. Not the most optimal solution, but it does ensure that the overlay reappears.

The above approaches could also be implemented in a long-running foreground service, to ensure that Android gives priority to your App and won't be so quick to kill it.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top