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
      });
    },
相关推荐
遇到困难睡大觉哈哈1 小时前
Harmony os 卡片传递消息给应用(message 事件)详细介绍
java·服务器·javascript·harmonyos·鸿蒙
周倦岚1 小时前
【HarmonyOS】用户通知服务
华为·harmonyos
晚霞的不甘1 小时前
开源鸿蒙(OpenHarmony)实战入门:从 Hello World 到 UI 交互设计
ui·开源·harmonyos
2501_916007472 小时前
苹果应用商店上架的系统逻辑,从产品开发到使用 开心上架 上架IPA 交付审核流程
android·ios·小程序·https·uni-app·iphone·webview
不羁的木木2 小时前
【开源鸿蒙跨平台开发学习笔记】Day06:React Native 在 OpenHarmony 开发中的自定义组件开发
笔记·学习·harmonyos
IT 前端 张2 小时前
Uni-app 实现全局无操作监听:自动退出弹窗倒计时功能
运维·服务器·uni-app
一只月月鸟呀2 小时前
使用node和@abandonware/bleno写一个ble模拟设备,用Uni-app模拟终端连接
uni-app
SuperHeroWu72 小时前
鸿蒙应用如何实现内存级别全局缓存数据?
华为·harmonyos·单例·lrucache·appstroage·内存缓存
初遇你时动了情2 小时前
vue3 ts uniapp基本组件封装、通用组件库myCompont、瀑布流组件、城市选择组件、自定义导航栏、自定义底部菜单组件等
typescript·uni-app·vue3