我是NFC技术的新手,并且开始考虑读写标签。为了阅读目的,我使用的是MIRFARE 1K智能卡,写作我使用的是NTAG203。我想要的只是在读取过程中获取TagID并将TagID和日期时间戳发送到NTAG203。
的问题:
我的应用程序在编译时遇到困难。它一直给我生成错误生成最终存档:无法创建'C:\ Android WS \ TabletApp \ bin \ TabletApp.apks':访问被拒绝错误。我清理项目并重新启动Eclipse但是徒劳无功。只有当我重新启动笔记本电脑时它才会消失。有什么建议吗?
当应用程序运行时,它仍然没有给我ID。我扫描我的卡/标签,一次又一次地加载MainActivity(ScanningActivity)。控件不会比这更进一步。关于如何处理它的任何建议?
public class ScanningActivity extends Activity {
private NfcAdapter sNfcAdapter;
Locale locale = new Locale("en", "US");
byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
boolean encodeInUtf8 = false;
Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
int utfBit = encodeInUtf8 ? 0 : (1 << 7);
char status = (char)(utfBit + langBytes.length);
static String bin2hex(byte[] data) {
return String.format("%0" + (data.length * 2) + "X", new BigInteger(1, data));
}
/* write to tag */
boolean writeNdefMessageToTag(NdefMessage message, Tag detectedTag) throws FormatException {
int size = message.toByteArray().length;
try {
Ndef ndef = Ndef.get(detectedTag);
if (ndef != null) {
ndef.connect();
if (!ndef.isWritable()) {
Toast.makeText(this, "Tag is read-only.", Toast.LENGTH_SHORT).show();
return false;
}
if (ndef.getMaxSize() < size) {
Toast.makeText(this,
"The data cannot be written since the tag capacity is" + ndef.getMaxSize() +
" bytes and the data to be transferred is " + size + " bytes",
Toast.LENGTH_LONG).show();
return false;
}
ndef.writeNdefMessage(message);
ndef.close();
Toast.makeText(this, "Data sent to the Tag", Toast.LENGTH_LONG).show();
return true;
} else {
NdefFormatable ndefFormat = NdefFormatable.get(detectedTag);
if (ndefFormat != null) {
try {
ndefFormat.connect();
ndefFormat.format(message);
ndefFormat.close();
Toast.makeText(this, "Data sent", Toast.LENGTH_LONG).show();
return true;
} catch (IOException e) {
Toast.makeText(this, "Unable to format tag", Toast.LENGTH_LONG).show();
return false;
}
} else {
Toast.makeText(this, "Not supported tag", Toast.LENGTH_LONG).show();
return false;
}
}
} catch (IOException e) {
Toast.makeText(this, "Sending failed", Toast.LENGTH_LONG).show();
}
return false;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scanning);
TextView tg = (TextView)findViewById(R.id.tagid);
final TextView tvtime = (TextView)findViewById(R.id.datetime);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss a");
String currentTimeStamp = dateFormat.format(new Date()); // Find todays date
tvtime.setText(currentTimeStamp);
sNfcAdapter = NfcAdapter.getDefaultAdapter(this);
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
if (sNfcAdapter == null) {
Toast.makeText(this, "This device does not support NFC or you have not scanned the card properly",
Toast.LENGTH_LONG).show();
return;
}
if (!sNfcAdapter.isEnabled()) {
Toast.makeText(this, "Looks like the NFC is not enabled on your device", Toast.LENGTH_LONG).show();
new AlertDialog.Builder(this).setTitle("NFC disabled").setMessage(
"Looks like the NFC is not enabled on your device. Please enable it.").setPositiveButton(
"Ok", null).show();
}
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(getIntent().getAction())) {
Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
try {
String TagID = tag.getId().toString();
tg.setText(bin2hex(tag.getId()));
Toast.makeText(getApplicationContext(), bin2hex(tag.getId()), Toast.LENGTH_LONG).show();
Toast.makeText(this, TagID, Toast.LENGTH_LONG).show();
} catch (Exception ex) {
new AlertDialog.Builder(this).setTitle("Error!").setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent i = new Intent(ScanningActivity.this, ScanningActivity.class);
startActivity(i);
}
}).setMessage(ex.getMessage() + "\n\nPlease click Ok. This will restart the application").create().show();
new AlertDialog.Builder(this).setTitle("Transferring the data").setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
TextView tvData = (TextView)findViewById(R.id.Data);
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
Tag tag1 = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
String DataToSend = tvtime.getText().toString() + tag1.getId().toString();
//String DataToSend = "Data";
//tvData.setText(tvtime.getText().toString()+tag.getId().toString());
byte[] textBytes = DataToSend.getBytes(utfEncoding);
byte[] dataa = new byte[1 + langBytes.length + textBytes.length];
dataa[0] = (byte)status;
System.arraycopy(langBytes, 0, dataa, 1, langBytes.length);
System.arraycopy(textBytes, 0, dataa, 1 + langBytes.length, textBytes.length);;
NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
NdefRecord.RTD_TEXT, new byte[0], dataa);
NdefMessage newMessage = new NdefMessage(new NdefRecord[] { textRecord });
try {
writeNdefMessageToTag(newMessage, tag1);
} catch (FormatException e) {
e.printStackTrace();
}
}
}
}).setMessage(
"Place this tablet on the RFID Tag on the Microbiology Form. Keep it there until you get to the next screen").create().show();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.scanning, menu);
return true;
}
}
和清单是
<uses-permission android:name="android.permission.NFC"/>
<uses-sdk
android:minSdkVersion="13"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.tabletapp.ScanningActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
</application>
更新
该应用不会显示任何祝酒词。当我在设备上放一张卡片/标签时,我被问到我想要使用哪个应用程序。我选择了我们正在讨论的那个,并再次加载'ScanningActivity'(MainActivity)。既没有向我显示身份证也没有通过扫描活动。
我想从卡片中读取ID,然后将其与时间戳一起写入另一个标签。
答案 0 :(得分:1)
你的代码中存在很多问题,所以我只关注最明显的问题:
您在AndroidManifest.xml中注册了NDEF_DISCOVERED
。但是,在onCreate()
中,只有在获得TAG_DISCOVERED
意图时才会读取ID。您必须更改此设置以匹配NDEF_DISCOVERED
意图。 (我在此假设您的标签包含与您的意图过滤器匹配的文本记录。)
tag.getId().toString()
不会为您提供更多有用信息,因为tag.getId()
会返回一个字节数组。您可能总是希望使用bin2hex()
方法将ID转换为人类可读的字符串。
单击按钮时,应避免与NFC标签进行任何交互。 (即您目前在onClick(DialogInterface dialog, int which)
中所做的事情。)两者都应该将按钮点击和NFC交互视为人工输入,您应该避免同时需要两个人工输入。 (此外,Bott是基于事件的,您不能直接组合它们。)您可以在onClick()
方法中设置一个标志,指示在下次NFC发现事件时应将数据写入标签。
如果您要扫描第一个标记,由于此事件而启动您的活动,并在扫描第二个标记时保持活动处于打开状态,则应使用foreground dispatch system(另请参阅{{3 }})。这样,前台活动可以处理标签的重复扫描而不会重新启动(并且不会控制任何其他可能由标签触发的活动)。