Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clear WindowManager flags in Android from Fragment

I have a FLAG_SECURE set for an activity (it contains sensitive data), but in one particular Fragment I need to clear it (because od Android Beam).

Window window = getActivity().getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE);

This code clears the flag (I have it on the Fragment's onResume callback), but the issue is, that it doesn't go into effect till next configuration change (screen rotation,...) The same problem is with setting the flag once again when leaving the Fragment.

Does anybody know, what should I do to fix this? (I thought about Activity.recreate(), that could work but I don't like the solution) I don't want to create a separate Activity for this particular screen if possible.

like image 393
simekadam Avatar asked Mar 31 '15 13:03

simekadam


Video Answer


1 Answers

EDIT: added example code.

I am late here, but I will post it anyway. It is not the best solution (in my honest opinion) since it makes visible "re-draw" like effect on Android 4.x (5+ is good), but it works at least. I am using it like this:

/**
 * @param flagSecure adds/removes FLAG_SECURE from Activity this Fragment is attached to/from.
 */
public void applyFlagSecure(boolean flagSecure)
{
    Window window = getActivity().getWindow();
    WindowManager wm = getActivity().getWindowManager();

    // is change needed?
    int flags = window.getAttributes().flags;
    if (flagSecure && (flags & WindowManager.LayoutParams.FLAG_SECURE) != 0) {
        // already set, change is not needed.
        return;
    } else if (!flagSecure && (flags & WindowManager.LayoutParams.FLAG_SECURE) == 0) {
        // already cleared, change is not needed.
        return;
    }

    // apply (or clear) the FLAG_SECURE flag to/from Activity this Fragment is attached to.
    boolean flagsChanged = false;
    if (flagSecure) {
        window.addFlags(WindowManager.LayoutParams.FLAG_SECURE);
        flagsChanged = true;
    } else {
        // FIXME Do NOT unset FLAG_SECURE flag from Activity's Window if Activity explicitly set it itself.
        if (!(getActivity() instanceof YourFlagSecureActivity)) {
            // Okay, it is safe to clear FLAG_SECURE flag from Window flags.
            // Activity is (probably) not showing any secure content.
            window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
            flagsChanged = true;
        }
    }

    // Re-apply (re-draw) Window's DecorView so the change to the Window flags will be in place immediately.
    if (flagsChanged && ViewCompat.isAttachedToWindow(window.getDecorView())) {
        // FIXME Removing the View and attaching it back makes visible re-draw on Android 4.x, 5+ is good.
        wm.removeViewImmediate(window.getDecorView());
        wm.addView(window.getDecorView(), window.getAttributes());
    }
}

Source: this solution is based on kdas's example: How to disable screen capture in Android fragment?

like image 177
Miroslav Javorský Avatar answered Oct 11 '22 10:10

Miroslav Javorský