「椎锋陷陈」微信技术号现已开通,为了获得第一手的技术文章推送,欢迎搜索关注!

前言

不久前,HarmonyOS 2.0的正式发布,在华为用户及科技产品爱好者之间掀起了不小的波澜。其中,讨论关于HarmonyOS是如何兼容Android应用的话题最为频繁,从而引发了多方阵营关于「HarmonyOS究竟是否是套壳Android」的激烈争论。

与此同时,部分嗅到风向的开发者,已经在部署如何收集应用在HarmonyOS上的兼容情况了。这不,笔者所在的公司就安排我去进行相关的技术调研。其中,最重要的一点就是判断当前应用是否搭载在了HarmonyOS上,从而统计升级HarmonyOS的用户数量,作为后续公司战略方向可能调整的依据。

OpenHarmony与HarmonyOS

首先,让我们先为前面的争论下一个明确的定论,即:

HarmonyOS并非套壳Android。

我们通常意义上所讲的HarmonyOS,实际分成了两部分,一部分是 OpenHarmony,另一部分则是包括HMS在内的闭源应用与服务。

OpenHarmony是由开放原子开源基金会孵化及运营的开源项目,其性质与定位可参照Android开放源代码项目(AOSP) 。

而HarmonyOS 2.0则是华为基于OpenHarmony 2.0开发的面向多种全场景智能设备的商用版本。HarmonyOS 2.0遵循了AOSP的开源许可,从而实现了现有Android生态应用在部分搭载HarmonyOS 2.0的设备上的正常运行。

目前在HarmonyOS 2.0上存在两种类型的应用,即

  • 纯HarmonyOS应用(指基于HarmonyOS开发的应用,不能安装在其他Android手机上,应用体积很小,但同时功能也很少)
  • 支持HarmonyOS特性的应用(基于Android开发的应用,但是使用了 HarmonyOS的特性,通过工具导出时后缀仍然是APK)

HarmonyOS检测方法

现在回到我们最初的需求,即基于Android开发的应用,该如何判断是否是搭载在了HarmonyOS上呢?

对于这个问题的我的第一个解决思路就是:

通过读取Android系统配置,遍历能够作为判断依据的属性

Android系统配置介绍

为了让所有运行中的进程共享系统运行时所需要的各种属性值,Android系统开辟了属性存储区域,并提供了访问该区域的API。属性由键(key)与值(value)构成,两者都是字符串类型。

属性被大量使用在Android系统中,用来记录系统设置或进程之间的信息交换。属性是在整个系统中全局可见的。每个进程可以get/set属性。

我们可以通过以下两种方式访问到系统配置中的属性值:

adb命令行工具

  • adb shell getprop 可以查看手机上所有属性值。
  • abb shell getprop xxx 可以查看某个指定属性值。

SystemProperties类

Systemproperties类在android.os目录下,但这个类是被标记为隐藏的,上层应用开发无法直接使用,但我们可以用反射的方式调用。创建/修改属性可以用Systemproperties.set(property,value)方法,获取属性则可以用Systemproperties.get(property)方法。

比如,我们可以通过此方式获取设置-关于手机中显示的版本号:

/*** 获取鸿蒙系统版本号*/
fun getHarmonyOsVersion(): String {return if (isHuaweiBrand() && isHarmonyOs()) {try {val cls = Class.forName("android.os.SystemProperties")val method = cls.getMethod("get", String::class.java)method.invoke(cls, "ro.huawei.build.display.id") as String} catch (e: Exception) {"-1"}} else {"-1"}
}

当然,这个版本号可以用一种更直接的方式获取:

/*** 获取鸿蒙系统版本号*/
fun getHarmonyOsVersion(): String {return if (isHuaweiBrand() && isHarmonyOs()) {Build.DISPLAY} else {"-1"}
}

通过阅读源码我们可以得知,其真正的实现也是通过调用SystemProperties.get(property)进行的,底层通过jni调用native方法实现属性的存取:

    public static final String DISPLAY = getString("ro.build.display.id");private static String getString(String property) {return SystemProperties.get(property, UNKNOWN);}public static String get(@NonNull String key, @Nullable String def) {if (TRACK_KEY_ACCESS) onKeyAccess(key);return native_get(key, def);}

