行业知识
Android 判断应用是否处于非全屏模式或fullScreen
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.如果你需要在应用的其他组件(如 Fragment、Service 等)中检查分屏模式,你可以使用 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)));
- field.get(configuration):首先通过反射获取了名为 “windowConfiguration” 的字段所对应的值,这个值是 configuration 对象中的一个字段的值。
- 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; } | NAME | VALE | explain |
|---|---|---|
| WINDOWING_MODE_UNDEFINED | 0 | 处理未定义的窗口模式 |
| WINDOWING_MODE_FULLSCREEN | 1 | 处理全屏窗口模式 |
| WINDOWING_MODE_PINNED | 2 | 处理固定窗口模式 |
| WINDOWING_MODE_FREEFORM | 5 | 处理自由窗口模式 |
| WINDOWING_MODE_MULTI_WINDOW | 6 | 处理多窗口模式 |
通过反射的方式可以拿到全部的窗口模式,通过返回值判断当前是否处于FullScreen状态。
上一篇:服务器无法进入怎么办?