Android Rom 识别的几种方法

最近公司 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的系统版本也一起发给我,方便查找。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 有时候需要判断手机系统的ROM,检测ROM是MIUI、EMUI还是Flyme,可以使用getprop命令,去系统b...
    夏末m阅读 19,918评论 3 33
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,462评论 25 707
  • 在家就是舒服了?我也有可能成为下一步都会在一起就会被你发现自己有什么区别呃呃呃呃呃呃 你们在哪里?我在外面的人是谁...
    qiunili阅读 140评论 0 0
  • 1. “嘿!阿黄,我今天的妆好看吗?”我把脸凑过去。 “汪!”它看着我往后退了几步。 “那,你看我今天穿的裙子好看...
    亲亲亲亲阅读 996评论 2 5
  • 类和对象 定义类 类和对象(object,也被称为实例,instance),类是抽象的,用来模拟现实事物,可理解为...
    panda_Hi阅读 326评论 0 0