我正在开发一个应用程序,在Android Studio中编写NFC标签。我的代码:
public class MainActivity extends AppCompatActivity {
public static final String Error_dected = "No NFC Tag Detected";
public static final String Write_Success = "Text Written Succesfully";
public static final String Write_Error = "Error during writtin, Try again";
NfcAdapter nfcAdapter;
PendingIntent pendingIntent;
IntentFilter writingTagFilters[];
boolean writeMode;
Tag myTag;
Context context;
EditText edit_message;
TextView nfc_contents;
Button ActivateButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit_message = (EditText) findViewById(R.id.edit_message);
nfc_contents = (TextView) findViewById(R.id.nfc_content);
ActivateButton = (Button) findViewById(R.id.ActivateButton);
context = this;
ActivateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String mensaje=edit_message.getText().toString();
try {
if (myTag == null) {
Toast.makeText(context, Error_dected, Toast.LENGTH_LONG).show();
} else {
write("PlainText|" + edit_message.getText().toString(), myTag);
Toast.makeText(context, Write_Success, Toast.LENGTH_LONG).show();
}
} catch (IOException e) {
Toast.makeText(context, Write_Error, Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (FormatException e) {
Toast.makeText(context, Write_Error, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
});
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "this device does not support NFC", Toast.LENGTH_LONG).show();
}
readfromIntent(getIntent());
pendingIntent = pendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
writingTagFilters = new IntentFilter[]{tagDetected};
}
public void readfromIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsg = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs = null;
if (rawMsg != null) {
msgs = new NdefMessage[rawMsg.length];
for (int i = 0; i < rawMsg.length; i++) {
msgs[i] = (NdefMessage) rawMsg[i];
}
buildTagView(msgs);
}
}
}
private void buildTagView(NdefMessage[] msgs) {
if (msgs == null || msgs.length == 0) return;
String text = "";
byte[] payload = msgs[0].getRecords()[0].getPayload();
String textEncodgin = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16"; //Get the text encoding
int languageCodeLength = payload[0] & 0063;
try {
text = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncodgin);
} catch (UnsupportedEncodingException e) {
Log.e("UnsupportedEncoding", e.toString());
}
nfc_contents.setText("NFC Content: " + text);
}
private void write(String text, Tag tag) throws IOException, FormatException {
NdefRecord[] records = {createRecord(text)};
NdefMessage message = new NdefMessage(records);
//Get an instance os Ndef for the tag
Ndef ndef = Ndef.get(tag);
//Enable I/0
ndef.connect();
//Write the message
ndef.writeNdefMessage(message);
//Clase de connection
ndef.close();
}
private NdefRecord createRecord(String text) throws UnsupportedEncodingException {
String lang ="en";
byte[] textBytes=text.getBytes();
byte[] langBytes=lang.getBytes("US-ASCII");
int langLength=langBytes.length;
int textLength=textBytes.length;
byte[] payload =new byte[1+langLength+textLength];
//set status byte (see NDEF spec for actual bits
payload[0]= (byte) langLength;
//copy langbytes and textbytes into payload
System.arraycopy(langBytes,0,payload,1,langLength);
System.arraycopy(textBytes,0,payload,1+langLength,textLength);
NdefRecord recordNFC =new NdefRecord(NdefRecord.TNF_WELL_KNOWN,NdefRecord.RTD_TEXT,new byte[0],payload);
return recordNFC;
}
@Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
setIntent(intent);
readfromIntent(intent);
if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))
{
myTag=intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
}
}
@Override
public void onPause()
{
super.onPause();
WriteModeOff();
}
@Override
public void onResume()
{
super.onResume();
WriteModeOn();
}
/********ENABLE WRITE*****/
private void WriteModeOn()
{
writeMode=true;
nfcAdapter.enableForegroundDispatch(this,pendingIntent,writingTagFilters,null);
}
/*******DISABLE WRITE*****/
private void WriteModeOff()
{
writeMode=false;
nfcAdapter.disableForegroundDispatch(this);
}
}
当我运行它并试图写在一个NFC标签我总是得到myTag==空,所以我总是在这里:
if(myTag==null){Toast.makeText(context,Error_dected,Toast.LENGTH_LONG).show();
我在“android.Manifest”中修改了用户权限,知道发生了什么吗?非常感谢。
任何NFC操作的唯一起点是当系统NFC应用程序给你一个Tag
对象作为与它检测到的NFC Tag交互的起点。
有很多方法可以做到这一点,并且enableForground Dispatch是您已经在使用的一种方法,但是在现实生活中使用这种方法来处理NFC是非常不可靠的,并且会导致NFC标签上的大量写入错误和损坏的数据。
更好的方法是使用较新的APIenableReaderMode
,在https://stackoverflow.com/a/64921434/2373819这也解释了为什么它更好。
但对于这两种API,当检测到标记并通知您标记已进入范围时,您需要完成与标记的所有交互(对于您正在使用的onNewIntent
中的当前API)
因此,当用户单击ActivateButton
时,处理此问题的一个简单方法是设置一个全局布尔值,以指示下次检测到标记时,您应该向其写入,而不是尝试从中读取(并且您还可以将要写入的字符串存储在全局字符串中)
下面是一些代码更改,让您有这样的想法,但这是一个简单的例子,因为它没有显示任何用户界面更改来提示用户将NFC卡带入范围,也没有涵盖您可能需要成功进行的任何重试写入NFC卡。
public class MainActivity extends AppCompatActivity {
public static final String Error_dected = "No NFC Tag Detected";
public static final String Write_Success = "Text Written Succesfully";
public static final String Write_Error = "Error during writtin, Try again";
NfcAdapter nfcAdapter;
PendingIntent pendingIntent;
IntentFilter writingTagFilters[];
boolean writeMode;
Tag myTag;
Context context;
EditText edit_message;
TextView nfc_contents;
Button ActivateButton;
//New code below
boolean someThingToWrite;
String stringToWrite;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit_message = (EditText) findViewById(R.id.edit_message);
nfc_contents = (TextView) findViewById(R.id.nfc_content);
ActivateButton = (Button) findViewById(R.id.ActivateButton);
context = this;
ActivateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Changed Code
stringToWrite = edit_message.getText().toString();
someThingToWrite = true;
});
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "this device does not support NFC", Toast.LENGTH_LONG).show();
}
readfromIntent(getIntent());
pendingIntent = pendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
writingTagFilters = new IntentFilter[]{tagDetected};
}
public void readfromIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsg = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs = null;
if (rawMsg != null) {
msgs = new NdefMessage[rawMsg.length];
for (int i = 0; i < rawMsg.length; i++) {
msgs[i] = (NdefMessage) rawMsg[i];
}
buildTagView(msgs);
}
}
}
private void buildTagView(NdefMessage[] msgs) {
if (msgs == null || msgs.length == 0) return;
String text = "";
byte[] payload = msgs[0].getRecords()[0].getPayload();
String textEncodgin = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16"; //Get the text encoding
int languageCodeLength = payload[0] & 0063;
try {
text = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncodgin);
} catch (UnsupportedEncodingException e) {
Log.e("UnsupportedEncoding", e.toString());
}
nfc_contents.setText("NFC Content: " + text);
}
private void write(String text, Tag tag) throws IOException, FormatException {
NdefRecord[] records = {createRecord(text)};
NdefMessage message = new NdefMessage(records);
//Get an instance os Ndef for the tag
Ndef ndef = Ndef.get(tag);
//Enable I/0
ndef.connect();
//Write the message
ndef.writeNdefMessage(message);
//Clase de connection
ndef.close();
}
private NdefRecord createRecord(String text) throws UnsupportedEncodingException {
String lang ="en";
byte[] textBytes=text.getBytes();
byte[] langBytes=lang.getBytes("US-ASCII");
int langLength=langBytes.length;
int textLength=textBytes.length;
byte[] payload =new byte[1+langLength+textLength];
//set status byte (see NDEF spec for actual bits
payload[0]= (byte) langLength;
//copy langbytes and textbytes into payload
System.arraycopy(langBytes,0,payload,1,langLength);
System.arraycopy(textBytes,0,payload,1+langLength,textLength);
NdefRecord recordNFC =new NdefRecord(NdefRecord.TNF_WELL_KNOWN,NdefRecord.RTD_TEXT,new byte[0],payload);
return recordNFC;
}
@Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
//New code
if(someThingToWrite) {
// Is it an NDEF tag
if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))
{
myTag=intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
write("PlainText|" + stringToWrite, myTag);
// Don't want to continue with reading so return
return;
}
// Really should handle NDEF formatable tags as well
// Just in case it's a blank unformatted tag
// but that is relevant for this example.
}
setIntent(intent);
readfromIntent(intent);
if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()))
{
myTag=intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
}
}
@Override
public void onPause()
{
super.onPause();
WriteModeOff();
}
@Override
public void onResume()
{
super.onResume();
WriteModeOn();
}
/********ENABLE WRITE*****/
private void WriteModeOn()
{
writeMode=true;
nfcAdapter.enableForegroundDispatch(this,pendingIntent,writingTagFilters,null);
}
/*******DISABLE WRITE*****/
private void WriteModeOff()
{
writeMode=false;
nfcAdapter.disableForegroundDispatch(this);
}
}
我很喜欢设置一个标志,而不是在下一个
只需启动新的活动,并通过Intent将字符串传递给它。Tag
检测写入Tag,实际上创建一个新的活动,只是为了处理用户界面,重新尝试逻辑和Tag
写入,这保持了逻辑的清洁
然后,您的ActivateButton.setOnClickListener
注意我可以你一直在复制和粘贴代码从可怜的例子在web上,因为你使用WriteModeOn
和WriteModeoff
方法:-)
我正在尝试使用react-native-NFC-Manager在我的react-本机应用程序中添加NFC功能,它工作正常。但问题是我第一次无法读取/写入NFC卡。第一次,我需要使用NFC工具应用程序编写一个新标签,将“NdeFormatable”转换为“Ndef”,否则我无法读取/写入NFC卡 我用这段代码写数据: 这个问题有什么解决办法吗?
我正在尝试创建一个 NFC 标签,该标签将触发两个单独的操作: 打开蓝牙连接 启动应用程序(或前往游戏商店) 我使用 nfc-eclipse-plugin 创建了一个包含两个合适记录的消息,但是,当写入标签时,它总是只触发第一个操作。两者都单独工作,但第二个总是被忽略。 我知道一个NFC标签上的2个NDEF消息/记录的答案-Android说你不能在一个标签上有两条独立的消息,只有一条消息中的多条记
我使用下面的示例代码来读取NFC标签,但它不是多次读取标签(有时读取3次,有时读取6-7次)。在我的应用程序中,我需要连续读取nfc标签。 https://github.com/andijakl/NfcDemo
本文向大家介绍详解Android平台上读写NFC标签,包括了详解Android平台上读写NFC标签的使用技巧和注意事项,需要的朋友参考一下 本文主要谈一谈Android上有关NFC标签的读写问题(NDEF格式)。 硬件环境:android4.0(Sony M35h)+可读可写的NFC标签若干 一、NFC基础知识 1.NFC是什么? NFC,即Near Field Communication,近距离
如何将NDEF消息写入NFC标记?我必须更改清单文件吗?到目前为止,我有生成NDEF消息的代码: 如何发现标签?有人能帮我吗?
我一直在开发一个应用程序,它使用NFC标签做一些魔术。 一切都很好,直到最近,我改变了一些代码,这些代码与之前一直有效的NFC代码无关。 当我通过NFC点击启动我的应用程序时,所有的工作,当我点击应用程序运行时,我将在onNewIntent()中收到未来的NFCTag。 当我通过图标启动应用程序并在应用程序运行时尝试点击时,会调用onNewIntent()方法,但当我试图从intent中获取额外的