Android HCE:三星设备setPreferredService被静默忽略,HostApduService未触发
三星One UI下HCE前台偏好服务失效问题排查
背景
开发了一款模拟韩国KS X 6924标准交通卡(T-money/Cashbee类AID)的HCE应用,其HostApduService在category="payment"下注册了6个交通卡AID。用户打开支付界面时,调用setPreferredService()使本服务优先于三星钱包/Google Pay。根据Android官方文档,前台应用调用该方法应覆盖AID冲突解决逻辑,且支付类AID的服务仅在前台调用该方法时可处理交易,理论上用户在前台界面刷卡时本服务应被触发。
问题
约50%的三星Galaxy设备上,即使满足以下条件,HostApduService.processCommandApdu()也从未被调用:
- 支付界面处于前台
setPreferredService()调用成功无异常- NFC已启用
- 用户手动将本设为默认NFC支付应用
用户刷卡后显示“认证失败”,且基于SharedPreferences的APDU日志为空,说明系统未将SELECT APDU路由到本服务,其余50%设备运行正常。
配置
apdu_service.xml
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/app_name" android:requireDeviceUnlock="false"> <aid-group android:description="@string/app_name" android:category="payment"> <aid-filter android:name="D4100000030001"/> <!-- KS X 6924-1 --> <aid-filter android:name="D4100000140001"/> <!-- T-money 부가 --> <aid-filter android:name="D4100000300001"/> <!-- Cashbee --> <aid-filter android:name="A000000003969807"/> <!-- KS X 6924-2 --> <aid-filter android:name="D4100000020001"/> <!-- Transit standard --> <aid-filter android:name="D410000003000101"/> <!-- T-money B --> </aid-group> </host-apdu-service>
HostApduService
class PitinHceService : HostApduService() { override fun processCommandApdu(commandApdu: ByteArray?, extras: Bundle?): ByteArray { // Log every invocation to SharedPreferences for diagnostics appendLog(this, "RX " + bytesToHex(commandApdu ?: byteArrayOf())) // ... build KS X 6924 frame response } }
setPreferredService调用
@ReactMethod fun setPreferredService(promise: Promise) { try { val activity = reactApplicationContext.currentActivity ?: return promise.reject("NO_ACTIVITY", "No current activity") val adapter = NfcAdapter.getDefaultAdapter(reactApplicationContext) ?: return promise.reject("NO_NFC", "NFC not available") val emulation = CardEmulation.getInstance(adapter) val component = ComponentName(reactApplicationContext, PitinHceService::class.java) emulation.setPreferredService(activity, component) promise.resolve(true) } catch (e: Exception) { promise.reject("PREFERRED_ERROR", e) } }
该方法在支付界面加载时从JS层调用,且界面活跃时每10秒重调一次。
已验证项
- 故障设备上
setPreferredService()调用成功无异常 - NFC已启用(
NfcAdapter.isEnabled()返回true) - 调用时支付界面所属
MainActivity处于resumed状态 processCommandApdu从未被调用(SharedPreferences日志为空)- 同一读卡器和账号在其他设备正常工作
已尝试方案
- 系统设置设为本应用为默认NFC支付应用→无变化
- 每10秒重调
setPreferredService→无变化 AppState变为active时重调→无变化- 调用后验证
isDefaultServiceForAid()→返回false(可能因该API针对默认应用而非前台偏好) - 强制停止三星钱包→部分设备无变化
受影响设备
- Samsung Galaxy S22、S23(One UI 6.x)→频繁故障
- Samsung Galaxy A系列→频繁故障
- Samsung Galaxy Z Flip 5→时好时坏
- Google Pixel→通常正常
- LG/Xiaomi→正常
环境
- React Native 0.81.5(Bare Workflow)
- Expo SDK 54
- Target SDK 35,Min SDK 24
- React Native新架构启用(
newArchEnabled: true) - 清单文件已声明NFC权限和特性
技术问询
根据官方文档,前台调用setPreferredService()应覆盖AID冲突解决逻辑,但本服务在大量三星设备上未被触发,现寻求以下问题解答:
- 三星One UI是否存在未公开的OEM特定要求(签名、清单声明、权限),需满足才会生效
setPreferredService? - 除实际刷卡外,是否有运行时验证
setPreferredService是否被系统认可的方法?公开CardEmulationAPI未提供相关能力。 - Android 15的“钱包角色持有者”概念是否会通过系统更新在Android 14设备上静默覆盖
setPreferredService? - 韩国主流HCE应用(如KB Pay、Shinhan Sol Pay)如何绕过三星钱包拦截?是否依赖三星KNOX合作或特定签名证书?
恳请提供setPreferredService被静默忽略的原因分析或调试方案。
内容的提问来源于stack exchange,提问作者user26755203
相关产品推荐
相关产品推荐

