You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android NFC读取应用崩溃求助:空对象引用异常

解决NFC读取Activity跳转时的空指针异常问题

我一眼就定位到问题根源了——崩溃日志里的空指针,是因为intent.getAction()返回了null,你却直接调用了equals()方法。咱们来捋清楚为什么会这样:

当把NFC读取Activity设为启动页时,系统是检测到NFC标签后才启动这个Activity的,这时传递的Intent带有明确的NFC相关Action(比如ACTION_NDEF_DISCOVERED),所以intent.getAction()不会为空。但当你从其他Activity通过按钮跳转过来时,传递的只是普通的跳转Intent,根本没有设置NFC相关Action,这时候intent.getAction()就是null,调用equals()自然就抛出空指针了。

修复方案

咱们只需要在处理Intent之前,先做一层空值判断,确保只有当Intent确实是NFC触发的情况下,才执行读取逻辑。

1. 修改onCreate中的readTag调用

在调用readTag之前,先判断当前Intent是否来自NFC触发:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
    mNfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP), 0);
    IntentFilter ndefDiscovery = new IntentFilter(
            NfcAdapter.ACTION_NDEF_DISCOVERED);
    IntentFilter tagDiscovery = new IntentFilter(
            NfcAdapter.ACTION_TAG_DISCOVERED);
    mTagFilters = new IntentFilter[]{
            ndefDiscovery, tagDiscovery
    };
    
    // 新增:只有当Intent是NFC相关的才调用readTag
    String action = getIntent().getAction();
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action) || NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
        readTag(getIntent());
    }
}

2. 加固readTag方法的空判断

在方法开头就加上空值检查,避免后续逻辑出现意外:

private void readTag(Intent intent) {
    // 先判断intent和action是否为空,为空直接返回
    if (intent == null || intent.getAction() == null) {
        return;
    }
    
    String action = intent.getAction();
    if (action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED) || action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
        // 原有的读取逻辑...
        findViewById(R.id.progress).setVisibility(View.GONE);
        Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        boolean writeable = writableTag(detectedTag);
        TextView writeableText = (TextView) findViewById(R.id.tag_writeable);
        writeableText.setText("Writeable? " + (writeable ? "Yes" : "No"));
        Ndef ndef = Ndef.get(detectedTag);
        if (ndef != null) {
            try {
                ndef.connect();
                int maxSize = ndef.getMaxSize();
                TextView infoText = (TextView) findViewById(R.id.tag_content);
                TextView maxSizeText = (TextView) findViewById(R.id.tag_max_size);
                maxSizeText.setText("Tag capacity: " + maxSize + " bytes");
                TextView remainingSizeText = (TextView) findViewById(R.id.tag_remaining_size);
                NdefMessage message = ndef.getNdefMessage();
                if (message != null) {
                    NdefRecord[] records = message.getRecords();
                    StringBuilder sb = new StringBuilder();
                    for (NdefRecord record : records) {
                        String payload = new String(record.getPayload(), "UTF-8");
                        sb.append(payload + "\n");
                    }
                    String regNum = sb.toString().substring(3);
                    infoText.setText(regNum);
                    infoText.setTextColor(Color.BLACK);
                    remainingSizeText.setText("Remaining capacity: " + (maxSize - message.getByteArrayLength()) + " bytes");
                } else {
                    infoText.setText("Empty tag");
                    infoText.setTextColor(Color.RED);
                    remainingSizeText.setText("Remaining capacity: " + maxSize + " bytes");
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (FormatException e) {
                e.printStackTrace();
            } finally {
                try {
                    ndef.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

额外优化建议

  • 你还可以在跳转至NFC读取Activity时,给Intent设置一个自定义Action,这样在onCreate里能更清晰地区分是正常跳转还是NFC触发的启动。
  • 另外,onNewIntent中调用readTag是没问题的,因为这个方法只会在NFC触发Activity前台调度时被调用,此时的Intent一定带有NFC相关Action。

内容的提问来源于stack exchange,提问作者Tinovimba Mawoyo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:22:42