如何用安卓手机读取nfc卡,
控制台上写的错误如下,这个应用程序打开了,但是当我读卡到NFC时,它给出了一个错误,
你能帮我修复这段代码吗? 如何用安卓手机读取nfc卡,
控制台上写的错误如下,这个应用程序打开了,但是当我读卡到NFC时,它给出了一个错误,
你能帮我修复这段代码吗?
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 17885
java.lang.NullPointerException: Attempt to read from null array
at com.example.myapplication.MainActivity.buildTagViews(MainActivity.java:126)
at com.example.myapplication.MainActivity.readfromIntent(MainActivity.java:114)
at com.example.myapplication.MainActivity.onNewIntent(MainActivity.java:180)
at android.app.Activity.performNewIntent(Activity.java:8113)
at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1410)
at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1423)
at android.app.ActivityThread.deliverNewIntents(ActivityThread.java:3724)
at android.app.ActivityThread.handleNewIntent(ActivityThread.java:3736)
at android.app.servertransaction.NewIntentItem.execute(NewIntentItem.java:53)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2108)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:7876)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
D/OOMEventManagerFK: checkEventAndDumpForJE: 0
I/Process: Sending signal. PID: 17885 SIG: 9
`public class MainActivity extends AppCompatActivity {
public static final String Error_Detected = "No NFC Tag Detected";
public static final String Write_Success = "Text Written Successfully!";
public static final String Write_Error = "Error During Writing, Try Again!";
NfcAdapter nfcAdapter;
PendingIntent pendingIntent;
IntentFilter writingTagFilters[];
boolean writeMode;
Tag myTag;
Context context;
TextView edit_message;
TextView nfc_contents;
Button ActivateButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit_message = (TextView) findViewById(R.id.edit_message);
nfc_contents = (TextView) findViewById(R.id.nfc_contents);
ActivateButton = (Button) findViewById(R.id.ActivateButton);
context = this;
ActivateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
if(myTag == null){
Toast.makeText(context,Error_Detected,Toast.LENGTH_LONG).show();
}else {
write("PlainTset|" + 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();
finish();
}
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 };
}
private 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[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs = null;
if(rawMsgs != null){
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
}
buildTagViews(msgs);
}
}
private void buildTagViews(NdefMessage[] msgs){
if (msgs == null || msgs.length == 0){
String text = "";
byte[] payload = msgs[0].getRecords()[0].getPayload();
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
int languageCodeLength = payload[0] & 0063;
try {
text = new String(payload,languageCodeLength+1, payload.length - languageCodeLength - 1, textEncoding);
} catch (UnsupportedEncodingException e) {
Log.e("UnsupportedEncoding", e.toString());
}
Log.d("myTag", text);
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);
Ndef ndef = Ndef.get(tag);
ndef.connect();
ndef.writeNdefMessage(message);
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];
payload[0] = (byte) langLength;
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_TAG_DISCOVERED.equals(intent.getAction())){
myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
}
}
@Override
public void onPause(){
super.onPause();
WriteModeOff();
}
@Override
public void onResume(){
super.onResume();
WriteModeOn();
}
private void WriteModeOn(){
writeMode = true;
nfcAdapter.enableForegroundDispatch(this, pendingIntent, writingTagFilters,null);
}
private void WriteModeOff(){
writeMode = false;
nfcAdapter.disableForegroundDispatch(this);
}
}
`
你得到一个空指针异常(与读取 nfc 卡没有直接关系)。
如果你阅读堆栈跟踪,你会看到:
java.lang.NullPointerException: Attempt to read from null array
at com.example.myapplication.MainActivity.buildTagViews(MainActivity.java:126)
at com.example.myapplication.MainActivity.readfromIntent(MainActivity.java:114)
at com.example.myapplication.MainActivity.onNewIntent(MainActivity.java:180)
查看您的代码,您会看到:
private 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[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs = null;
if(rawMsgs != null){
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
}
buildTagViews(msgs); /// <---- HERE IS THE PROBLEM
}
}
如果您的参数 rawMsgs 为 null,则您将 null 传递给 buildTagViews,因为您这样做了:
NdefMessage[] msgs = null;
如果 rawMsgs 为 null 或传入一个空数组,则不要调用 buildTagViews。
简单的逻辑错误
在
buildTagViews
线路
if (msgs == null || msgs.length == 0){
逻辑上说,如果我们没有消息,那么尝试处理不存在的消息,因此当您尝试访问消息时,您会得到空指针。
应该是
if (msgs != null && msgs.length != 0){
但是
null
消息的潜在原因可能是您试图从可能没有任何消息的事件中提取 NDef 消息。
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)){
应该是
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)){
as
ACTION_TAG_DISCOVERED
和 ACTION_TECH_DISCOVERED
也可以由没有 Ndef 消息的 NFC 标签触发。