必须用uni.requireNativePlugin动态加载,否则无法调用;返回undefined主因是路径/命名未对齐(nativeplugins目录名、插件子目录名、package.json的name、JS中传入名四者须完全一致且区分大小写)或原生未注册成功(Android需.aar直放android/下、iOS需.framework放ios/下、package.json不可缺、manifest.json中app-plus→usingComponents须为true),且须平台判断与空值校验。

uni-app 无法直接调用原生插件实现硬件控制——必须通过 uni.requireNativePlugin 动态加载,且插件本身必须已正确注册、权限已申请、平台已校验,否则调用即失效。
为什么 uni.requireNativePlugin('xxx') 总是返回 undefined
这不是 JS 报错,而是原生插件根本没被识别。核心就两点:路径/命名没对齐,或 Android/iOS 侧压根没注册成功。
-
nativeplugins目录必须手动建在项目根目录下,名称大小写一个字母都不能错(不能是NativePlugins或native-plugins) - 插件子目录名(如
nativeplugins/nfc-reader/)、package.json中的"name"字段、JS 中传给uni.requireNativePlugin()的字符串,三者必须完全一致且区分大小写 - Android 插件的
.aar必须直放android/子目录下(不是android/libs/),iOS 的.framework或源码必须放ios/下 -
package.json不可缺失,且必须放在插件子目录根下;其中_dp_nativeplugin.android.plugins[0].class要写完整 Java 类路径(如com.example.nfc.NfcModule),少一个点或大小写错,运行时报NoClassDefFoundError -
manifest.json中app-plus → usingComponents必须为true,否则整个原生插件系统被禁用
调用前必须做平台判断与空值校验
uni.requireNativePlugin 在 H5、小程序等非 App 平台永远返回 undefined,且不抛错——try/catch 捕获不到。
- 先用
uni.getSystemInfoSync().platform === 'app-plus'做运行时判断,非 App 环境直接跳过调用逻辑 -
uni.requireNativePlugin()返回的是普通对象,不是 Promise,不支持await - 首次调用可能返回
null(插件加载有延迟),必须加空值校验:if (!nfcPlugin) { uni.showToast({ title: '插件未就绪', icon: 'none' }); return; } - 建议把插件实例挂到
globalThis.nfcPlugin或Vue.prototype.$nfc上复用,避免重复调用
硬件控制类插件必须手动处理运行时权限
manifest.json 里勾选“NFC”或“蓝牙”只是声明权限,真机上不等于能用。插件内部若需访问硬件,必须走运行时流程。
- Android:必须调用
uni.authorize({ scope: 'scope.nfc' })(NFC)或scope.bluetooth(蓝牙),且要在确认platform后再请求;部分厂商(华为、小米)还需额外处理后台白名单 - iOS:除了
manifest.json,Xcode 工程的Info.plist必须手动添加NFCTagReaderUsageDescription(NFC)或NSBluetoothAlwaysUsageDescription(蓝牙),值为用户可见的用途说明 - 权限拒绝后,再次调用
uni.authorize不会弹窗,需引导用户去系统设置中手动开启 - 某些硬件(如 NFC)还依赖系统服务状态,调用前应先检查:
nfcPlugin.isAvailable()或类似接口(由插件暴露)
插件调用失败时怎么快速定位问题
别只看 HBuilderX 插件管理页显示“已安装”。真正验证方式只有两个:
- 在 App 端运行时,打开 Android Studio 的 Logcat,筛选关键词
UniPlugin或插件类名(如NfcModule),看是否有初始化日志输出;无日志 = 插件未加载 - 在 JS 中执行
console.log(uni.requireNativePlugin('NfcReader')),如果返回一个带readTag、writeTag等方法的对象,才算接入成功;如果返回undefined或报错Plugin not found,说明原生侧断连 - 注意:Android 插件类必须继承
io.dcloud.feature.uniapp.common.UniModule,并用@UniJSMethod注解标记公开方法;方法参数类型要严格匹配(如JSONObject不能写成Map)
最易被忽略的是:插件类中的硬件操作(如 NfcAdapter.getDefaultAdapter())必须在主线程外执行(@UniJSMethod(uiThread = false)),否则会卡死 UI;同时,Intent 携带的 Tag 对象需用 plus.android.invoke(intent, 'getParcelableExtra', 'android.nfc.extra.TAG') 获取,不能直接 JSON 序列化。


















