React Native:一次从两个扇区读取数据会引发 "Transceive fail" 错误

React Native: Reading data from two sectors at once throws "Transceive fail" error

我目前正在开发一个简单的应用程序,用户可以在其中扫描 NFC 标签并在屏幕上接收存储在标签上的数据。

我遵循了 this example,当我尝试验证一个扇区并从中读取和写入数据时一切正常,但是当我尝试同时从两个扇区读取数据时,我收到“收发失败" 错误。

我正在使用 Mifare 1k 卡在三星 J6 设备上测试该应用程序。

这是我的代码:

this.state = {
      keyAorB: KeyTypes[1], // 'B'
      keyToUse: 'FFFFFFFFFFFF',
      sectors: [3, 4],
      ...
};

authenticateSector = (sector) => {
    // Convert the key to a UInt8Array
    const key = [];
    for (let i = 0; i < this.state.keyToUse.length - 1; i += 2) {
      key.push(parseInt(this.state.keyToUse.substring(i, i + 2), 16));
    }

    if (this.state.keyAorB === KeyTypes[0]) {
      return NfcManager.mifareClassicAuthenticateA(sector, key);
    } else {
      return NfcManager.mifareClassicAuthenticateB(sector, key);
    }
};

read = (sector) => {
    return NfcManager.mifareClassicGetBlockCountInSector(sector)
      .then(() => NfcManager.mifareClassicReadSector(sector))
      .then((tag) => {
        ...
      })
      .then(() => NfcManager.mifareClassiacSectorToBlock(sector))
      .then(block => NfcManager.mifareClassicReadBlock(block))
      .catch((err) => console.warn(err))
};

readBulk = () => {
    this.state.sectors.forEach(async (s) => {
      const sector = parseInt(s);
      await this.authenticateSector(sector)
        .then(() => this.read(sector))
        .then(() => this.cleanUp())
        .catch((err) => console.warn(err));
    });
}

经过调试,我发现了问题所在,即:据我所知,一个扇区必须被认证,然后读取,但是,在我的情况下,两个扇区都被认证,然后读取功能是要求他们两个都不起作用。

我的问题是:为什么会发生这种情况?我的代码不应该以扇区经过身份验证(returns 承诺)的方式工作,然后从中读取数据并在之后清理吗?

感谢任何帮助! :)

.forEach() 不等待异步回调(参见 this article),因此您的 readBulk 函数实际上是一次在所有扇区上调用 this.read(),无需等待清理。 forEach 只是 运行 通过并触发 this.sectors.

中所有元素的回调

要在继续之前等待每个 auth/read/cleanUp 周期,您可以像这样重构它:


readBulk = async () => {
  for (const s of this.state.sectors) {
    const sector = parseInt(s)
    try {
      await this.authenticateSector(sector)
      await this.read(sector)
      await this.cleanUp()
    } catch (err) {
      console.warn(err)
    }
  }
    
}