但是很遗憾,遍历了所有的属性值之后,发现跟OS相关的属性值仍是关联到Android系统的,唯一出现Harmony字样的,是一个默认来电铃声的属性值:

所以,想要以此方案作为判断依据,我们需要通过读取默认来电铃声属性值并判断是否以Harmony结尾,但由于目前我手头上只有一台升级到HarmonyOS 2.0的手机,无法确保在其他机型的手机上该属性值也一致,因此只能将此方案作为保留方案。

另外一个解决思路则是:

通过是否支持调用HarmonyOS Java API来判断

至于调用方式,和你猜想的一样,依然是以反射的形式,看看能否在运行时获取相关API的类的Class对象。

在HarmonyOS开发者官网上可以看到,最新发布的HarmonyOS SDK Release版的版本号是2.1.1.21,API版本为5(截至2021.6.22)。

而在HarmonyOS Java API文档中通过Since来标记包、类或接口等开始支持的版本号,如“Since:1”表示从API Version 1开始支持。

于是我们选择最新的API版本为5的类来作为试验对象:

具体代码也很简单,使用Class类的forName静态方法,以完整类名为参数获取Class对象,如果Class对象不为空,即可证明当前应用搭载在了HarmonyOS上:

/*** 当前是否是鸿蒙系统* 根据是否能调用Harmony JAVA API判断*/
fun isHarmonyOs(): Boolean {return try {val cls = Class.forName("ohos.utils.system.SystemCapability")cls != null} catch (e: Exception) {false}
}

一点小疑惑

我为什么要选择API版本为5的类来判断呢?这是因为,通过是否支持调用HarmonyOS Java API来判断应用搭载在HarmonyOS的设备上这种思路,其实我一开始就想到了,但我最初是选用了HarmonyOS开发者官网第一个介绍的特性——Ability相关的类,而该类的API版本为1。

测试发现,升级了HarmonyOS和未升级的手机上居然都能够获取到Ability的Class对象!!!

百思不得其解的我,直到在查阅了HarmonyOS的历史版本说明后才注意到以下这一句:

于是进一步在HarmonyOS开发者的官方公众号上确认,得到了以下回复:

因此证明,通过是否支持调用HarmonyOS Java API来判断应用搭载在HarmonyOS的设备上这种思路是正确的,但要选用API版本为5的类才可以。

但是另外一个疑惑又产生了,即未升级HarmonyOS的手机为什么也能调用API版本低于5以下的HarmonyOS Java API呢?难道HarmonyOS的一部分特性相关的库早就在现有华为手机的EMUI上部署了吗?此问题目前还得不到合理的解释。

总结

为了减少用户的迁移成本,保护用户的现有数据,现阶段的HarmonyOS选择了在遵循AOSP的开源许可基础上兼容Android生态应用。

也是由于这一点,加上华为开发者官网上并没有明确给出API,导致基于Android开发的应用,要判断是否搭载在HarmonyOS上会比较迂回。

目前比较可靠的方式,是通过是否支持调用HarmonyOS Java API来判断,并且必须选择API版本为5的类。

如果你有更好的方式,欢迎在文章下方留言告诉我,谢谢~

「椎锋陷陈」微信技术号现已开通,为了获得第一手的技术文章推送,欢迎搜索关注!

参考

OpenHarmony和HarmonyOS有什么区别?
https://developer.huawei.com/consumer/cn/forum/topic/0202596835671930522?fid=0101303901040230869

HarmonyOS Java API参考
https://developer.harmonyos.com/cn/docs/documentation/doc-references/systemversion-0000001054358980#ZH-CN_TOPIC_0000001054358980__getReleaseType–

Android 系统属性SystemProperty分析
https://blog.csdn.net/yangwen123/article/details/8936555

