英文:
Scanning NFC type v tag
问题
以下是您要翻译的内容:
I am developing an application in Android Studio that should be able to scan for an NFC type V tag. If I can just instantiate the tag object, then I can perform further operations with the tag, but I am having trouble with scanning the tag.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
<uses-permission android:name="android.permission.NFC" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.NfcTool"
tools:targetApi="30">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
以下是我的MainActivity.java
package com.example.nfctool;
import androidx.appcompat.app.AppCompatActivity;
import android.app.PendingIntent;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.NfcV;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private NfcAdapter nfcAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
}
@Override
protected void onResume() {
super.onResume();
// 启用NFC前台分派以捕获NFC意图
// 创建一个显式意图,在NFC意图被分派时启动MainActivity。
Intent intent = new Intent(this, MainActivity.class);
// 此标志确保如果MainActivity已经在前台运行,则不会重新创建,而是在其onNewIntent()方法中接收NFC意图。
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
// 创建一个待处理意图,包装我们早些时候创建的意图。它将用于处理到达的NFC意图。
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
// 启用NFC前台分派系统以处理NFC意图
nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
}
@Override
protected void onPause() {
super.onPause();
// 禁用NFC前台分派
nfcAdapter.disableForegroundDispatch(this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.d("DEBUG", "###############" + intent.getAction());
// 检查意图是否具有NFC标签
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
// 获取标签对象
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
// 检查标签是否支持NfcV技术
if (NfcV.get(tag) != null) {
// 使用标签实例化NfcV对象
NfcV nfcvTag = NfcV.get(tag);
// 使用NfcV对象进行进一步操作
// ...
Toast.makeText(this, "NFC标签已检测", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "不支持的标签技术", Toast.LENGTH_SHORT).show();
}
}
}
}
当我记录intent.getAction()的值时,它记录了一个null值 D ###############null
,所以我知道意图的操作没有设置。如果有人能指出我哪里出错或者我漏掉了什么,将不胜感激。
英文:
I am developing an application in Android studio that should be to scan for an NFC type v tag. If I can just instantiate the tag object then I can perform further operations with the tag but I am having trouble with scanning the tag.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
<uses-permission android:name="android.permission.NFC" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.NfcTool"
tools:targetApi="30">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
and here is my MainActivity.java
package com.example.nfctool;
import androidx.appcompat.app.AppCompatActivity;
import android.app.PendingIntent;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.NfcV;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private NfcAdapter nfcAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
}
@Override
protected void onResume() {
super.onResume();
// Enable NFC foreground dispatch to capture NFC intents
// creates an explicit intent to launch the MainActivity when an NFC intent is dispatched.
Intent intent = new Intent(this, MainActivity.class);
// This flag ensures that if the MainActivity is already in the foreground, it will not be recreated and instead receive the NFC intent in its onNewIntent() method.
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
// creates a pending intent that wraps the intent we created earlier. It will be used to handle the NFC intent when it arrives.
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
// enables the foreground dispatch system for NFC intents
nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
}
@Override
protected void onPause() {
super.onPause();
// Disable NFC foreground dispatch
nfcAdapter.disableForegroundDispatch(this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.d("DEBUG","###############" + intent.getAction());
// Check if the intent has an NFC tag
// if(intent.getAction() == NfcAdapter.ACTION_TECH_DISCOVERED){
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())){
// Get the tag object
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
// Check if the tag supports NfcV technology
if (NfcV.get(tag) != null) {
// Instantiate the NfcV object with the tag
NfcV nfcvTag = NfcV.get(tag);
// Use the NfcV object for further operations
// ...
Toast.makeText(this, "NFC tag detected", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Unsupported tag technology", Toast.LENGTH_SHORT).show();
}
}
}
}
when I log the value of intent.getAction() in the onNewIntent method it logs a null value
D ###############null
So I know that the action of the intent is not being set. IF someone could point out where I am going wrong or what I am missing it would be greatly appreciated.
答案1
得分: 2
PendingIntent.FLAG_IMMUTABLE
应该是 PendingIntent.FLAG_MUTABLE
的一个可能问题。
这是因为 PendingIntent
是一个对象,可以传递给其他应用程序,以便它们可以代表您在以后的某个时间执行您描述的操作。
因此,您将其传递给系统 NFC 服务,该服务稍后将添加 NFC 数据并返回给您,因此它必须是可更改的(Mutable)。
此外,从文档中可以看到,在示例中它必须是 Mutable。
还要注意,实际上使用 enableForegroundDispatch
并不是使用 NFC 的最佳方式,使用 enableReaderMode
是一个更新且更好的 NFC API。enableReaderMode
不使用 Intent,而且提供更多控制权,可以在后台线程中轻松执行 NFC 操作(建议如此),对于写入 NFC 标签,它更加可靠,减少错误。
英文:
One possible problem the PendingIntent.FLAG_IMMUTABLE
should be PendingIntent.FLAG_MUTABLE
This is because a PendingIntent
is an object can be handed to other applications so that they can perform the action you described on your behalf at a later time.
So you are handing this to the System NFC service which then adds the NFC data and returns it to at a later time, Thus it has to be changeable (Mutable).
Also from the docs You can see in the example it has to be Mutable.
Also note that using enableForegroundDispatch
is actually not the best way to use NFC using enableReaderMode
is a newer and much better API to use NFC. enableReaderMode
does not use Intent's and gives you more control, it is easy to do NFC operations in a background Thread (which is recommended), for writing to NFC Tag's it is much more reliable and leads to less errors.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论