我最近开始在Android上开发,并开始使用带有 NDEF 消息的NFC标签的项目。我设法创建了一个简单的应用程序,它将从text / plain NDEF记录中读取并将数据写入屏幕。
现在我正致力于将 NDEF 消息写入标签。我好像有它工作,但想知道是否最好在主UI线程以外的线程上编写标签?
最近开始学习之后,我被教导在主线程中执行(可能)长时间运行的任务是禁止的,并且认为写入标签会如此。但是,将代码写入Runnable()中的标记似乎会导致写入失败。所以,我的问题是。我错误地认为写入标签应该是从主线程完成的吗?或者我错了使用Runnable? 并且如果之前已经回答道歉,我尝试使用谷歌搜索,但在主题上找不到多少。
我已经包含了我的示例代码:
按钮处理程序:
public void writeButton(View view)
{
//Some validation
createMessageToWrite();
}
创建消息:
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();
}
最后,我的代码写入标签:
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();
// }
发布的代码有效,但取消注释Runnable()会导致应用崩溃。不幸的是,我正在处理的系统没有设置为允许从设备进行USB调试,而我没有安装驱动程序的权限。所以,在设置之前,我必须满足于“应用已经停止工作”的消息......
非常感谢任何和所有帮助
编辑:语法答案 0 :(得分:2)
首先,在不知道你得到什么异常的情况下,我会假设崩溃/异常不是由在单独的线程中执行写操作而是通过从非UI线程显示Toast
引起的。
Toast
。您可以通过将Toast.makeText(...).show()
调用包含在以下内容中来解决此问题:
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(YourActivityClass.this, yourMessage, Toast.LENGTH_SHORT).show();
}
});
其次,优良作法是在单独的线程中访问NFC标签(或者通常用于执行IO操作)。
第三,用户与NFC标签的交互通常是非常短的动作,并且用户通常仅在实际的读取,写入等操作期间轻敲标签。因此,保存Tag
句柄并在稍后通过额外的用户输入(按下按钮)调用写入操作通常是一个非常糟糕的想法(尽管可能存在一些罕见的例外)。
更好的方法是存储要写入的NDEF消息,将应用程序设置为某种“写入模式”状态,并提示用户点击标记。然后,在标记检测时,启动写入线程并让它写入先前保存的消息。