소스 검색

[fix]键盘插件,支持部分国产ROM跳转去悬浮窗权限开关页

hezihao 7 달 전
부모
커밋
9e519e5ae2

+ 2 - 2
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/floating/FloatingButtonService.kt

@@ -16,7 +16,7 @@ import android.widget.ImageView
 import com.atmob.keyboard_android.R
 import com.atmob.keyboard_android.ext.click
 import com.atmob.keyboard_android.keyboard.InputMethodPickerActivity
-import com.atmob.keyboard_android.util.FloatingWindowUtil
+import com.atmob.keyboard_android.util.flow.FloatingWindowUtil
 import kotlin.math.abs
 
 /**
@@ -34,7 +34,7 @@ class FloatingButtonService : Service() {
         fun start(context: Context) {
             // 检查是否有悬浮窗权限,没有则跳转到设置页面
             if (!FloatingWindowUtil.hasFloatingWindowPermission(context)) {
-                FloatingWindowUtil.jumpFloatingWindowSetting(context)
+                FloatingWindowUtil.tryJumpToPermissionPage(context)
             } else {
                 // 有权限,开启悬浮窗
                 val serviceIntent = Intent(context, FloatingButtonService::class.java)

+ 0 - 47
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/FloatingWindowUtil.kt

@@ -1,47 +0,0 @@
-package com.atmob.keyboard_android.util
-
-import android.content.Context
-import android.content.Intent
-import android.os.Build
-import android.provider.Settings
-import androidx.core.net.toUri
-
-/**
- * 悬浮窗工具类
- */
-class FloatingWindowUtil {
-    companion object {
-        /**
-         * 检查是否有悬浮窗权限
-         */
-        fun hasFloatingWindowPermission(context: Context): Boolean {
-            // 6.0及其以上,需要授权
-            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
-                return Settings.canDrawOverlays(context)
-            } else {
-                return true
-            }
-        }
-
-        /**
-         * 跳转到悬浮窗的权限设置页面
-         */
-        fun jumpFloatingWindowSetting(context: Context) {
-            // 安卓6以下,跳应用详情
-            val intent = if (Build.VERSION.SDK_INT < 23) {
-                Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
-                    data = "package:${context.packageName}".toUri()
-                }
-            } else {
-                // 安卓6以上,可以直接跳去悬浮窗权限列表页
-                Intent(
-                    Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
-                    "package:${context.packageName}".toUri()
-                )
-            }
-            // 重要:在非 Activity 里启动 Activity 需要添加 FLAG_ACTIVITY_NEW_TASK
-            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-            context.startActivity(intent)
-        }
-    }
-}

+ 79 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/SystemProperties.java