如何判断Android应用运行在鸿蒙系统上相关推荐

  1. 鸿蒙os能运行win软件吗,暂无在Windows、Linux、Android下运行华为鸿蒙OS的模拟器

    在网络上有人开发出了Flmage,用它可以模拟运行谷歌的Fuchsia OS,然后有人想是不是也有同样的工具能够运行华为鸿蒙OS(HarmonyOS).可惜的是,在Windows.Linux.Andr ...

  2. 厉害了!Flutter 在鸿蒙系统上跑起来了

    点击"开发者技术前线",选择"星标????" 让一部分开发者看到未来 来自:美团技术团队 前言 鸿蒙系统 (HarmonyOS)是华为推出的一款面向未来.面向全 ...

  3. 鸿蒙系统是单任务还是多任务,在鸿蒙系统上使用MQTT编程

    我们使用的是paho mqtt软件包,这里介绍一下怎么使用mqtt协议编程.关于鸿蒙系统的mqtt移植好的软件包,相关github链接如下: https://gitee.com/qidiyun/har ...

  4. 【FFH】如何在鸿蒙系统上进行抓包测试

    [FFH]如何在鸿蒙系统上进行抓包测试 前言 什么是抓包? Charles工具介绍 Charles代理配置 Charles访问配置 鸿蒙端代理配置 抓取https数据 (一)安装SSL证书 (二)Ht ...

  5. realme支持鸿蒙系统,小米、OPPO、vivo、魅族、Realme在搭载华为鸿蒙系统上的态度...

    华为鸿蒙系统(HarmonyOS)不同于谷歌安卓系统,它是一款国产操作系统,华为已经正式表态,在2021年的目标是搭载3亿终端,2022年继续扩大对鸿蒙系统的部署.当前华为鸿蒙主要锁定六大领域,即智能 ...

  6. ios6应用运行在ios7系统上

    ios6的程序 如果跑在ios7系统中.界面什么的有可能会变形,最简单的办法就是直接用ios6的sdk来编译程序,所以只要在把ios6.x的sdk放在xcode5下,看下图 ,重新打开xcode5,打 ...

  7. android studio无法连接鸿蒙系统手机

    数据线连接手机和电脑,打开手机开发者模式以及进行USB调试开关情况下,在终端输入命令adb devices,显示List of devices attached没有连上手机,解决办法真的离谱. 在电脑 ...

  8. [android] app运行在夜神模拟器上

    此测试是在android studio上演示的,如要使用android studio请到http://pan.baidu.com/s/1o6KPdRs下载. 一.首先要去夜神官网(http://www ...

  9. android studio 运行闪退,ubuntu上在androidstudio中启动emulator闪退的解决方法

    阅读目录(Content) 平台 现象 解决 一.查看模拟器的信息 二.命令行运行模拟器 平台 Ubuntu14.04 64 现象 在AndrodStudio中点击模拟器的启动按钮后,模拟器界面弹出后 ...

最新文章

  1. 用两种方法判断男性女性的存储过程
  2. 设计模式的六大原则(个人笔记)
  3. 计划策略-25-具有配置的订货型生产
  4. Python中文处理(转)
  5. 推荐 | 方便好用的浏览器插件
  6. LeetCode 637 二叉树的层平均值-简单
  7. 还有哪些类似0.99999…=1有趣的事实?
  8. 树(5)-----判断两颗树一样或者一棵树是否是另外一颗的子树
  9. 宝塔面板连接阿里云服务器、及部署网页项目教程
  10. 想成功创业,你首先要有这样的思维
  11. Arcgis desktop 9.3的破解方法(转载GIS帝国)
  12. 镁光闪存颗粒对照表_最全的内存颗粒编码规则说明,教你看穿内存条到底用的什么颗粒...
  13. CF838D Airplane Arrangements
  14. Android反编译工具绿色版V2.0(改进版)
  15. android顶部导航高度,快速实现顶端导航栏(ToolBar+TabLayout+Viewpager)
  16. 5、Horizon 桌面模板机安装配置
  17. C++ sort 排序函数使用方法
  18. Maperitive地图瓦片切割部分使用方法总结
  19. OPENXML的用法
  20. 单元测试基础上篇——几大常用框架对比

热门文章

  1. pe本地计算机策略,Win10怎么设置PIN码|本地组策略编辑器设置PIN复杂性方法
  2. blend界面右侧 大纲视图和属性窗口不见了?
  3. java do对象_java一些对象概念扫盲帖(DO VO DTO PO)
  4. 网络驱动->PHY驱动调试
  5. 开箱即用!让世界最强AI成为你的生产力
  6. 微信小程序的事件处理,绝对干货
  7. 实验室仪器设备档案管理,这几点很实用
  8. abaqus轮胎建模仿真 轮胎仿真建模
  9. Listview gridview TV 焦点落在item上面修改背景色
  10. jquery获取图片并压缩上传