我尝试按照这里的指示制作一个应用程序:
https://developer.android.com/guide/topics/connectivity/nfc/nfc
但是当我编译代码并将一张卡放在手机上时,我听到了奇怪的声音。
我的nfc已经打开,我使用运行Android 9的oneplus 6。
当我检查logcat时,发现我遇到了一个错误:
我的nfc已经打开,我使用运行Android 9的oneplus 6。
当我检查logcat时,发现我遇到了一个错误:
56:27.888 7834-7850/com.appname D/DecorView: onWindowFocusChangedFromViewRoot hasFocus: true, DecorView@6302a6f[MainActivity]
2019-10-12 22:56:27.913 7834-7834/com.appname W/RenderThread: type=1400 audit(0.0:2504791): avc: denied { read } for name="u:object_r:vendor_default_prop:s0" dev="tmpfs" ino=21655 scontext=u:r:untrusted_app:s0:c16,c257,c512,c768 tcontext=u:object_r:vendor_default_prop:s0 tclass=file permissive=0
2019-10-12 22:56:27.928 7834-7880/com.appname E/libc: Access denied finding property "vendor.debug.egl.swapinterval"
为什么我会收到这个错误,而不是文本视图显示我正在扫描的NFC卡的信息(我尝试了多张NFC卡,但都出现相同的错误)
我发现有人遇到了类似的问题。他们说你应该按照链接中的说明并查看第三条评论。然后他们说这与由于安全问题而不允许写入tmp目录有关。
请帮助我解决这个问题,这是我的MainActivity.java:
package com.packagename;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Parcelable;
import android.renderscript.RenderScript;
import android.widget.TextView;
import android.widget.Toast;
import static android.nfc.NdefRecord.createMime;
public class MainActivity extends AppCompatActivity implements CreateNdefMessageCallback {
NfcAdapter nfcAdapter;
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Check for available NFC Adapter
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
// Register callback
nfcAdapter.setNdefPushMessageCallback(this, this);
}
@Override
public NdefMessage createNdefMessage(NfcEvent event) {
String text = ("Beam me up, Android!\n\n" +
"Beam Time: " + System.currentTimeMillis());
NdefMessage msg = new NdefMessage(
new NdefRecord[] { createMime(
"application/vnd.com.example.android.beam", text.getBytes())
/**
* The Android Application Record (AAR) is commented out. When a device
* receives a push with an AAR in it, the application specified in the AAR
* is guaranteed to run. The AAR overrides the tag dispatch system.
* You can add it back in to guarantee that this
* activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system.
*/
//,NdefRecord.createApplicationRecord("com.example.android.beam")
});
return msg;
}
@Override
public void onResume() {
super.onResume();
// Check to see that the Activity started due to an Android Beam
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
processIntent(getIntent());
}
}
@Override
public void onNewIntent(Intent intent) {
// onResume gets called after this to handle the intent
setIntent(intent);
}
/**
* Parses the NDEF Message from the intent and prints to the TextView
*/
void processIntent(Intent intent) {
textView = findViewById(R.id.textView);
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// only one message sent during the beam
NdefMessage msg = (NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
textView.setText(new String(msg.getRecords()[0].getPayload()));
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.packagename">
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
以下是我的activity_main.xml的图片:
![activity](https://istack.dev59.com/Cbf9j.webp)
谢谢!
protected void onResume()
中放置了super.onResume();
,并将textView id更改为我在程序中使用的textView id。我需要在oncreate中放置其他东西吗?我需要添加implements
吗?我甚至看到有些人在创建nfc读卡器时有额外的文件,我需要那些吗?谢谢(我确实正在尝试制作一个从nfc卡中读取数据并将文本放入textView的应用程序) - novunonCreate
,其中我只获取默认的NFC适配器和其他提示。你是否检查过卡片是NDEF类型和NDEF格式?并且卡片上有一个带有一些有效负载的NDEF记录可供读取吗?因为如果卡片没有要显示的内容,它将不会显示任何内容。我添加了一个链接到一个通用的应用程序,有助于查看卡片的格式和编写测试数据。 - Andrewsuper.onResume();
的同样问题,它仍然不起作用。我已经使用了7张卡进行了检查,但它们都没有起作用。我又看到这个人使用了额外的文件(Textrecord、urirecord),我不需要那些吗?除了代码之外,还有其他需要更改的地方吗?我的应用程序的其余部分是否正常?因为如果它对你有效,那么为什么对我无效? - novunsuper.onResume()
,我还删除了自定义的mimeType代码,我已经添加回来了一个*/*
的mimeType,因为我忘记了根据https://developer.android.com/guide/topics/connectivity/nfc/nfc#dispatching注册mimeType(s),如果您不注册mimeType(s),则处理操作系统会将其作为ACTION_TAG_DISCOVERED Intent而不是ACTION_NDEF_DISCOVERED给您。*/*
mimeType应该涵盖所有NDEF消息,现在您实际上有了一些可以从卡片中读取的内容(这已经作为独立应用程序测试,读取text/plain
)。 - Andrew