【问题标题】:NFC - NdefRecord mis-constructedNFC - NdefRecord 构造错误
【发布时间】:2015-03-03 11:11:42
【问题描述】:

我正在尝试使用 NdefRecord/NdefMessage 编写 NFC 标签。

byte prefix = 0x04; // https://
byte[] uriBytes = "whatever.anywhere.com".getBytes();
byte[] recordBytes = new byte[uriBytes.length + 1];
recordBytes[0] = prefix;
System.arraycopy(uriBytes, 0, recordBytes, 1, uriBytes.length);

NdefRecord record = new NdefRecord(
    NdefRecord.TNF_WELL_KNOWN,
    NdefRecord.RTD_URI,
    null,
    recordBytes);

这就是我创建NdefRecord 的方式,由于兼容性问题,我无法使用createUri()createUri() 从 API14 开始可用,我需要 API11 兼容...)

它在 Lollipop(5.0.2 测试)和 KitKat 事件(4.4.3 测试)上运行良好。

我的一个用户在创建NdefRecord 时崩溃了:

NdefRecord record = new NdefRecord(
    NdefRecord.TNF_WELL_KNOWN,
    NdefRecord.RTD_URI,
    null,
    recordBytes);

他使用的是 ICS 4.0.2,我无法真正调试此问题,因为我没有这样的手机可用,也无法使用 AVD 来模拟此问题。

有没有人发现我的做法有问题?或者有其他/更好的方法吗?

编辑: 这是与此错误相关的堆栈跟踪

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.your.application/com.your.application.NFCWriter}: java.lang.IllegalArgumentException: Illegal null argument
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
        at android.app.ActivityThread.access$600(ActivityThread.java:127)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4448)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
        at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Illegal null argument
        at android.nfc.NdefRecord.<init>(NdefRecord.java:242)
        at android.nfc.NdefRecord.<init>(NdefRecord.java:233)
        at com.your.application.NFCWriter.onCreate(Unknown Source)
        at android.app.Activity.performCreate(Activity.java:4465)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
        ... 11 more

【问题讨论】:

  • 代码看起来不错。我建议您添加有关“崩溃”的更多详细信息,否则此问题可能与 SO 无关。例如,您可以使用错误报告中的堆栈跟踪(如果您的应用在 Play 商店中)或在您的应用中实现自己的异常处理程序,为您提供调试信息。
  • 这是棘手的部分,该应用不在 Play 商店中,因为它是在我的工作场所内部使用的,所以我无权访问错误报告。
  • 我知道问题来自这个语句,因为用户能够设置断点来检查它何时崩溃,但我没有他的堆栈跟踪...添加一个处理程序来发送调试info 听起来是个好主意,但我怎样才能通过应用程序获取调试信息(然后发送)?
  • 绝对是题外话,但您想要搜索的神奇术语是 UncaughtExceptionHandlersetDefaultUncaughtExceptionHandler。您可以使用它来收集有关导致崩溃的异常的数据并将该数据发送给您(或将该数据打包到用户可以手动发送给您的文件中)。

标签: android nfc ndef


【解决方案1】:

我想我找到了答案。

尽管 API 文档说将 null 用于 typeidpayload 是可以的,但事实并非如此。 --> API Reference

从 Android 4.1.1 开始就是如此,对于那些感兴趣的人来说,这里是源代码:

NdefRecord Constructor (4.1.1_r1) nullEMPTY_BYTE_ARRAY 替换(尽管如此,new byte[0]

NdefRecord Constructor (4.0.4_r2.1) 中使用null 作为参数时会抛出IllegalArgumentException

因此,如果您想向后兼容并构建 NdefRecord,永远不要提供 null 作为参数,请使用 new byte[0] INSTEAD

byte prefix = 0x04; // https://
byte[] uriBytes = "whatever.anywhere.com".getBytes();
byte[] recordBytes = new byte[uriBytes.length + 1];
recordBytes[0] = prefix;
System.arraycopy(uriBytes, 0, recordBytes, 1, uriBytes.length);

NdefRecord record = new NdefRecord(
    NdefRecord.TNF_WELL_KNOWN,
    NdefRecord.RTD_URI,
    new byte[0],
    recordBytes);

就是这样。

感谢@michael-roland 提供UncaughtExceptionHandler 的线索,这很有帮助。

【讨论】:

  • 如果您能记录您在问题中收到的例外情况,那就太好了。
  • 我在问题中添加了堆栈跟踪。
猜你喜欢
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 2012-12-14
  • 2017-07-31
  • 2016-11-24
  • 2018-11-15
  • 2012-07-01
  • 1970-01-01
相关资源
最近更新 更多