【问题标题】:Write NDEF message inside a loop在循环内写入 NDEF 消息
【发布时间】:2015-08-13 08:41:44
【问题描述】:

我想在 while() 循环中编写不同的 NDEF 消息。

LAST EDIT: 看来微控制器不能这么快处理数据,所以我的问题无法解决。

//ndef.connect();
ndef.writeNdefMessage(message);
//ndef.close();

我的 write() 方法,简化,没有全部 try/catch

所以,第一次循环它可以正常工作,但下一个循环不能。但经过多次循环后,它再次工作一次。如此反复。

stop = 0;    
while(stop < 1000)
    {
        write();
        stop++
    } 

write() 在一个循环中正常工作。

编辑:我用计时器替换了 while():

    new Timer().schedule(new TimerTask() {
        @Override
        public void run() {
               write();
                }
}, 2000);

但这太慢了……我需要每秒至少写 5 次。 如果我设置的定时器周期小于 2000 它不起作用,与 while() 工作相同

EDIT2:我测量了消息传输和接收的速度。似乎发送一条消息大约需要 55 毫秒,接收大约需要 7 毫秒。这就是我想要的,但是如果我将计时器设置为在 100 毫秒后重复,例如,我会从 writeNDEFmessage() 收到此错误: java.io.IOException: Tag is not ndef 。因此,如果我循环 10 次 writeNDEFmessage() 它在第一次循环时工作正常,但在接下来的 9 处我收到异常。

EDIT3:

onNewIntent()

@Override
    protected void onNewIntent(Intent intent)
    {
        try {
            if(intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED) ||
                    intent.getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED)||
                    intent.getAction().equals(NfcAdapter.ACTION_TECH_DISCOVERED))
            {
                detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

                if(detectedTag != lastDetectedTag)
                {

                    lastDetectedTag = detectedTag;
                    setIntent(intent);
                }


            }
        } catch (Exception e)
        {
            Log.e("", "onIntent >>> "+e.getMessage());

        }

    }

这被分配给一个按钮:

 public void testWrite()
    {

        final Timer timer = new Timer();

        try {
            ndef = Ndef.get(detectedTag);
            ndef.connect();
        } catch (IOException e) {
            Log.e("", "Cannot connect");
            e.printStackTrace();
        }
        timer.schedule(new TimerTask() {

            @Override
            public void run() {

                transmit.writeTag(message), ndef) 

        }, 0, 200);

    }

writeTag():

public boolean writeTag(String str, Ndef ndef) {


        try {
            message = getNdefMessage(str);
        }
        catch (Exception e)
        {
           toast("Message error");
        }

        int size = message.toByteArray().length;

        try {


            if (ndef != null) {

                if(!ndef.isConnected())
                {
                    ndef.connect();
                    Log.e("", ""+ndef.toString());
                }

                if (!ndef.isWritable()) {
                    return false;
                }
                if (ndef.getMaxSize() < size) {
                    toast("Tag capacity is " + ndef.getMaxSize() + " bytes, message is " + size + " bytes.");
                    return false;
                }
                try{

                    ndef.writeNdefMessage(message);
                }
                catch(IOException e){
                    toast("error send");
                    Log.e("IOException", e + "-+-");
                    return false;
                }


                return true;
            } 
        }
        catch (Exception e) {
            toast("Failed to write tag");
        }
        return false;
    }

transmit 是来自Transmit 类的对象,其中定义了writeTag()

onCreate():

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView);
        transmit = new Transmit(this);
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        textView.setText("");
        detectedTag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
        lastDetectedTag = detectedTag;
        pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
                new Intent(this, getClass()).
                        addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
        IntentFilter filter2     = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        readTagFilters = new IntentFilter[]{tagDetected,filter2};
        techListsArray = new String[][] { new String[] { NfcF.class.getName() } };


        if (mNfcAdapter == null) {
            // Stop here, we definitely need NFC

            finish();
            return;

        }

        if (!mNfcAdapter.isEnabled()) {

        }


        buttonListener(testButton);

    }

【问题讨论】:

  • 你测试的是什么安卓版本和手机?
  • Android 4.4.2,API19,摩托罗​​拉 RAZR HD
  • 是否需要ndef.connect{}ndef.close() 部分?这可能是我在“循环”之外完成的。我想知道你为什么要做那种压力测试?实现您的“目标”可能有不同的方式。
  • 从循环中删除了 ndef.connect()ndef.close()。同样...
  • 添加了更多信息@vlp

标签: android while-loop nfc message ndef


【解决方案1】:

来自close() 方法的Ndef 文档:“禁用从此 TagTechnology 对象对标签的 I/O 操作,并释放资源。”

所以我认为当您调用close() 时,内部TagTechnology 会被释放。如果你在同一个 ndef 上调用 connect ,它就是一个“陈旧”的对象。尝试通过传递 Tag 对象每次创建一个新的 Ndef 对象。

编辑:否则在你真正完成之前不要打电话给close()。您仍然需要第一次致电connect()。此外,我总是先致电isConnected() 以确保标签存在并已连接。

【讨论】:

  • write() 中删除了ndef.connect()ndef.close() 并添加了ndef.isConnected() 检查。在调试器中,它每 4-5 个循环就会达到这个值,ndef Ndef@4219b850 Ndef@42151838 Ndef@4210a068 etc 的值不同
  • 从你上面的评论中你提到你在onNewIntent() 中有一个断点。这只会在标签离开并重新进入该字段时触发。因此,尝试在另一个线程中循环写入并等待onNewIntent() 中的断点是没有意义的。请发布完整的 Activity 类,并保留所有 NFC 逻辑,以便我们查看问题可能出在哪里。
猜你喜欢
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多