鸿蒙 给大家分享点鸿蒙小知识

哲豪 · 2022年04月26日 · 最后由 陈恒捷 回复于 2022年04月28日 · 4229 次阅读

咱别的先不说,先上个小工具,功能不多但大家可以自行扩展。(主要暂时需要用到的就这些😉
需要 ohos.jar,可以鸿蒙 SDK 中找到。
在 AndroidManifest.xml 添加

<uses-permission android:name="ohos.permission.GET_BUNDLE_INFO" />
import android.content.Context;
import android.text.TextUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;

import ohos.bundle.AbilityInfo;
import ohos.bundle.BundleInfo;
import ohos.bundle.HapModuleInfo;
import ohos.bundle.IBundleManager;

public class HarmonyUtils {
    /**
     * 是否为鸿蒙系统
     *
     * @return true为鸿蒙系统
     */
    public static boolean isHarmonyOs() {
        try {
            Class<?> buildExClass = Class.forName("com.huawei.system.BuildEx");
            Object osBrand = buildExClass.getMethod("getOsBrand").invoke(buildExClass);
            return "Harmony".equalsIgnoreCase(osBrand != null ? osBrand.toString() : null);
        } catch (Throwable x) {
            return false;
        }
    }

    /**
     * 获取鸿蒙系统版本号
     *
     * @return 版本号
     */
    public static String getHarmonyVersion() {
        return getProp("hw_sc.build.platform.version");
    }

    /**
     * 获得鸿蒙系统版本号(含小版本号)
     *
     * @return 版本号
     */
    public static String getHarmonyDisplayVersion() {
        return getProp("ro.huawei.build.display.id");
    }

    /**
     * 获取属性
     *
     * @param property
     * @return
     */
    private static String getProp(String property) {
        String value = "";
        try {
            Class spClz = Class.forName("android.os.SystemProperties");
            Method method = spClz.getDeclaredMethod("get", String.class);
            value = (String) method.invoke(spClz, property);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return value;
    }

    /**
     * 获取鸿蒙应用的mainAbility(这边踩了很多坑)
     *
     * @param context
     * @param bundleName 应用包名
     * @return mainAbility
     */
    public static String getHarmonyMainAbility(Context context, String bundleName) {
        String mainAbility = null;
        Context mContext = context.getApplicationContext();

        ClassLoader classLoader = mContext.getClassLoader();
        try {
            Class ohosApplication = Class.forName("ohos.app.Application");
            Object mOhosApplication = ohosApplication.newInstance();

            Class contextDeal = Class.forName("ohos.app.ContextDeal");
            Constructor contextDealConstructor = contextDeal.getConstructor(Context.class, ClassLoader.class);
            Object mContextDeal = contextDealConstructor.newInstance(mContext, classLoader);

            Method setApplication;
            try {
                setApplication = contextDeal.getDeclaredMethod("setApplication", ohosApplication);
            } catch (NoSuchMethodException e) {
                // 在一些手机上 "setApplication" 方法名打印后发现变成了 "O000000"
                // 或许是有其他原因,暂时先用这个办法解决
                setApplication = contextDeal.getDeclaredMethod("O000000", ohosApplication);
            }
            setApplication.invoke(mContextDeal, mOhosApplication);

            Method attachBaseContext = ohosApplication.getMethod("attachBaseContext", ohos.app.Context.class);
            attachBaseContext.invoke(mOhosApplication, mContextDeal);

            Method getApplicationContext = ohosApplication.getMethod("getApplicationContext");
            ohos.app.Context hContext = (ohos.app.Context) getApplicationContext.invoke(mOhosApplication);
            // 到此获取到 hContext ,就能调用到ohos里面的一些方法了,有需要可以自行扩展
            IBundleManager iBundleManager = hContext.getBundleManager();

            BundleInfo bundleInfo = iBundleManager.getBundleInfo(bundleName, 0);
            if (bundleInfo != null) {
                Method getHapModuleInfo = bundleInfo.getClass().getMethod("getHapModuleInfo", String.class);
                HapModuleInfo moduleInfo = null;
                if (!TextUtils.isEmpty(bundleInfo.getEntryModuleName())) {
                    moduleInfo = (HapModuleInfo) getHapModuleInfo.invoke(bundleInfo, bundleInfo.getEntryModuleName());
                } else {
                    for (String moduleName : bundleInfo.getModuleNames()) {
                        moduleInfo = (HapModuleInfo) getHapModuleInfo.invoke(bundleInfo, moduleName);
                        break;
                    }
                }

                if (moduleInfo != null) {
                    if (!TextUtils.isEmpty(moduleInfo.getMainAbility().getClassName())) {
                        mainAbility = moduleInfo.getMainAbility().getClassName();
                    } else {
                        List<AbilityInfo> abilityInfoList = moduleInfo.getAbilityInfos();
                        if (abilityInfoList.size() > 0) {
                            mainAbility = abilityInfoList.get(0).getClassName();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mainAbility;
    }
}

最近因为客户那边有了测试鸿蒙原生包的需求,便开始着手开发功能(开发过程可谓曲折,就不吐槽了。PS:主要太多要吐槽了😤 )。

鸿蒙原生包是.hap 后缀,有个专门的 hdc 命令,但和 adb 是一样的。 hdc 能实现的也可以用 adb 去实现,所以并不需要特地的下载和编译它(这边已经踩过坑了)。

例如:adb 如何安装.hap 包

通常 adb 的两种安装命令:

adb install xxx.apk
adb shell pm install xxx.apk

还有种方式是先 push 到手机中然后手动点安装。

到这时或许有人会说 “我都试过了,并不行!”

没错,我上面说的是 “通常”。那么应该用什么命令来安装呢,看下面这条命令:

adb shell bm install xxx.hap

这个命令大家可能不常用到,甚至可能都没用过吧, hdc 也是用的这个命令。

想了解更多的可以执行这个命令,里面包含了查询手机上的鸿蒙应用列表、判断是否是鸿蒙应用等。

adb shell bm -h

包括鸿蒙应用的启动也是一样可以用 adb 启动,下面给大家介绍两种方式

adb shell aa start -p "com.sina.weibo.harmonyos" -n "com.sina.weibo.entry.splash.SplashPageAbility" -a action

adb shell am start -n com.sina.weibo.harmonyos/com.sina.weibo.entry.splash.SplashPageAbilityShellActivity

两种方式大家有看到启动类名有什么不一样的吗?对咯,就是下面一条命令的启动类名多了 ShellActivity。因为每一个 Ability 都会生成对应的 ShellActivity,所以我们在使用 am start 启动时需要拼接上 ShellActivity。

至于启动类怎么获取上面的 Util 里有方法,直接调用即可。

就先到这吧,流水文章 大家多担待。

共收到 1 条回复 时间 点赞

收藏了,后面如果需要弄鸿蒙原生包的时候用得上。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册