我需要检查设备上是否启用了卡仿真。我找到了一种方法here:
boolean isDefault = CardEmulation
.getInstance(NfcAdapter.getDefaultAdapter(this))
.isDefaultServiceForCategory(
new ComponentName(this, MyPaymentService.class),
CardEmulation.CATEGORY_PAYMENT);
看起来这适用于某些设备,但不适用于所有设备。
例如,在Samsung GT-I9300I(使用Android 4.4)上,有一个NFC模块,但它没有在设置中显示Tap-and-pay选项。
当我的应用在该设备上运行时,我收到以下错误:
E/CardEmulation: This device does not support card emulation 09-26 16:41:13.592 2625-2625/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.android.settings, PID: 2625 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.settings/com.android.settings.nfc.PaymentDefaultDialog}: java.lang.UnsupportedOperationException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2441) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2500) at android.app.ActivityThread.access$900(ActivityThread.java:171) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1309) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5679) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.UnsupportedOperationException at android.nfc.cardemulation.CardEmulation.getInstance(CardEmulation.java:159) at com.android.settings.nfc.PaymentBackend.(PaymentBackend.java:53) at com.android.settings.nfc.PaymentDefaultDialog.onCreate(PaymentDefaultDialog.java:57) at android.app.Activity.performCreate(Activity.java:5582) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2405) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2500) at android.app.ActivityThread.access$900(ActivityThread.java:171) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1309) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5679) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107) at dalvik.system.NativeStart.main(Native Method)
但是,根据the documentation,自API级别19(Android 4.4)以来CardEmulation
可用。
所以有人能解释为什么我得到这个例外吗?我怎样才能克服这个问题?
答案 0 :(得分:1)
日志输出中的错误非常明显:
E/CardEmulation: This device does not support card emulation
此类只能用于支持卡仿真和基于AID的路由配置的设备。这也记录在the documentation of the class CardEmulation
:
使用此类需要
FEATURE_NFC_HOST_CARD_EMULATION
才能出现在设备上。
因此,您必须仅在实际支持HCE功能的设备上使用方法getInstance()
。请注意, host 卡仿真在这里有点误导,因为使用OffHostApduService
声明管理路由配置也需要该功能,并且使用CardEmulation
类进行与之相关的任何操作OffHostApduService
。因此,此功能适用于HCE和基于安全元件的卡仿真的路由配置管理。但是,一些设备制造商开发了其他机制来测试基于安全元件的卡仿真的可用性(并且还有助于管理路由)。
在调用CardEmulation.getInstance()
方法之前,您可以使用以下代码检查HCE功能:
boolean isDefault = false;
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
isDefault = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(this))
.isDefaultServiceForCategory(
new ComponentName(this, MyPaymentService.class),
CardEmulation.CATEGORY_PAYMENT);
}