如何编程识别带HCE服务的NFC支付应用及设备默认支付应用?
NFC支付应用相关查询方案
1. 识别可用于NFC支付的应用列表及默认支付应用
获取支持NFC支付的应用列表
通过CardEmulation类可直接获取系统中注册为支付类别的HCE服务,每个服务对应一个应用:
fun getPaymentApps(context: Context): List<ApplicationInfo> { val cardEmulation = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(context)) val paymentServices = cardEmulation.getServicesForCategory(CardEmulation.CATEGORY_PAYMENT) val packageManager = context.packageManager val paymentApps = mutableListOf<ApplicationInfo>() for (service in paymentServices) { try { val appInfo = packageManager.getApplicationInfo(service.packageName, 0) paymentApps.add(appInfo) } catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() } } return paymentApps }
遍历返回的ComponentName集合,通过包名即可获取对应的应用信息。
检查当前默认支付应用
调用getDefaultServiceForCategory方法获取默认服务,再关联到对应应用:
fun getDefaultPaymentApp(context: Context): ApplicationInfo? { val cardEmulation = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(context)) val defaultService = cardEmulation.getDefaultServiceForCategory(CardEmulation.CATEGORY_PAYMENT) val packageManager = context.packageManager return defaultService?.let { try { packageManager.getApplicationInfo(it.packageName, 0) } catch (e: PackageManager.NameNotFoundException) { null } } }
2. 识别具备HCE服务的可用NFC支付应用列表
HCE服务需在Manifest中声明android.nfc.cardemulation.action.HOST_APDU_SERVICE的Intent Filter,因此可通过PackageManager查询所有包含该过滤规则的服务,再筛选属于支付类别的:
fun getHcePaymentApps(context: Context): List<ApplicationInfo> { val packageManager = context.packageManager val intent = Intent("android.nfc.cardemulation.action.HOST_APDU_SERVICE") val resolveInfos = packageManager.queryIntentServices(intent, 0) val cardEmulation = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(context)) val hcePaymentApps = mutableListOf<ApplicationInfo>() for (resolveInfo in resolveInfos) { val componentName = ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name) // 检查该HCE服务是否属于支付类别 if (cardEmulation.getCategoryForService(componentName) == CardEmulation.CATEGORY_PAYMENT) { try { val appInfo = packageManager.getApplicationInfo(resolveInfo.serviceInfo.packageName, 0) hcePaymentApps.add(appInfo) } catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() } } } return hcePaymentApps }
补充:设置自身为默认NFC支付应用(你的实现)
你已实现的代码可正常使用,注意需在Manifest中声明对应权限和HCE服务配置:
fun setAsDefault(context: Context) { try { val intent = Intent() intent.setAction(CardEmulation.ACTION_CHANGE_DEFAULT); intent.putExtra( CardEmulation.EXTRA_SERVICE_COMPONENT, ComponentName( context, HCEService::class.java ) ) intent.putExtra(CardEmulation.EXTRA_CATEGORY, CardEmulation.CATEGORY_PAYMENT) context.startActivity(intent) } catch (e: Exception) { e.printStackTrace() } }
注意:使用这些API需要在Manifest中添加
android.permission.NFC权限,并且确保设备支持NFC功能,调用前需检查NfcAdapter.getDefaultAdapter(context)不为null。
内容的提问来源于stack exchange,提问作者breeze
相关产品推荐
相关产品推荐

