Android 为什么总是技术发现或标签发现,而不是NDEF发现?

Android 为什么总是技术发现或标签发现,而不是NDEF发现?,android,nfc,intentfilter,ndef,Android,Nfc,Intentfilter,Ndef,我刚刚接触安卓系统的NFC。我有几个问题要问。首先,让我介绍一下代码。在我的程序中,它只是简单地从记录中检索有效负载,并将它们作为字符串记录 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); adapter = NfcAdapter.getDef

我刚刚接触安卓系统的NFC。我有几个问题要问。首先,让我介绍一下代码。在我的程序中,它只是简单地从记录中检索有效负载,并将它们作为字符串记录

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    adapter = NfcAdapter.getDefaultAdapter(this);
    nfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP),  0);
    nfcFilter = new IntentFilter[]{
                new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED),
                new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED),
                new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)
            };
    techList = new String[][]{{Ndef.class.getName()}};
}

@Override
public void onResume(){
    super.onResume();

    if (adapter != null){
        adapter.enableForegroundDispatch(this, nfcPendingIntent, nfcFilter, techList);
        if (!adapter.isEnabled()){
            Toast.makeText(this, "please enable your nfc", Toast.LENGTH_SHORT).show();
        }
    } else {
        Toast.makeText(this, "your device do not have nfc.", Toast.LENGTH_SHORT).show();
    }
}

@Override
public void onPause(){
    super.onPause();
    if (adapter != null){
        adapter.disableForegroundDispatch(this);
    }
}

@Override
protected void onNewIntent(Intent intent){
    String TAG = "onNewIntent";
    super.onNewIntent(intent);

    Log.d(TAG, "action: "+intent.getAction());
    //Log.d(TAG, "type: "+intent.getType());
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())){
        Parcelable[] rawMsg = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        if (rawMsg != null){
            for (int i=0; i<rawMsg.length; i++){
                NdefMessage msg = (NdefMessage)rawMsg[i];
                NdefRecord[] records = msg.getRecords();
                for (int j=0; j<records.length; j++){
                    Log.d(TAG, records[j].toMimeType()+"");
                    byte [] payload = records[j].getPayload();
                    if (payload != null && payload.length > 0){
                        Log.d(TAG, new String(payload, 1, payload.length-1));
                    }
                }
            }
        }
    } else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())){

    } else if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
        Parcelable[] rawMsg = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        if (rawMsg != null){
            for (int i=0; i<rawMsg.length; i++){
                NdefMessage msg = (NdefMessage)rawMsg[i];
                NdefRecord[] records = msg.getRecords();
                for (int j=0; j<records.length; j++){
                    Log.d(TAG, records[j].toMimeType()+"");
                    byte [] payload = records[j].getPayload();
                    if (payload != null && payload.length > 0){
                        Log.d(TAG, new String(payload, 1, payload.length-1)+"("+j+")");
                    }
                }
            }
        }
    }
}
这里有两个问题:

结果告诉前台调度器仅捕获使用techList发现的TECH_和未使用techList发现的TAG_,但未捕获发现的NDEF_

当我离开应用程序并扫描NFC标签时,它会自动将我带到我将url作为记录的网站。它如何告诉此记录包含打开浏览器或拨打电话的操作

NDEF_查找到的意图过滤器通常只有在其关联的数据类型与标记上的NDEF消息匹配时,才会出现某些异常。例如,数据类型规范*/*将匹配任何MIME类型:

IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
    ndef.addDataType("*/*");
} catch (MalformedMimeTypeException e) {}
nfcFilter = new IntentFilter[]{
        ndef,
        new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED),
        new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)
};
类似地,如果您只想触发特定URL,可以使用:

IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
ndef.addDataScheme("http");
ndef.addDataAuthority("www.example.com", null);
请注意,对于前台调度系统,您通常只注册要匹配的最通用的意图过滤器。因此,如果您的前台分派意图筛选器已包含已发现的操作标记,则无需添加任何更具体的筛选器,如TECH_DISCOVERD或NDEF_DISCOVERD,因为您的活动将已收到任何已发现的标记。这同样适用于结合Ndef标记技术发现的技术:它已经包含任何会触发Ndef标记的标记。然而请注意,TAG_Discovery intent filter的特殊之处在于,当与前台调度一起使用时,它意味着“全包”,而当在基于清单的intent filter中使用时,它意味着“仅回退”(fallback only),即仅当与任何其他应用程序没有更好的匹配时才进行匹配。

NDEF_Discovery intent filter通常只存在一些异常匹配如果它具有与标记上的NDEF消息匹配的关联数据类型。例如,数据类型规范*/*将匹配任何MIME类型:

IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
    ndef.addDataType("*/*");
} catch (MalformedMimeTypeException e) {}
nfcFilter = new IntentFilter[]{
        ndef,
        new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED),
        new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)
};
类似地,如果您只想触发特定URL,可以使用:

IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
ndef.addDataScheme("http");
ndef.addDataAuthority("www.example.com", null);

请注意,对于前台调度系统,您通常只注册要匹配的最通用的意图过滤器。因此,如果您的前台分派意图筛选器已包含已发现的操作标记,则无需添加任何更具体的筛选器,如TECH_DISCOVERD或NDEF_DISCOVERD,因为您的活动将已收到任何已发现的标记。这同样适用于结合Ndef标记技术发现的技术:它已经包含任何会触发Ndef标记的标记。然而请注意,TAG_Discoveryd intent filter的特殊之处在于,在前台调度中使用时,它意味着“全包”,而在基于清单的intent filter中使用时,它意味着“仅回退”(fallback only),即只有在与任何其他应用程序没有更好的匹配时才匹配。

为什么我不能触发NDEF_Discoveryd操作???为什么我不能触发NDEF U Discoveryd操作操作???我添加了数据类型,但它仍然不是NDEFèU发现的操作。如果改用TAG_DISCOVERED,是否可以类似地检索消息?所有消息都遵循NDEF格式吗?@Simon您的标签上有什么NDEF消息?如果您收到上述三个意向过滤器组合的TAG_DISCOVERED intent操作,则您的标记不包含任何NDEF消息/未被检测为NDEF标记。我有2条文本/普通记录,标记支持NDEF、nfca、ultralight技术……如何知道标记是否包含NDEF消息?或检测为NDEF?该结构确实遵循NDEF消息,正如我在代码中所做的那样运行良好,因此您可以使用一些可用的标记检查工具(例如my)进行检查。我添加了数据类型,但它仍然不是NDEF_发现的操作。如果改用TAG_DISCOVERED,是否可以类似地检索消息?所有消息都遵循NDEF格式吗?@Simon您的标签上有什么NDEF消息?如果您收到上述三个意向过滤器组合的TAG_DISCOVERED intent操作,则您的标记不包含任何NDEF消息/未被检测为NDEF标记。我有2条文本/普通记录,标记支持NDEF、nfca、ultralight技术……如何知道标记是否包含NDEF消息?或检测为NDEF?该结构确实遵循NDEF消息,正如我在代码中所做的那样运行良好,因此您可以使用一些可用的标记检查工具进行检查,例如my。