Android 判断应用是否处于非全屏模式或fullScreen

本文介绍了在Android应用中如何使用isInMultiWindowMode()和getWindowingMode()方法判断应用是否处于非全屏模式,包括在Activity、Fragment和服务中的应用,并通过反射机制详细解释了getWindowingMode的使用和窗口模式的含义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android 判断应用是否处于非全屏模式

对于常见大多数安卓应用判断分屏的方法是使用isInMultiWindowMode()方法来判断是否是处于全屏状态,当这种方法有一种特殊途径会失效,我们先介绍isInMultiWindowMode()方法。在使用另外一种,通过android.app.WindowConfiguration–>getWindowingMode 通过反射的方法调用到这个。

core/java/android/app/WindowConfiguration.java - platform/frameworks/base - Git at Google (googlesource.com)

isInMultiWindowMode() 方法判断分屏

1.使用 Activity 类的 isInMultiWindowMode() 方法来检查当前活动是否在分屏模式下。例如:

javaCopy codeif (isInMultiWindowMode()) {
    // 在分屏模式下执行的代码
} else {
    // 不在分屏模式下执行的代码
}

2.如果你需要在应用的其他组件(如 FragmentService 等)中检查分屏模式,你可以使用 WindowManager 来获取当前设备的配置信息,并检查 Configuration 中的 isInMultiWindowMode() 方法。例如:

javaCopy codeWindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
if (windowManager != null) {
    Configuration configuration = getResources().getConfiguration();
    if (configuration != null && configuration.isInMultiWindowMode()) {
        // 在分屏模式下执行的代码
    } else {
        // 不在分屏模式下执行的代码
    }
}

这两种方法都可以让你检查应用当前是否处于分屏模式,从而进行相应的操作。

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.WindowManager;
import android.widget.TextView;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        // 检查当前是否处于分屏模式
        checkMultiWindowMode();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // 当配置改变时重新检查分屏模式
        checkMultiWindowMode();
    }

    private void checkMultiWindowMode() {
        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        if (windowManager != null) {
            Configuration configuration = getResources().getConfiguration();
            if (configuration != null && configuration.isInMultiWindowMode()) {
                // 在分屏模式下显示特定布局
                setContentView(R.layout.activity_main_multi_window);
                TextView textView = findViewById(R.id.textView);
                textView.setText("当前处于分屏模式");
            } else {
                // 不在分屏模式下显示默认布局
                setContentView(R.layout.activity_main);
            }
        }
    }
}

上面简单的使用了isInMultiWindowMode方法来判断应用是否处于分屏状态。

getWindowingMode方法
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // 当配置改变时重新检查分屏模式
        checkWindowingMode(newConfig);
    }


/**
 * get the status whether app is shown in full screen or multi windows.
 * @param  configuration , from activity onConfigurationChanged
 * */
@SuppressLint("PrivateApi")
public static void checkWindowingMode(Configuration configuration) {
    try {
        @SuppressLint("BlockedPrivateApi")
        Field field = configuration.getClass().getDeclaredField("windowConfiguration");
        field.setAccessible(true);

        Class<?> clazz = Class.forName("android.app.WindowConfiguration");
        Method method = clazz.getDeclaredMethod("getWindowingMode", null);
        method.setAccessible(true);

        int windowingMode =  (int) (method.invoke(field.get(configuration)));
        isFullScreen = windowingMode == WINDOWING_MODE_FULL_SCREEN;
        Log.d(TAG,"windowingMode = "+windowingMode + "isFullScreen "+isFullScreen);
    } catch (Exception e) {
        e.printStackTrace();
        isFullScreen = true;
    }
}

@SuppressLint("PrivateApi") 是 Android 中的一个注解,用于告诉编译器忽略特定类型的 lint 错误或警告。

使用了私有 API,lint 可能会警告你。你可以在方法前面添加 @SuppressLint("PrivateApi") 注解来消除这个警告。

    @SuppressLint("BlockedPrivateApi")
    Field field = configuration.getClass().getDeclaredField("windowConfiguration");
    field.setAccessible(true);

使用了反射来获取 windowConfiguration 字段,这个字段可能是一个被标记为私有的 API,因此 lint 可能会对此发出警告。

通过在代码中添加 @SuppressLint("BlockedPrivateApi") 注解,你告诉 lint 忽略这个警告,使得你的代码可以编译通过。

method.setAccessible(true) 是 Java 中反射 API 中的一个方法调用,用于设置方法的可访问性。通过调用 setAccessible(true) 方法,你可以取消对方法的访问限制,使得即使这个方法是私有的或者不可访问的,你也可以在运行时调用它。

int windowingMode =  (int) (method.invoke(field.get(configuration)));
  1. field.get(configuration):首先通过反射获取了名为 “windowConfiguration” 的字段所对应的值,这个值是 configuration 对象中的一个字段的值。
  2. method.invoke(field.get(configuration)):然后调用了 method 对象所代表的方法,并传入了上一步获取到的值作为方法调用的对象。这样就相当于在获取到的对象上调用了相应的方法。

我们看一下WindowConfiguration的源码,https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/WindowConfiguration.java

    /** Windowing mode is currently not defined. */
    public static final int WINDOWING_MODE_UNDEFINED = 0;
    /** Occupies the full area of the screen or the parent container. */
    public static final int WINDOWING_MODE_FULLSCREEN = 1;
    /** Always on-top (always visible). of other siblings in its parent container. */
    public static final int WINDOWING_MODE_PINNED = 2;
    /** Can be freely resized within its parent container. */
    // TODO: Remove once freeform is migrated to wm-shell.
    public static final int WINDOWING_MODE_FREEFORM = 5;
    /** Generic multi-window with no presentation attribution from the window manager. */
    public static final int WINDOWING_MODE_MULTI_WINDOW = 6;
    /** @hide */
    @IntDef(prefix = { "WINDOWING_MODE_" }, value = {
            WINDOWING_MODE_UNDEFINED,
            WINDOWING_MODE_FULLSCREEN,
            WINDOWING_MODE_MULTI_WINDOW,
            WINDOWING_MODE_PINNED,
            WINDOWING_MODE_FREEFORM,
    })

    public void setWindowingMode(@WindowingMode int windowingMode) {
        mWindowingMode = windowingMode;
    }
    @WindowingMode
    public int getWindowingMode() {
        return mWindowingMode;
    }
NAMEVALEexplain
WINDOWING_MODE_UNDEFINED0处理未定义的窗口模式
WINDOWING_MODE_FULLSCREEN1处理全屏窗口模式
WINDOWING_MODE_PINNED2处理固定窗口模式
WINDOWING_MODE_FREEFORM5处理自由窗口模式
WINDOWING_MODE_MULTI_WINDOW6处理多窗口模式

通过反射的方式可以拿到全部的窗口模式,通过返回值判断当前是否处于FullScreen状态。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值