美文网首页安卓IT梦
Android Rom 识别的几种方法

Android Rom 识别的几种方法

作者: Walkud | 来源:发表于2018-11-16 18:35 被阅读126次

    最近公司 app 需要保活,开始研究白名单保活引导设置的时,需要用到 ROM 识别 ,顺便也查阅了相关的一些资料,了解了一些判断 ROM 的方法,在这里整理出来一起学习。

    三种判断方法

    1. 读取系统初始化配置文件,判断属性值
      • 直接读取 /system/build.prop 文件 (只支持 Android 8.0 以下)
      • 执行命令行 getprop 获取 build.prop 等文件属性
    2. 根据 ROM 定制应用列表判断
    3. 根据 Build.MANUFACTURER 判断

    build.prop 属性读取

    直接读取 build.prop 文件

    该方法读取只支持 8.0 以下,因为在 Android O (8.0)开始,对 /system/build.prop 的权限进行了限制,不再对非 root 用户开放,所以这种方法可以抛弃了。

    
    public class BuildProperties {
    
        private final Properties properties;
    
        private BuildProperties() throws IOException {
            properties = new Properties();
            properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
        }
    
        public String getProperty(final String name) {
            return properties.getProperty(name);
        }
    
    }
    
    

    优点:识别成功率高。

    缺点:只支持8.0以下。

    执行命令行 getprop 获取build.prop文件属性

    执行命令行 getprop 将读取的属性信息装载至Properties

    /**
     * Android 系统属性读取工具类
     * Created by Zhuliya on 2018/10/22
     */
    public class SystemPropertyUtil {
    
        /**
         * 使用命令方式读取系统属性
         *
         * @param propName
         * @return
         */
        public static String getSystemProperty(String propName) {
            String line;
            BufferedReader input = null;
            try {
                Process p = Runtime.getRuntime().exec("getprop " + propName);
                input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
                line = input.readLine();
                input.close();
            } catch (IOException ex) {
                RLog.e("Unable to read sysprop " + propName, ex);
                return null;
            } finally {
                if (input != null) {
                    try {
                        input.close();
                    } catch (IOException e) {
                        RLog.e("Exception while closing InputStream", e);
                    }
                }
            }
            return line;
        }
    
        /**
         * 读取系统属性,装载至Properties
         *
         * @return
         */
        public static Properties getProperty() {
            Properties properties = new Properties();
            try {
                Process p = Runtime.getRuntime().exec("getprop");
                properties.load(p.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return properties;
        }
    }
    
    

    优点:识别成功率高,支持Android 9.0 。

    缺点:前期需要收集 ROM 的专属属性。

    相关代码:RLog

    Rom 识别

    如何收集对应 ROM 的专属属性?

    adb shell
    
    cd sdcard
    getprop > xprop.txt 
    exit
    
    adb pull /sdcard/xprop.txt .
    
    

    打开 xprop.txt 文件,分析哪些属性是专属的,收集最关键的那几个。

    下面以小米为例,常量 MIUI_VERSION、MIUI_VERSION_NAME 为MIUI 系统定制的专属属性,使用此来进行判断是否为小米 ROM。

    public static final String MIUI_VERSION_NAME = "ro.build.version.incremental"; // "7.6.15"
    public static final String MIUI_VERSION = "ro.miui.ui.version.name"; // "V8"
    
    /**
         * 检查系统属性
         *
         * @param romProperties
         * @return
         */
        @Override
        public boolean checkBuildProp(RomProperties romProperties) {
            String version = romProperties.getProperty(MIUI_VERSION);
    
            return !TextUtils.isEmpty(version);
        }
    
    

    相关代码: RomProperties

    ROM 应用列表判断

    各个 ROM 厂商都会有一些定制的应用被预先植入,所以根据这些应用列表来判断 ROM 也是一个可行的方法,下面说说整体逻辑:

    1. 收集各个厂商专属的应用列表(包名)
    2. 读取系统已安装的应用列表
    3. 遍历收集的列表,判断是否已安装列表中
    4. 定一个系数,已安装的超过收集的一半后确定为对应ROM

    下面是引用的别人写好的代码片段。

    
        String[] MIUI_APPS = {
                "com.miui.home"                // 系统桌面
                , "com.miui.core"              // MIUI SDK
                , "com.miui.rom"               // com.miui.rom
                , "com.miui.system"            // com.miui.system
                , "com.xiaomi.bluetooth"       // MIUI Bluetooth
                , "com.miui.securitycenter"    // 安全中心
                , "com.miui.cloudservice"      // 小米云服务
                , "com.miui.backup"            // 备份
                , "com.android.camera"         // 相机
                , "com.miui.gallery"           // 相册
                , "com.miui.player"            // 音乐
        };
    
        @Override
        protected String[] getAppList() {
            return MIUI_APPS;
        }
    
        @Override
        public boolean checkApplication(Set<String> installedPackages) {
            int count = 0;
            String[] list = getAppList();
            int aim = (list.length + 1) / 2;
            for (String pkg : list) {
                if (installedPackages.contains(pkg)) {
                    count++;
                    if (count >= aim)
                        return true;
                }
            }
            return false;
        }
    
        public static void check(Context context) {
            List<ApplicationInfo> appInfos = context.getPackageManager().getInstalledApplications(0);
            HashSet<String> installPkgs = new HashSet<>();
            for (ApplicationInfo appInfo : appInfos) {
                installPkgs.add(appInfo.packageName);
            }
    
            boolean isMiui = checkApplication(installPkgs)
        }
    

    优点:识别限制小。

    缺点:前期收集任务会相对较大,维护成本相对较高,Root用户大量删除定制应用会降低识别成功率。

    引用的地址 Android-ROM-Identifier 有兴趣的可以了解下

    Build.MANUFACTURER 判断

    Build.MANUFACTURER 获取的是手机硬件厂商,例如小米手机 获取的就是 Xiaomi 。使用该方法判断通常情况下没什么问题,但对于一些发烧级用户来说,刷新那真是家常便饭,就会出现小米手机上运行的是非 MIUI ROM ,所以这种方法可以作为备用选择。

    
    public static final String MA_XIAOMI ="Xiaomi";
    
        /**
         * 检查手机制造商
         *
         * @return
         */
        public boolean checkManufacturer() {
            return MA_XIAOMI.equalsIgnoreCase(Build.MANUFACTURER);
        }
    
    

    优点:识别简单。

    缺点:对于刷ROM的手机会出现判断错误。

    写在最后

    看到这里已经会如果写出自己的判断工具类了,识别方法的选择:优先getprop , 应用列表判断 与Build.MANUFACTURER 判断可作为备用选择。

    由于网上大多数都是讲所有的逻辑写成在了一个工具类中,本人比较在意细节,抽离了工具类中的代码,写了一个 Android Rom 的识别库,有兴趣可以了解下,扩展相对比较灵活。

    AndroidRomChecker

    有些ROM没有适配,如果你手上正好有这对应的ROM的手机,可以执行 ROM 识别 那节的命令获取属性文件,将内容通过Issues提给我,除了属性文件的内容外,最好将设置中关于手机的ROM的系统版本也一起发给我,方便查找。

    相关文章

      网友评论

        本文标题:Android Rom 识别的几种方法

        本文链接:https://www.haomeiwen.com/subject/odfvfqtx.html