Uni-App 鸿蒙应用微信相关功能上架踩坑:自制微信安装检测插件

背景:上架失败的痛点

做 Uni-App 跨端开发时,鸿蒙应用上架遇到了一个棘手问题:应用集成了微信登录、支付、分享等核心功能,但上架平台的测试机未安装微信,导致这些功能触发时直接崩溃,最终上架失败。

翻遍了 Uni-App 官方文档、鸿蒙开发者社区,甚至各类技术论坛,都没找到现成的「鸿蒙平台检测微信是否安装」的解决方案 ------ 毕竟 Uni-App 对鸿蒙的适配还在持续完善中,很多原生能力的跨端封装还未覆盖到。

无奈之下,只能自己摸索鸿蒙原生能力与 Uni-App 的桥接方式,最终实现了一个轻量的检测插件,完美解决了上架问题。今天把这个过程分享出来,希望能帮到有同样需求的开发者~

核心思路

Uni-App 调用鸿蒙原生能力,本质是通过「Uni-App 插件 + 鸿蒙原生代码」的方式实现桥接:

  1. 鸿蒙原生层:通过鸿蒙的包管理能力,查询设备是否安装了微信(微信包名:com.tencent.mm
  2. 插件层:将原生查询结果封装成 Uni-App 可调用的 API
  3. 应用层:在调用微信登录 / 支付 / 分享前,先通过插件检测是否安装微信,避免崩溃

插件实现步骤(附完整代码)

一、创建 Uni-App 插件结构

首先通过 HBuilder X 在 Uni-App 项目中右键 uni_modules,新建 UTS插件-API插件,标准结构如下:

二、编写鸿蒙原生检测逻辑

1. 路径 uni_modules=>hl-appcheckplugin=>utssdk=>interface.uts

js 复制代码
/**
 * 内部结果类型(避免对象字面量作为类型)
 */
export interface CheckResult {
  isInstalled: boolean;
  errMsg: string;
}

/**
 * 检查微信安装状态的入参配置
 */
export interface CheckWeChatInstalledOptions {
  /** 检查成功回调(仅当已安装时触发) */
  success?: (result: CheckWeChatInstalledSuccess) => void;
  /** 检查失败回调(未安装或检查出错时触发) */
  fail?: (result: CheckWeChatInstalledFail) => void;
  /** 检查完成回调(无论成败) */
  complete?: (result: CheckWeChatInstalledComplete) => void;
}

/**
 * 成功回调结果类型
 */
export interface CheckWeChatInstalledSuccess {
  isInstalled: true;
  errMsg: "ok"; // 严格字面量类型,避免 string 不匹配
}

/**
 * 失败回调结果类型
 */
export interface CheckWeChatInstalledFail {
  isInstalled: false;
  errMsg: string; // 错误信息描述
}

/**
 * 完成回调结果类型
 */
export interface CheckWeChatInstalledComplete {
  isInstalled: boolean;
  errMsg: string;
}

2. 路径 uni_modules=>hl-appcheckplugin=>utssdk=>app-harmony=>index.uts

js 复制代码
import {
	CheckWeChatInstalledOptions,
	CheckWeChatInstalledSuccess,
	CheckWeChatInstalledFail,
	CheckWeChatInstalledComplete,
	CheckResult
} from '../interface.uts'

// 重新导出类型,供外部使用
export type {
	CheckWeChatInstalledOptions,
	CheckWeChatInstalledSuccess,
	CheckWeChatInstalledFail,
	CheckWeChatInstalledComplete,
	CheckResult
}

import { bundleManager } from '@kit.AbilityKit';
import hilog from '@ohos.hilog';
import { BusinessError } from '@kit.BasicServicesKit';

/**
 * 常量定义(使用大写+下划线命名规范)
 */
export const WECHAT_BUNDLE_NAME = 'com.tencent.mm'; // 微信官方包名(Android/鸿蒙通用)
const LOG_TAG = 'HL_APPCHECK'; // 日志标签常量
const LOG_DOMAIN = 0x0000; // 日志域常量

/**
 * 检查设备是否安装微信(优化版)
 * @param options 配置参数(包含成功、失败、完成回调)
 * @returns Promise<CheckResult> 异步返回检查结果(支持 Promise 链式调用)
 */
export async function checkWeChatInstalled(
	options : CheckWeChatInstalledOptions = {} // 给参数设置默认值,避免 undefined 报错
) : Promise<CheckResult> {
	// 初始化默认结果
	let result : CheckResult = {
		isInstalled: false,
		errMsg: '检查中...'
	};

	try {
		// 检查微信是否安装
		const isInstalled = await isAppInstalled(WECHAT_BUNDLE_NAME);

		if (isInstalled) {
			// 微信已安装 - 构造成功结果
			result = {
				isInstalled: true,
				errMsg: 'ok'
			};
			// 调用成功回调(类型安全转换)
			options.success?.(result as CheckWeChatInstalledSuccess);
			hilog.info(LOG_DOMAIN, LOG_TAG, '微信已安装');
		} else {
			// 微信未安装 - 构造失败结果
			result = {
				isInstalled: false,
				errMsg: '微信未安装'
			};
			// 调用失败回调(类型安全转换)
			options.fail?.(result as CheckWeChatInstalledFail);
			hilog.info(LOG_DOMAIN, LOG_TAG, '微信未安装');
		}

	} catch (err) {
		// 异常处理
		const error = err as BusinessError | Error;
		const errorCode = 'code' in error ? error.code : 'unknown';
		const errorMsg = error.message || `检查失败(错误码:${errorCode})`;

		// 构造错误结果
		result = {
			isInstalled: false,
			errMsg: errorMsg
		};

		// 调用失败回调
		options.fail?.(result as CheckWeChatInstalledFail);
		// 错误日志增强
		hilog.error(LOG_DOMAIN, LOG_TAG, `检查微信安装状态失败:${errorMsg},错误码:${errorCode}`);

	} finally {
		// 调用完成回调
		options.complete?.(result as CheckWeChatInstalledComplete);
		hilog.info(LOG_DOMAIN, LOG_TAG, `检查微信安装状态完成:${JSON.stringify(result)}`);
	}

	// 返回 Promise 结果,支持 async/await 调用
	return result;
}

/**
 * 检查指定包名的应用是否已安装)
 * @param bundleName 应用包名
 * @returns Promise<boolean> 是否已安装
 */
async function isAppInstalled(bundleName : string) : Promise<boolean> {
	try {
		// 获取应用信息
		await bundleManager.getBundleInfo(
			bundleName,
			bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT
		);
		return true;
	} catch (err) {
		return false;
	}
}

三、Uni-App 中使用插件

1. 调用检测方法

在需要使用微信功能的页面(如登录页、支付页),先调用检测方法:

js 复制代码
    import { checkWeChatInstalled } from "@/uni_modules/hl-appcheckplugin"

    checkApp() {
      // 统一返回 Promise,确保所有端行为一致
      return new Promise((resolve) => {
        // #ifdef APP-PLUS
        const isExist = plus.runtime.isApplicationExist({
          pname: 'com.tencent.mm',
          action: 'weixin://'
        });
        resolve(isExist);
        // #endif

        // #ifdef APP-HARMONY
        checkWeChatInstalled({
          success: () => {
            console.log('微信已安装');
            resolve(true);
          },
          fail: (err) => {
            console.log('微信未安装或检测失败', err);
            resolve(false);
          }
        });
        // #endif

        // #ifdef MP-WEIXIN
        resolve(true);
        // #endif
      });
    },
相关推荐
梧桐ty19 小时前
鸿蒙应用冷启动优化:Flutter首屏秒开与白屏治理实战
flutter·华为·harmonyos
梧桐ty19 小时前
驾驭未来:基于鸿蒙的Flutter车载应用与手机端协同实战
flutter·华为·harmonyos
FrameNotWork21 小时前
HarmonyOS 教学实战(五):路由、页面生命周期与多页面架构
华为·架构·harmonyos
云和数据.ChenGuang1 天前
鸿蒙电视的核心技术
华为·harmonyos·数据库运维工程师·运维教程
AirDroid_cn1 天前
鸿蒙NEXT:升级系统时提示 “存储空间不足” 如何解决?
华为·harmonyos
盐焗西兰花1 天前
鸿蒙学习实战之路-数据持久化键值型数据库KV-Store全攻略
数据库·学习·harmonyos
磊少工作室_CTO1 天前
鸿蒙Next —— 状态管理实践
harmonyos·mvvm·客户端
御承扬1 天前
鸿蒙原生系列之动画效果(转场动画)
华为·harmonyos·转场动画
子榆.1 天前
Flutter 与开源鸿蒙(OpenHarmony)深度集成实战:从零构建跨平台应用
flutter·开源·harmonyos
luxy20041 天前
HarmonyOS 5.0 WiFi连接调试工具
华为·harmonyos