@@ -0,0 +1,79 @@
+package com.atmob.keyboard_android.util;
+
+import android.text.TextUtils;
+
+import java.lang.reflect.Method;
+
+/**
+ * 获取系统属性的工具类
+ */
+public class SystemProperties {
+    private static final Method getStringProperty = getMethod(getClass("android.os.SystemProperties"));
+
+    private static Class<?> getClass(String name) {
+        try {
+            Class<?> cls = Class.forName(name);
+            if (cls == null) {
+                throw new ClassNotFoundException();
+            }
+            return cls;
+        } catch (ClassNotFoundException e) {
+            try {
+                return ClassLoader.getSystemClassLoader().loadClass(name);
+            } catch (ClassNotFoundException e1) {
+                return null;
+            }
+        }
+    }
+
+    private static Method getMethod(Class<?> clz) {
+        if (clz == null) return null;
+        try {
+            return clz.getMethod("get", String.class);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static String get(String key) {
+        if (getStringProperty != null) {
+            try {
+                Object value = getStringProperty.invoke(null, key);
+                if (value == null) {
+                    return "";
+                }
+                return trimToEmpty(value.toString());
+            } catch (Exception ignored) {
+            }
+        }
+        return "";
+    }
+
+    public static String get(String key, String def) {
+        if (getStringProperty != null) {
+            try {
+                String value = (String) getStringProperty.invoke(null, key);
+                return defaultString(trimToNull(value), def);
+            } catch (Exception ignored) {
+            }
+        }
+        return def;
+    }
+
+    private static String defaultString(String str, String defaultStr) {
+        return str == null ? defaultStr : str;
+    }
+
+    private static String trimToNull(String str) {
+        String ts = trim(str);
+        return TextUtils.isEmpty(ts) ? null : ts;
+    }
+
+    private static String trimToEmpty(String str) {
+        return str == null ? "" : str.trim();
+    }
+
+    private static String trim(String str) {
+        return str == null ? null : str.trim();
+    }
+}

+ 2 - 2
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/bridge/method/KeyboardExposeNativeMethodHandler.kt

@@ -5,7 +5,6 @@ import android.os.Build
 import com.atmob.keyboard_android.floating.FloatingButtonService
 import com.atmob.keyboard_android.model.KeyboardSelectModel
 import com.atmob.keyboard_android.util.ContextUtil
-import com.atmob.keyboard_android.util.FloatingWindowUtil
 import com.atmob.keyboard_android.util.InputMethodUtil
 import com.atmob.keyboard_android.util.JsonUtil
 import com.atmob.keyboard_android.util.KeyboardHolder
@@ -14,6 +13,7 @@ import com.atmob.keyboard_android.util.bridge.FlutterBridgeManager
 import com.atmob.keyboard_android.util.bridge.callback.NativeMethodHandler
 import com.atmob.keyboard_android.util.bridge.callback.ResultCallback
 import com.atmob.keyboard_android.util.bridge.enums.ExposeNativeMethod
+import com.atmob.keyboard_android.util.flow.FloatingWindowUtil
 
 /**
  * 键盘,暴露给Flutter的原生方法处理器
@@ -68,7 +68,7 @@ class KeyboardExposeNativeMethodHandler : NativeMethodHandler {
 
             // 跳转到系统的悬浮窗设置页
             ExposeNativeMethod.JUMP_FLOATING_WINDOW_SETTING.methodName -> {
-                FloatingWindowUtil.jumpFloatingWindowSetting(context)
+                FloatingWindowUtil.tryJumpToPermissionPage(context)
                 resultCallback.onSuccess(null)
             }
 

+ 331 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/flow/FloatingWindowUtil.java

@@ -0,0 +1,331 @@
+package com.atmob.keyboard_android.util.flow;
+
+import android.Manifest;
+import android.app.AppOpsManager;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Build;
+import android.provider.Settings;
+
+import androidx.annotation.RequiresApi;
+
+import com.blankj.utilcode.util.AppUtils;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * 悬浮窗工具类
+ */
+public class FloatingWindowUtil {
+    /**
+     * 检查是否有悬浮窗权限
+     */
+    public static boolean hasFloatingWindowPermission(Context context) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            return Settings.canDrawOverlays(context);
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            return checkOps(context);
+        }
+        return true;
+    }
+
+    public static boolean checkOverlayPermission(Context context) {
+        AppOpsManager appOpsMgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        try {
+            if (appOpsMgr != null) {
+                int mode = appOpsMgr.checkOpNoThrow("android:system_alert_window",
+                        android.os.Process.myUid(), context.getPackageName());
+                if (mode == 0) {
+                    return true;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
+    private static boolean checkOps(Context context) {
+        try {
+            Object object = context.getSystemService(Context.APP_OPS_SERVICE);
+            if (object == null) {
+                return false;
+            }
+            Class localClass = object.getClass();
+            Class[] arrayOfClass = new Class[3];
+            arrayOfClass[0] = Integer.TYPE;
+            arrayOfClass[1] = Integer.TYPE;
+            arrayOfClass[2] = String.class;
+            Method method = localClass.getMethod("checkOp", arrayOfClass);
+            if (method == null) {
+                return false;
+            }
+            Object[] arrayOfObject1 = new Object[3];
+            arrayOfObject1[0] = 24;
+            arrayOfObject1[1] = Binder.getCallingUid();
+            arrayOfObject1[2] = AppUtils.getAppPackageName();
+            int m = (Integer) method.invoke(object, arrayOfObject1);
+            return m == AppOpsManager.MODE_ALLOWED || !RomUtil.isDomesticSpecialRom();
+        } catch (Exception ignore) {
+        }
+        return false;
+    }
+
+    public static boolean tryJumpToPermissionPage(Context context) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+            switch (RomUtil.getRomName()) {
+                case RomUtil.ROM_MIUI:
+                    return applyMiuiPermission(context);
+                case RomUtil.ROM_EMUI:
+                    return applyHuaweiPermission(context);
+                case RomUtil.ROM_VIVO:
+                    return applyVivoPermission(context);
+                case RomUtil.ROM_OPPO:
+                    return applyOppoPermission(context);
+                case RomUtil.ROM_QIKU:
+                    return apply360Permission(context);
+                case RomUtil.ROM_SMARTISAN:
+                    return applySmartisanPermission(context);
+                case RomUtil.ROM_COOLPAD:
+                    return applyCoolpadPermission(context);
+                case RomUtil.ROM_ZTE:
+                    return applyZTEPermission(context);
+                case RomUtil.ROM_LENOVO:
+                    return applyLenovoPermission(context);
+                case RomUtil.ROM_LETV:
+                    return applyLetvPermission(context);
+                default:
+                    return true;
+            }
+        } else {
+            if (RomUtil.isMeizuRom()) {
+                return getAppDetailSettingIntent(context);
+            } else if (RomUtil.isVivoRom()) {
+                return applyVivoPermission(context);
+            } else if (RomUtil.isMiuiRom()) {
+                return applyMiuiPermission(context) || getAppDetailSettingIntent(context);
+            } else {
+                return applyCommonPermission(context);
+            }
+        }
+    }
+
+    private static boolean startActivitySafely(Intent intent, Context context) {
+        try {
+            if (isIntentAvailable(intent, context)) {
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                context.startActivity(intent);
+                return true;
+            } else {
+                return false;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public static boolean isIntentAvailable(Intent intent, Context context) {
+        return intent != null && !context.getPackageManager().queryIntentActivities(intent,
+                PackageManager.MATCH_DEFAULT_ONLY).isEmpty();
+    }
+
+    private static boolean applyCommonPermission(Context context) {
+        try {
+            Class clazz = Settings.class;
+            Field field = clazz.getDeclaredField("ACTION_MANAGE_OVERLAY_PERMISSION");
+            Intent intent = new Intent(field.get(null).toString());
+            intent.setData(Uri.parse("package:" + context.getPackageName()));
+            startActivitySafely(intent, context);
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    private static boolean applyCoolpadPermission(Context context) {
+        Intent intent = new Intent();
+        intent.setClassName("com.yulong.android.seccenter",
+                "com.yulong.android.seccenter.dataprotection.ui.AppListActivity");
+        return startActivitySafely(intent, context);
+    }
+
+    private static boolean applyLenovoPermission(Context context) {
+        Intent intent = new Intent();
+        intent.setClassName("com.lenovo.safecenter",
+                "com.lenovo.safecenter.MainTab.LeSafeMainActivity");
+        return startActivitySafely(intent, context);
+    }
+
+    private static boolean applyZTEPermission(Context context) {
+        Intent intent = new Intent();
+        intent.setAction("com.zte.heartyservice.intent.action.startActivity.PERMISSION_SCANNER");
+        return startActivitySafely(intent, context);
+    }
+
+    private static boolean applyLetvPermission(Context context) {
+        Intent intent = new Intent();
+        intent.setClassName("com.letv.android.letvsafe",
+                "com.letv.android.letvsafe.AppActivity");
+        return startActivitySafely(intent, context);
+    }
+
+    private static boolean applyVivoPermission(Context context) {
+        Intent intent = new Intent();
+        intent.putExtra("packagename", context.getPackageName());
+        intent.setAction("com.vivo.permissionmanager");
+        intent.setClassName("com.vivo.permissionmanager",
+                "com.vivo.permissionmanager.activity.SoftPermissionDetailActivity");
+        ComponentName componentName1 = intent.resolveActivity(context.getPackageManager());
+        if (componentName1 != null) {
+            return startActivitySafely(intent, context);
+        }
+
+        intent.setAction("com.iqoo.secure");
+        intent.setClassName("com.iqoo.secure",
+                "com.iqoo.secure.safeguard.SoftPermissionDetailActivity");
+        ComponentName componentName2 = intent.resolveActivity(context.getPackageManager());
+        if (componentName2 != null) {
+            return startActivitySafely(intent, context);
+        }
+
+        intent.setAction("com.iqoo.secure");
+        intent.setClassName("com.iqoo.secure", "com.iqoo.secure.MainActivity");
+        ComponentName componentName3 = intent.resolveActivity(context.getPackageManager());
+        if (componentName3 != null) {
+            return startActivitySafely(intent, context);
+        }
+
+        return startActivitySafely(intent, context);
+    }
+
+    private static boolean applyOppoPermission(Context context) {
+        Intent intent = new Intent();
+        intent.putExtra("packageName", context.getPackageName());
+        intent.setAction("com.oppo.safe");
+        intent.setClassName("com.oppo.safe",
+                "com.oppo.safe.permission.PermissionAppListActivity");
+        if (!startActivitySafely(intent, context)) {
+            intent.setAction("com.color.safecenter");
+            intent.setClassName("com.color.safecenter",
+                    "com.color.safecenter.permission.floatwindow.FloatWindowListActivity");
+            if (!startActivitySafely(intent, context)) {
+                intent.setAction("com.coloros.safecenter");
+                intent.setClassName("com.coloros.safecenter",
+                        "com.coloros.safecenter.sysfloatwindow.FloatWindowListActivity");
+                return startActivitySafely(intent, context);
+            } else {
+                return true;
+            }
+        } else {
+            return true;
+        }
+    }
+
+    private static boolean apply360Permission(Context context) {
+        Intent intent = new Intent();
+        intent.setClassName("com.android.settings",
+                "com.android.settings.Settings$OverlaySettingsActivity");
+        if (!startActivitySafely(intent, context)) {
+            intent.setClassName("com.qihoo360.mobilesafe",
+                    "com.qihoo360.mobilesafe.ui.index.AppEnterActivity");
+            return startActivitySafely(intent, context);
+        } else {
+            return true;
+        }
+    }
+
+    private static boolean applyMiuiPermission(Context context) {
+        Intent intent = new Intent();
+        intent.setAction("miui.intent.action.APP_PERM_EDITOR");
+        intent.addCategory(Intent.CATEGORY_DEFAULT);
+        intent.putExtra("extra_pkgname", context.getPackageName());
+        return startActivitySafely(intent, context);
+    }
+
+    public static boolean getAppDetailSettingIntent(Context context) {
+        Intent localIntent = new Intent();
+        localIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+        localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
+        return startActivitySafely(localIntent, context);
+    }
+
+    private static boolean applyMeizuPermission(Context context) {
+        Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
+        intent.setClassName("com.meizu.safe",
+                "com.meizu.safe.security.AppSecActivity");
+        intent.putExtra("packageName", context.getPackageName());
+        return startActivitySafely(intent, context);
+    }
+
+    private static boolean applyHuaweiPermission(Context context) {
+        try {
+            Intent intent = new Intent();
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            ComponentName comp = new ComponentName("com.huawei.systemmanager",
+                    "com.huawei.systemmanager.addviewmonitor.AddViewMonitorActivity");
+            intent.setComponent(comp);
+            if (!startActivitySafely(intent, context)) {
+                comp = new ComponentName("com.huawei.systemmanager",
+                        "com.huawei.notificationmanager.ui.NotificationManagmentActivity");
+                intent.setComponent(comp);
+                context.startActivity(intent);
+                return true;
+            } else {
+                return true;
+            }
+        } catch (SecurityException e) {
+            try {
+                Intent intent = new Intent();
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                ComponentName comp = new ComponentName("com.huawei.systemmanager",
+                        "com.huawei.permissionmanager.ui.MainActivity");
+                intent.setComponent(comp);
+                context.startActivity(intent);
+                return true;
+            } catch (Exception e1) {
+                e.printStackTrace();
+                return getAppDetailSettingIntent(context);
+            }
+        } catch (ActivityNotFoundException e) {
+            try {
+                Intent intent = new Intent();
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                ComponentName comp = new ComponentName("com.Android.settings",
+                        "com.android.settings.permission.TabItem");
+                intent.setComponent(comp);
+                context.startActivity(intent);
+                return true;
+            } catch (Exception e2) {
+                e.printStackTrace();
+                return getAppDetailSettingIntent(context);
+            }
+        } catch (Exception e) {
+            return getAppDetailSettingIntent(context);
+        }
+    }
+
+    private static boolean applySmartisanPermission(Context context) {
+        Intent intent = new Intent("com.smartisanos.security.action.SWITCHED_PERMISSIONS_NEW");
+        intent.setClassName("com.smartisanos.security",
+                "com.smartisanos.security.SwitchedPermissions");
+        //有版本差异,不一定定位正确
+        intent.putExtra("index", 17);
+        if (startActivitySafely(intent, context)) {
+            return true;
+        } else {
+            intent = new Intent("com.smartisanos.security.action.SWITCHED_PERMISSIONS");
+            intent.setClassName("com.smartisanos.security",
+                    "com.smartisanos.security.SwitchedPermissions");
+            intent.putExtra("permission", new String[]{Manifest.permission.SYSTEM_ALERT_WINDOW});
+            return startActivitySafely(intent, context);
+        }
+    }
+}

+ 255 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/flow/RomUtil.java

@@ -0,0 +1,255 @@
+package com.atmob.keyboard_android.util.flow;
+
+import android.os.Build;
+import android.text.TextUtils;
+
+import androidx.annotation.StringDef;
+
+import com.atmob.keyboard_android.util.SystemProperties;
+import com.blankj.utilcode.util.DeviceUtils;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * ROM系统工具类
+ */
+public class RomUtil {
+    static final String ROM_MIUI = "MIUI";
+    static final String ROM_EMUI = "EMUI";
+    static final String ROM_VIVO = "VIVO";
+    static final String ROM_OPPO = "OPPO";
+    static final String ROM_FLYME = "FLYME";
+    static final String ROM_SMARTISAN = "SMARTISAN";
+    static final String ROM_QIKU = "QIKU";
+    static final String ROM_LETV = "LETV";
+    static final String ROM_LENOVO = "LENOVO";
+    static final String ROM_NUBIA = "NUBIA";
+    static final String ROM_ZTE = "ZTE";
+    static final String ROM_COOLPAD = "COOLPAD";
+    static final String ROM_UNKNOWN = "UNKNOWN";
+
+    @StringDef({
+            ROM_MIUI, ROM_EMUI, ROM_VIVO, ROM_OPPO, ROM_FLYME,
+            ROM_SMARTISAN, ROM_QIKU, ROM_LETV, ROM_LENOVO, ROM_ZTE,
+            ROM_COOLPAD, ROM_UNKNOWN
+    })
+    @Target({ElementType.METHOD})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RomName {
+    }
+
+    private static final String SYSTEM_VERSION_MIUI = "ro.miui.ui.version.name";
+    private static final String SYSTEM_VERSION_EMUI = "ro.build.version.emui";
+    private static final String SYSTEM_VERSION_VIVO = "ro.vivo.os.version";
+    private static final String SYSTEM_VERSION_OPPO = "ro.build.version.opporom";
+    private static final String SYSTEM_VERSION_FLYME = "ro.build.display.id";
+    private static final String SYSTEM_VERSION_SMARTISAN = "ro.smartisan.version";
+    private static final String SYSTEM_VERSION_LETV = "ro.letv.eui";
+    private static final String SYSTEM_VERSION_LENOVO = "ro.lenovo.lvp.version";
+
+    private static String getSystemProperty(String propName) {
+        return SystemProperties.get(propName, null);
+    }
+
+    @RomName
+    public static String getRomName() {
+        if (isMiuiRom()) {
+            return ROM_MIUI;
+        }
+        if (isHuaweiRom()) {
+            return ROM_EMUI;
+        }
+        if (isVivoRom()) {
+            return ROM_VIVO;
+        }
+        if (isOppoRom()) {
+            return ROM_OPPO;
+        }
+        if (isMeizuRom()) {
+            return ROM_FLYME;
+        }
+        if (isSmartisanRom()) {
+            return ROM_SMARTISAN;
+        }
+        if (is360Rom()) {
+            return ROM_QIKU;
+        }
+        if (isLetvRom()) {
+            return ROM_LETV;
+        }
+        if (isLenovoRom()) {
+            return ROM_LENOVO;
+        }
+        if (isZTERom()) {
+            return ROM_ZTE;
+        }
+        if (isCoolPadRom()) {
+            return ROM_COOLPAD;
+        }
+        return ROM_UNKNOWN;
+    }
+
+    public static String getDeviceManufacture() {
+        if (isMiuiRom()) {
+            return "小米";
+        }
+        if (isHuaweiRom()) {
+            return "华为";
+        }
+        if (isVivoRom()) {
+            return ROM_VIVO;
+        }
+        if (isOppoRom()) {
+            return ROM_OPPO;
+        }
+        if (isMeizuRom()) {
+            return "魅族";
+        }
+        if (isSmartisanRom()) {
+            return "锤子";
+        }
+        if (is360Rom()) {
+            return "奇酷";
+        }
+        if (isLetvRom()) {
+            return "乐视";
+        }
+        if (isLenovoRom()) {
+            return "联想";
+        }
+        if (isZTERom()) {
+            return "中兴";
+        }
+        if (isCoolPadRom()) {
+            return "酷派";
+        }
+        return DeviceUtils.getManufacturer();
+    }
+
+    public static boolean isMiuiRom() {
+        return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_MIUI));
+    }
+
+    public static boolean isHuaweiRom() {
+        return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_EMUI));
+    }
+
+    public static boolean isVivoRom() {
+        return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_VIVO));
+    }
+
+    public static boolean isOppoRom() {
+        return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_OPPO));
+    }
+
+    public static boolean isMeizuRom() {
+        String meizuFlymeOSFlag = getSystemProperty(SYSTEM_VERSION_FLYME);
+        return !TextUtils.isEmpty(meizuFlymeOSFlag) && meizuFlymeOSFlag.toUpperCase().contains(ROM_FLYME);
+    }
+
+    public static boolean isSmartisanRom() {
+        return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_SMARTISAN));
+    }
+
+    public static boolean is360Rom() {
+        String manufacturer = Build.MANUFACTURER;
+        return !TextUtils.isEmpty(manufacturer) && manufacturer.toUpperCase().contains(ROM_QIKU);
+    }
+
+    public static boolean isLetvRom() {
+        return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_LETV));
+    }
+
+    public static boolean isLenovoRom() {
+        return !TextUtils.isEmpty(getSystemProperty(SYSTEM_VERSION_LENOVO));
+    }
+
+    public static boolean isCoolPadRom() {
+        String model = Build.MODEL;
+        String fingerPrint = Build.FINGERPRINT;
+        return (!TextUtils.isEmpty(model) && model.toLowerCase().contains(ROM_COOLPAD))
+                || (!TextUtils.isEmpty(fingerPrint) && fingerPrint.toLowerCase().contains(ROM_COOLPAD));
+    }
+
+    public static boolean isZTERom() {
+        String manufacturer = Build.MANUFACTURER;
+        String fingerPrint = Build.FINGERPRINT;
+        return (!TextUtils.isEmpty(manufacturer) && (fingerPrint.toLowerCase().contains(ROM_NUBIA)
+                || fingerPrint.toLowerCase().contains(ROM_ZTE)))
+                || (!TextUtils.isEmpty(fingerPrint) && (fingerPrint.toLowerCase().contains(ROM_NUBIA)
+                || fingerPrint.toLowerCase().contains(ROM_ZTE)));
+    }
+
+    public static boolean isDomesticSpecialRom() {
+        return RomUtil.isMiuiRom()
+                || RomUtil.isHuaweiRom()
+                || RomUtil.isMeizuRom()
+                || RomUtil.is360Rom()
+                || RomUtil.isOppoRom()
+                || RomUtil.isVivoRom()
+                || RomUtil.isLetvRom()
+                || RomUtil.isZTERom()
+                || RomUtil.isLenovoRom()
+                || RomUtil.isCoolPadRom();
+    }
+
+    public static boolean isSmartisanR1() {
+        return Build.MODEL.contains("DE106");
+    }
+
+    public static boolean isVivoX21() {
+        return Build.MODEL.contains("vivo X21");
+    }
+
+    public static boolean isVivoX21S() {
+        return Build.MODEL.contains("V1814");
+    }
+
+    public static boolean isVivoX23() {
+        //X23普通 幻彩版
+        return Build.MODEL.contains("V1809") || Build.MODEL.contains("V1816");
+    }
+
+    public static boolean isVivoZ1() {
+        return Build.MODEL.contains("V1730");
+    }
+
+    public static boolean isVivoZ3() {
+        return Build.MODEL.contains("V1813BA");
+    }
+
+    public static boolean isVivoY81s() {
+        return Build.MODEL.contains("V1732");
+    }
+
+    public static boolean isVivoY83() {
+        return Build.MODEL.contains("Y83");
+    }
+
+    public static boolean isVivoY85() {
+        return Build.MODEL.contains("vivo Y85");
+    }
+
+    public static boolean isVivoY93() {
+        return Build.MODEL.contains("V1818");
+    }
+
+    public static boolean isVivoY97() {
+        return Build.MODEL.contains("V1813A") || Build.MODEL.contains("V1813T");
+    }
+
+    public static boolean isHonorV10() {
+        return Build.MODEL.contains("BKL-AL00");
+    }
+
+    public static boolean isHonor10() {
+        return Build.MODEL.contains("COL-AL10");
+    }
+
+    public static boolean isMiPad4() {
+        return TextUtils.equals(Build.MODEL, "MI PAD 4");
+    }
+}