如何用安卓手机读取nfc卡

问题描述 投票:0回答:2

如何用安卓手机读取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);
}

}
`

android nfc
2个回答
0
投票

你得到一个空指针异常(与读取 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。


0
投票

简单的逻辑错误

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 标签触发。

© www.soinside.com 2019 - 2024. All rights reserved.