android 悬浮窗权限申请

发布于:2025-08-16 ⋅ 阅读:(11) ⋅ 点赞:(0)

在AndroidQ(12)中,如果应用尝试获取SYSTEM_ALERT_WINDOW权限,且设备被视为低内存设备时,系统会阻止该功能。可以通过修改ro.config.low_ram属性为false来避免这一限制,从而在设备上启用权限。

一问题描述:

预装应用到系统,应用有申请悬浮窗功能,点击去设置界面该应用下开启该开关,但是系统提示禁用该功能,截图如下:

二分析:

这是系统功能限制控制了该功能:

定位源码:android/packages/apps/Settings/src/com/android/settings/applications/manageapplications/ManageApplications.java

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        if (mListType == LIST_TYPE_OVERLAY && !Utils.isSystemAlertWindowEnabled(getContext())) {//Utils.isSystemAlertWindowEnabled(getContext())表示弹窗是否可用
            mRootView = inflater.inflate(R.layout.manage_applications_apps_unsupported, null);
            setHasOptionsMenu(false);
            return mRootView;
        }

        mRootView = inflater.inflate(R.layout.manage_applications_apps, null);
        mLoadingContainer = mRootView.findViewById(R.id.loading_container);
        mEmptyView = mRootView.findViewById(android.R.id.empty);
        mRecyclerView = mRootView.findViewById(R.id.apps_list);

        mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter,
                savedInstanceState);
        if (savedInstanceState != null) {
            mApplications.mHasReceivedLoadEntries =
                    savedInstanceState.getBoolean(EXTRA_HAS_ENTRIES, false);
            mApplications.mHasReceivedBridgeCallback =
                    savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false);
        }

我们看下面的工具类

android/packages/apps/Settings/src/com/android/settings/Utils.java

 /** Get {@link Resources} by subscription id if subscription id is valid. */
    public static Resources getResourcesForSubId(Context context, int subId) {
        if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
            return SubscriptionManager.getResourcesForSubId(context, subId);
        } else {
            return context.getResources();
        }
    }
//********************start***********************
    /**
     * Returns true if SYSTEM_ALERT_WINDOW permission is available.
     * Starting from Q, SYSTEM_ALERT_WINDOW is disabled on low ram phones.
     */
    public static boolean isSystemAlertWindowEnabled(Context context) {
        // SYSTEM_ALERT_WINDOW is disabled on on low ram devices starting from Q
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        return !(am.isLowRamDevice() && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q));
    }
//*********************end************************

    /**
     * Adds a shadow appear/disappear animation to action bar scroll.
     *
     * <p/>
     * This method must be called after {@link Fragment#onCreate(Bundle)}.
     */
    public static void setActionBarShadowAnimation(Activity activity, Lifecycle lifecycle,
            View scrollView) {
        if (activity == null) {
            Log.w(TAG, "No activity, cannot style actionbar.");
            return;
        }
        final ActionBar actionBar = activity.getActionBar();
        if (actionBar == null) {

看上面的代码,该版本是否大于Q,且am.isLowRamDevice() 设备是否是低内存

我们接下来看android/frameworks/base/core/java/android/app/ActivityManager.java

/**
     * Returns true if this is a low-RAM device.  Exactly whether a device is low-RAM
     * is ultimately up to the device configuration, but currently it generally means
     * something with 1GB or less of RAM.  This is mostly intended to be used by apps
     * to determine whether they should turn off certain features that require more RAM.
     */
    public boolean isLowRamDevice() {
        return isLowRamDeviceStatic();
    }

    /** @hide */
    @UnsupportedAppUsage
    public static boolean isLowRamDeviceStatic() {
        return RoSystemProperties.CONFIG_LOW_RAM ||
                (Build.IS_DEBUGGABLE && DEVELOPMENT_FORCE_LOW_RAM);
    }

我们看下面的/frameworks/base/core/java/com/android/internal/os/RoSystemProperties.java

    // ------ ro.config.* -------- //
    public static final boolean CONFIG_AVOID_GFX_ACCEL =
            SystemProperties.getBoolean("ro.config.avoid_gfx_accel", false);
    public static final boolean CONFIG_LOW_RAM =
            SystemProperties.getBoolean("ro.config.low_ram", false);
    public static final boolean CONFIG_SMALL_BATTERY =
            SystemProperties.getBoolean("ro.config.small_battery", false);

    // ------ ro.fw.* ------------ //
    public static final boolean FW_SYSTEM_USER_SPLIT =
            SystemProperties.getBoolean("ro.fw.system_user_split", false);
    public static final boolean MULTIUSER_HEADLESS_SYSTEM_USER =
            SystemProperties.getBoolean("ro.fw.mu.headless_system_user", false);

public static final boolean CONFIG_LOW_RAM =
            SystemProperties.getBoolean("ro.config.low_ram", false);

我们看到以上是从变量o.config.low_ram读取的,这样我们需要从属性文件中修改改默认值就可以了。

在build、device下检索,该属性,最后在build目录下找到。

三修改

修改点:

//build目录下
Date:   Fri Aug 15 11:40:32 2025 +0800

    关闭低内存系统禁用悬浮窗
    
    Change-Id: I784af2652c3a9426ec7eb9be023ffebb60318681

diff --git a/target/product/go_defaults_common.mk b/target/product/go_defaults_common.mk
index 7f19615ed..5d384eff5 100644
--- a/target/product/go_defaults_common.mk
+++ b/target/product/go_defaults_common.mk
@@ -19,7 +19,7 @@
 
 # Set lowram options and enable traced by default
 PRODUCT_VENDOR_PROPERTIES += \
-     ro.config.low_ram=true \
+     ro.config.low_ram=false \
 
 # Speed profile services and wifi-service to reduce RAM and storage.
 PRODUCT_SYSTEM_SERVER_COMPILER_FILTER := speed-profile

四重新编译刷机,效果如下:

问题解决~

参考文章:

android 悬浮窗权限申请


网站公告

今日签到

点亮在社区的每一天
去签到