我试图用PN532模块从Android向Arduino发送一条字符串消息。当我接近智能手机(打开应用程序)到模块时,会出现“点击到波束”的用户界面,但在我点击屏幕后,手机会告诉我再次接近这两台设备。在我再次接近它们之后(“再次接近设备”消息仍然显示在屏幕上),什么都没有发生,arduino打印出"failed“。
这是Kotlin代码:
package com.cerowski.nfcclient
import android.nfc.NdefMessage
import android.nfc.NdefRecord
import android.nfc.NfcAdapter
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager
import com.cerowski.nfcclient.databinding.ActivityMainBinding
import com.cerowski.nfcclient.ui.main.SectionsPagerAdapter
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout
import java.io.File
import java.io.UnsupportedEncodingException
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {config(); sendid();
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val sectionsPagerAdapter = SectionsPagerAdapter(this, supportFragmentManager)
val viewPager: ViewPager = binding.viewPager
viewPager.adapter = sectionsPagerAdapter
val tabs: TabLayout = binding.tabs
tabs.setupWithViewPager(viewPager)
val fab: FloatingActionButton = binding.fab
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
}
fun config(){
val dir = getExternalFilesDir(null);
val file = File(dir,"config");
var msgtext="";
val msg = TextView (this)
if (dir!=null) {
if (!file.exists()) {msgtext = "config not found, attempting to create..."; file.createNewFile(); if(file.exists()) {msgtext = "config created successfully"; file.writeText(idgenerator())} else {msgtext = "problem creating file"}}
else {msgtext = (file.readText())}
} else {msgtext = "app directory not found"}
}
fun idgenerator() : String {
val allowedChars = ('a'..'z') + ('A'..'Z') + ('0'..'9')
return (1..16)
.map { allowedChars.random() }
.joinToString("")
}
fun sendid() {
val dir = getExternalFilesDir(null);
val file = File(dir,"config");
//var bytes = file.readBytes();
//var nfcmsg = NdefMessage(bytes);
//var msgtext="";
var nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter != null) {
val msg: String = file.readText().toString()
val languageCode: ByteArray
val msgBytes: ByteArray
try {
languageCode = "en".toByteArray(charset("US-ASCII"))
msgBytes = msg.toByteArray(charset("UTF-8"))
} catch (e: UnsupportedEncodingException) {
return
}
val messagePayload = ByteArray(
1 + languageCode.size
+ msgBytes.size
)
messagePayload[0] = 0x02.toByte() // status byte: UTF-8 encoding and
// length of language code is 2
// length of language code is 2
System.arraycopy(
languageCode, 0, messagePayload, 1,
languageCode.size
)
System.arraycopy(
msgBytes, 0, messagePayload, 1 + languageCode.size,
msgBytes.size
)
val message: NdefMessage
val records = arrayOfNulls<NdefRecord>(1)
val textRecord = NdefRecord(
NdefRecord.TNF_WELL_KNOWN,
NdefRecord.RTD_TEXT, byteArrayOf(), messagePayload
)
records[0] = textRecord
message = NdefMessage(records)
nfcAdapter.setNdefPushMessage(message, this);
}
else {Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();}
}
}下面是我的带有PN532模块的Arduino Uno的代码(红色的,如果你在网上搜索照片的话):
// Receive a NDEF message from a Peer
// Requires SPI. Tested with Seeed Studio NFC Shield v2
#include "SPI.h"
#include "PN532_SPI.h"
#include "snep.h"
#include "NdefMessage.h"
PN532_SPI pn532spi(SPI, 10);
SNEP nfc(pn532spi);
uint8_t ndefBuf[128];
void setup() {
Serial.begin(9600);
Serial.println("NFC Peer to Peer Example - Receive Message");
}
void loop() {
Serial.println("Waiting for message from Peer");
int msgSize = nfc.read(ndefBuf, sizeof(ndefBuf));
if (msgSize > 0) {
NdefMessage msg = NdefMessage(ndefBuf, msgSize);
msg.print();
Serial.println("\nSuccess");
} else {
Serial.println("Failed");
}
delay(3000);
}NFC模块上的小开关位于正确的位置,模块按其应有的方式连接到板上(对于SPI),所以我不知道是什么原因导致它失败。
任何帮助都是非常感谢的。
发布于 2022-02-28 17:22:06
首先检查它是否是可用的,b)启用,c)注册&实现回调。在Java中:
MainActivity extends AppCompatActivity implements
NfcAdapter.CreateNdefMessageCallback,
NfcAdapter.OnNdefPushCompleteCallback,
NfcAdapter.CreateBeamUrisCallback {
...
if (
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 &&
Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
) {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (!nfcAdapter.isEnabled()) {
startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
} else if (!nfcAdapter.isNdefPushEnabled()) {
startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS));
} else {
nfcAdapter.setNdefPushMessageCallback(this);
nfcAdapter.setOnNdefPushCompleteCallback(this);
nfcAdapter.setNdefPushMessage(nfcMessage, this);
}
}在Build.VERSION_CODES.Q中被弃用的意思是仍然可用;也许是<=。
这些回调也可能为您提供更多的细节,为什么它会失败。
否则你会发送一条NDEF信息,它将不知道下一步该做什么.
与此类似,您也可能会产生正确的错误消息。
另见:https://developer.android.com/training/beam-files/send-files
https://stackoverflow.com/questions/71297711
复制相似问题