Android Beam传输NFC文本文件失败,遇空指针异常求助
先来说那个致命的空指针错误——这大概率是导致Beam流程卡壳的核心原因之一,得先把它搞定。
一、修复intent.getAction()空指针异常
你遇到的空指针,本质是intent对象本身为null,直接调用getAction()自然会崩溃。解决思路分两种场景:
如果是在**Activity的
onCreate/onResume**中获取intent:
一定要先判断intent是否非空,再调用方法:Intent receivedIntent = getIntent(); if (receivedIntent != null) { String action = receivedIntent.getAction(); // 后续处理逻辑 } else { Toast.makeText(this, "未接收到有效Intent", Toast.LENGTH_SHORT).show(); }如果是处理NFC相关的Intent:
NFC的触发Intent通常是通过onNewIntent()传递的,而不是初始的getIntent()。你需要重写这个方法来接收:@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); // 这里的intent大概率不会为空,可以放心处理 String action = intent.getAction(); if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) { // 处理NDEF数据逻辑 } }另外,别忘了在Manifest里给Activity设置对应的intent-filter,确保能捕获NFC相关的Action:
<activity android:name=".YourNfcActivity"> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <!-- 如果是传输文本文件,可添加对应的MIME类型 --> <data android:mimeType="text/plain"/> </intent-filter> </activity>
二、解决Android Beam文本文件传输失败问题
搞定空指针后,再来排查传输失败的问题,几个关键检查点:
权限配置是否齐全
确保Manifest里声明了必要的权限:<!-- NFC基础权限 --> <uses-permission android:name="android.permission.NFC"/> <!-- 声明设备支持NFC(可选,但建议加) --> <uses-feature android:name="android.hardware.nfc" android:required="true"/> <!-- Android 6.0+需要动态申请文件读写权限,如果传输的是外部存储的文件 -->如果你的文件在外部存储,记得在代码中动态申请
READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE权限。正确构建NDEF消息用于传输
Android Beam依赖NDEF格式的数据,传输文本文件时,要把文件内容或Uri封装成NdefRecord。如果是小文本文件,可以直接把内容写入NdefRecord;如果是大文件,建议用Uri的方式:@TargetApi(16) public void sendNfcFile() { NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); if (nfcAdapter == null) { Toast.makeText(this, "设备不支持NFC", Toast.LENGTH_SHORT).show(); return; } if (!nfcAdapter.isEnabled()) { Toast.makeText(this, "请在设置中开启NFC", Toast.LENGTH_SHORT).show(); return; } // 假设文本文件路径是filePath File file = new File(filePath); // Android 7.0+必须用FileProvider获取Uri,不能直接用file:// Uri fileUri = FileProvider.getUriForFile(this, "com.your.package.fileprovider", file); // 创建NDEF消息 NdefRecord record = NdefRecord.createMime("text/plain", fileUri.toString().getBytes()); NdefMessage message = new NdefMessage(new NdefRecord[]{record}); // 设置Beam要传输的消息 nfcAdapter.setNdefPushMessage(message, this); }注意:如果用FileProvider,需要在Manifest中配置:
<provider android:name="androidx.core.content.FileProvider" android:authorities="com.your.package.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/> </provider>然后在res/xml下创建file_paths.xml,指定可访问的文件路径:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="my_files" path="."/> <!-- 根据你的文件位置选择对应的标签,比如external-path、files-path等 --> </paths>双方设备的兼容性检查
- 确保接收方设备也开启了NFC和Android Beam(部分设备可能叫“Android Beam”或“NFC共享”)
- 两台设备要紧贴,且NFC感应区域对齐(通常在手机背部顶部)
- 接收方的Activity也要配置对应的intent-filter,能识别你发送的MIME类型(比如text/plain)
排查传输流程的逻辑漏洞
检查你的sendNfcFile()方法是否在正确的时机调用,比如用户点击按钮触发,而不是在Activity启动时就调用(此时可能还没获取到文件路径或权限)。
最后总结
先优先解决空指针问题,确保Intent的获取和处理逻辑安全;再逐一排查权限、NDEF消息构建、设备兼容性这几个点,应该就能解决Beam传输失败的问题了。
内容的提问来源于stack exchange,提问作者Hazed 2.0

