如何获取应用包及项目配置项信息
===============

#### 问题现象

开发过程中，有很多场景需要获取本应用（模块）的相关信息，如versionCode版本号，versionName版本号描述，bundleName应用包名，module.json5里面的应用配置项值，当前包的编译模式（debug还是release）等等，本文将详细分析此类情形。

#### 背景知识

*   三方应用目前只能查询到自身应用包的信息，由于安全隐私，暂时不支持查询其他应用；其中[@ohos.bundle.bundleManager](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-bundlemanager)包（即bundleManager模块）提供了应用信息查询能力，支持各类属性查询，详见[【bundleManager获取应用信息】](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-bundlemanager#bundlemanagergetbundleinfoforself)。
*   非自身应用包的信息，可以通过hdc命令进行查询。
*   HarmonyOS应用使用Hvigor进行编译构建，Hvigor会生成BuildProfile类，开发者可以通过该类在运行时获取编译构建参数，也可以在build-profile.json5中通过buildProfileFields增加自定义字段，从而在运行时获取自定义的参数；参见[【获取自定义编译参数】](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-hvigor-get-build-profile-para-guide)。

#### 解决方案

1.  命令行查询：
    *   hdc shell bm dump -a，获取设备已安装所有应用包名。
    *   hdc shell bm dump -n com.huawei.hmos.browser，获取指定应用包名的详细信息。
2.  代码中查询：
    
    此种查询方式可以获取到应用的签名证书信息，应用id，应用包名，应用版本号，访问应用程序所需的权限，应用程序的元信息，应用程序的安装目录，应用程序签名证书文件的类型（debug、release），以及应用是否为系统应用，应用是否处于调试模式，应用包的类型（应用或元服务）等等；
    

*   方式一：[bundleManager.getBundleInfo](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-bundlemanager#bundlemanagergetbundleinfo14-2)、[bundleManager.getBundleInfoSync](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-bundlemanager#bundlemanagergetbundleinfosync14-1)；
    
    由[@ohos.bundle.bundleManager](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-bundlemanager)包提供，如果有ohos.permission.GET\_BUNDLE\_INFO\_PRIVILEGED权限，可以查询其他应用包信息，否则只能查询自身应用包信息；
    
    代码使用示例：
    
    import bundleManager from '@ohos.bundle.bundleManager';
    import { BusinessError } from '@ohos.base';
    import hilog from '@ohos.hilog';
    
    @Entry
    @Component
    struct TestMain {
      build() {
        Column() {
          Button('TEST')
            .onClick(() => {
              this.test1();
            })
        }
      }
    
      test1() {
        let bundleName = 'com.dao.ooo';
        let bundleFlags =
          bundleManager.BundleFlag.GET\_BUNDLE\_INFO\_WITH\_HAP\_MODULE | bundleManager.BundleFlag.GET\_BUNDLE\_INFO\_WITH\_ABILITY;
        let userId = 100;
    
        try {
          _// 查询自身（com.dao.ooo）不需要申请权限；_
          _// 如果查询其他应用，则报错。_
          bundleManager.getBundleInfo(bundleName, bundleFlags, userId, (err, data) => {
            hilog.info(0x0000, 'testTag', 'getBundleInfoForSelf successfully. Data: %{public}s', JSON.stringify(data));
            if (err) {
              hilog.error(0x0000, 'testTag', 'getBundleInfo failed: %{public}s', err.message);
            } else {
              hilog.info(0x0000, 'testTag', 'getBundleInfo successfully: %{public}s', JSON.stringify(data));
            }
          });
        } catch (err) {
          let message = (err as BusinessError).message;
          hilog.error(0x0000, 'testTag', 'getBundleInfo failed: %{public}s', message);
        }
      }
    }    
    
*   方式二：[bundleManager.getBundleInfoForSelf](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-bundlemanager#bundlemanagergetbundleinfoforself)；
    
    由[@ohos.bundle.bundleManager](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-bundlemanager)包提供，无需申请权限，用于应用查询自身包信息，其中返回对象BundleInfo里面的属性字段，记录了应用包的各类信息[【BundleInfo相关属性值详解】](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-bundlemanager-bundleinfo)。
    
    代码使用示例：
    
    import bundleManager from '@ohos.bundle.bundleManager';
    import { BusinessError } from '@ohos.base';
    import hilog from '@ohos.hilog';
    
    @Entry
    @Component
    struct TestMain {
      build() {
        Column() {
          Button('TEST')
            .onClick(() => {
              this.test();
            })
        }
      }
    
      test() {
      _  // 入参bundleFlags指定所返回的BundleInfo中所包含的信息_
        _// 此处获取包含应用信息的bundleInfo、额外获取metadata信息，额外获取permissions信息_
        let bundleFlags2 = bundleManager.BundleFlag.GET\_BUNDLE\_INFO\_WITH\_APPLICATION |
          bundleManager.BundleFlag.GET\_BUNDLE\_INFO\_WITH\_METADATA |
          bundleManager.BundleFlag.GET\_BUNDLE\_INFO\_WITH\_REQUESTED\_PERMISSION |
          bundleManager.BundleFlag.GET\_BUNDLE\_INFO\_WITH\_SIGNATURE\_INFO;
        bundleManager.getBundleInfoForSelf(bundleFlags2).then((data) => {
          hilog.info(0x0000, 'testTag', 'getBundleInfoForSelf successfully. Data: %{public}s',
            JSON.stringify(data)
          );
        _  // 获取应用的签名证书信息_
          console.info('fingerPrint', data.signatureInfo.fingerprint);
          console.info('certificate', data.signatureInfo.certificate);
          console.info('certificate', data.signatureInfo.appId);
       _   // 应用包名，当前输出：com.dao.ooo_
          console.info('name', data.name);
         _ // 应用版本号，当前输出：1000000_
          console.info('versionCode', data.versionCode);
        _  // 应用版本号描述，当前输出：1.0.0_
          console.info('versionName', data.versionName);
    
         _ // 应用名称，当前输出：$string:app\_name_
          console.info('label', data.appInfo.label);
        _  // 访问应用程序所需的权限，当前项目输出空,未配置_
        _  // 即module.json5文件里面的requestPermissions字段对应的权限数组_
          console.info('permissions', data.appInfo.permissions);
         _ // 应用程序的元信息，当前项目输出空,未配置_
          const metadataArray = data.appInfo.metadataArray;
          console.info('metadataArray', JSON.stringify(metadataArray));
          _// 应用程序的安装目录，输出：/data/app/el1/bundle/public/com.dao.ooo_
          console.info('codePath', data.appInfo.codePath);
        _  // 应用程序签名证书文件的类型，分为debug和release两种类型。输出debug_
          console.info('appProvisionType', data.appInfo.appProvisionType);
         _ // 应用是否为系统应用，取值为true表示系统应用，取值为false表示非系统应用。当前输出false_
          console.info('systemApp', data.appInfo.systemApp);
         _ // 应用是否处于调试模式，取值为true表示应用处于调试模式，取值为false表示应用处于非调试模式。当前输出true_
          console.info('debug', data.appInfo.debug);
          _// 标识包的类型，取值为APP（应用）或者ATOMIC\_SERVICE（元服务），当前输出0_
          console.info('bundleType', data.appInfo.bundleType);
        }).catch((err: BusinessError) => {
          hilog.error(0x0000, 'testTag', 'getBundleInfoForSelf failed. Cause: %{public}s', err.message);
        });
      }
    }    
    
*   方式三：[UIAbilityContext.abilityInfo；](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-bundlemanager-abilityinfo#abilityinfo-1)
    
    代码使用示例：
    
    import hilog from '@ohos.hilog';
    import { common } from '@kit.AbilityKit';
    
    @Entry
    @Component
    struct TestMain {
      build() {
        Column() {
          Button('TEST')
            .onClick(() => {
              this.test2();
            })
        }
      }
    
      test2() {
        let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
        hilog.info(0x0000, 'testTag', 'context.abilityInfo successfully. Data: %{public}s', JSON.stringify(context.abilityInfo));
       _ // eg：获取应用包名，输出：com.dao.ooo_
        console.info(\`bundleName: ${context.abilityInfo.bundleName}\`);
      }
    }
    
*   方式四：借助Hvigor编译构建生成的配置文件【BuildProfile.ets】动态获取（此种方式前提：项目构建成功，BuildProfile.ets文件正常生成）；
    
    此种方式可以获取应用包名即Bundle名称、Bundle类型，应用版本号，Product名称，Target名称，编译模式（debug还是release），是否可调试等；
    
    *   已有的系统构建参数查询：
        
        针对hap、hsp包，BuildProfile文件中自动生成系统默认参数有：应用包名即Bundle名称、Bundle类型，应用版本号，Product名称，Target名称，编译模式（debug还是release），是否可调试等；
        
        针对har包，BuildProfile文件中自动生成系统默认参数有：har版本号、编译模式、应用是否可调试、目标名称等；
        
    *   自定义构建参数查询：
        
        如果开发者需要的包信息或者构建信息，在上述方式中都取不到，可以自定义在模块级、工程级的build-profile.json5文件中，构建完成后这些自定义参数会生成到对应的BuildProfile文件中，导出后代码里面即可直接获取；
        
        其中Hvigor编译构建生成的BuildProfile类文件如图：![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/52/v3/yyPA2jsGRRO78c258Jp5YA/zh-cn_image_0000002658990785.png?HW-CC-KV=V1&HW-CC-Date=20260709T133824Z&HW-CC-Expire=86400&HW-CC-Sign=0C8320988E92C4010A25E6F321B7B55ADB54EA188E0D42FC0CD845C6715859BD "点击放大")
        
    
    对于自定义构建参数，详细调用示例：[动态获取自定义构建参数](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-hvigor-get-build-profile-para-sample)。
    

#### 常见FAQ

Q：系统未放开包名查询权限，如何获取设备上已安装的应用信息？

A：目前不允许查询设备应用列表数据，无法申请相关权限。

Q：build-profile.json5中的buildProfileFields自定义字段的优先级是怎样？

A：模块级targets-》模块级buildOptionSet-》模块级buildOption-》工程级products-》工程级buildModeSet。