简体   繁体   English

将NDEF消息写入Runnable内的标记

[英]Write An NDEF Message To A Tag Inside Runnable

I have recently started developing in Android and have started a project using NFC tags with NDEF messages. 我最近开始在Android上开发,并开始使用带有NDEF消息的NFC标签的项目。 I have managed to create a simple application which will read from text/plain NDEF records and write the data to the screen. 我设法创建了一个简单的应用程序,它将从text / plain NDEF记录中读取并将数据写入屏幕。

Now I am working on writing NDEF messages to tags. 现在我正致力于将NDEF消息写入标签。 I seem to have it working but wonder whether or not it's best to write the tag on a thread other than the main UI thread? 我好像有它工作,但想知道是否最好在主UI线程以外的线程上编写标签?

Having recently started learning, I have been taught that doing (potentially) long-running tasks in the main thread is a no-no, and figured that writing to a tag would count as such. 在最近开始学习之后,我被教导在主线程中执行(可能)长时间运行的任务是禁止的,并且认为写入标签会如此。 Putting the code to write to a tag inside a Runnable(), though, seems to cause the write to fail. 但是,将代码写入Runnable()中的标记似乎会导致写入失败。 So, my question is. 所以,我的问题是。 am I wrong in my assumption that writing to a tag should be done off of the main thread? 我错误地认为写入标签应该是从主线程完成的吗? Or am I wrong to use a Runnable? 或者我错了使用Runnable? And apologies if this has been answered before, I tried googling but couldn't find much on the topic. 并且如果之前已经回答道歉,我尝试谷歌搜索,但在这个主题上找不到多少。

I've included my example code: 我已经包含了我的示例代码:

The button handler: 按钮处理程序:

public void writeButton(View view)
{
    //Some validation
    createMessageToWrite();
}

Creating the message: 创建消息:

public void createMessageToWrite()
{       
    EditText messageBox = (EditText)findViewById(R.id.toWrite);
    String toWrite = messageBox.getText().toString();
    if(toWrite.length() == 0)
        toWrite = "This is some text from My writer";
    NdefRecord textRecord = NdefRecord.createMime("text/plain", toWrite.getBytes());
    NdefRecord aar        = NdefRecord.createApplicationRecord(getPackageName());

    NdefMessage message = new NdefMessage(new NdefRecord[]{textRecord, aar});
    messageToWrite=message;
    Toast.makeText(getApplicationContext(), "Message made", Toast.LENGTH_SHORT).show();

    write();
}

And, finally, my code to write to the tag: 最后,我的代码写入标签:

public void write()
{       
    Toast.makeText(getApplicationContext(),"Starting write. Touch tag",Toast.LENGTH_SHORT).show();
    sleep(3000);
//  Runnable r = new Runnable()
    //{
//      @Override
//      public void run()
//      {
            Toast.makeText(getApplicationContext(),"Starting runnable. Touch tag",Toast.LENGTH_SHORT).show();
            sleep(3000);

            if(messageToWrite == null)
            {
                Toast.makeText(getApplicationContext(),"Message is null",Toast.LENGTH_SHORT).show();
                return;
            }

            Toast.makeText(getApplicationContext(), "Trying", Toast.LENGTH_SHORT).show();
            sleep(3000);

            try
            {                   
                if(theTag != null)
                {
                    theTag.connect();//The tag is a global var set in onCreate() or onNewIntent()
                    theTag.writeNdefMessage(messageToWrite);
                    theTag.close();
                }
                else
                {
                    Toast.makeText(getApplicationContext(), "tag is null", Toast.LENGTH_SHORT).show();
                }
            }
            catch (IOException e)
            {
                e.printStackTrace();
                Toast.makeText(getApplicationContext(), "IOException", Toast.LENGTH_LONG).show();
            }
            catch (FormatException e)
            {
                e.printStackTrace();
                Toast.makeText(getApplicationContext(), "Format", Toast.LENGTH_LONG).show();
            }
            Toast.makeText(getApplicationContext(),"Written",Toast.LENGTH_SHORT).show();
        }
//      };
//      Thread t = new Thread(r);
//      t.start();
//  }

The code posted works, but uncommenting the Runnable() stuff causes the app to crash. 发布的代码有效,但取消注释Runnable()的东西会导致应用程序崩溃。 Unfortunately, the system I'm working on isn't set up to allow for USB debugging from a device and I don't have permissions to install the drivers. 不幸的是,我正在处理的系统没有设置为允许从设备进行USB调试,而我没有安装驱动程序的权限。 So, until that's set up, I have to settle for the "The app has stopped working" message... 所以,在设置之前,我必须满足于“应用已经停止工作”的消息......

Many thanks for any and all help 非常感谢任何和所有的帮助

EDIT: Grammar 编辑:语法

First of all, without knowing what exception you get, I would assume that the crash/exception is not caused by doing the write operation in a separate thread but by showing a Toast from a non-UI thread. 首先,在不知道你得到什么异常的情况下,我会假设崩溃/异常不是由在单独的线程中执行写操作而是通过从非UI线程显示Toast引起的。

Toast s must always be shown from the UI thread. 必须始终从UI线程显示Toast s。 You can overcome this issue by wrapping the Toast.makeText(...).show() call in something like the following: 您可以通过包装Toast.makeText(...).show()调用来解决此问题,如下所示:

runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(YourActivityClass.this, yourMessage, Toast.LENGTH_SHORT).show();
    }
});

Second, it is good practice to access NFC tags (or in general to do IO operations) in a separate thread. 其次,优良作法是在单独的线程中访问NFC标签(或者通常用于执行IO操作)。

Third, user interaction with an NFC tag is typically a very short action and a user will typically tap a tag only during the actual read, write, etc. operations. 第三,用户与NFC标签的交互通常是非常短的动作,并且用户通常仅在实际的读取,写入等操作期间敲击标签。 So saving the Tag handle and calling the write operation later upon additional user input (pressing a button) is generally a very bad idea (some rare exception to this may exist though). 因此,保存Tag句柄并在稍后用户输入(按下按钮)时调用写入操作通常是一个非常糟糕的想法(尽管可能存在一些罕见的例外)。

A better approach would be to store the NDEF message to be written, set your application to some "write mode" state and prompt the user to tap the tag. 更好的方法是存储要写入的NDEF消息,将应用程序设置为某种“写入模式”状态,并提示用户点击标记。 Then, upon tag detection, start the write thread and let it write the previously saved message. 然后,在标记检测时,启动写入线程并让它写入先前保存的消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM