仅适用于特定NFC标签的应用程序

时间:2016-04-04 13:39:24

标签: android tags nfc intentfilter uniqueidentifier

我当前的Android应用程序识别任何NFC标签并执行所需的功能。但是,我希望它只能使用具有特定UID的特定标记。实现这一目标的最佳方法是什么?

相关代码的UID为:046a0b42402b84

我的NFC功能代码如下:

public class NFC extends AppCompatActivity {

    NfcAdapter nfcAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_nfc);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        String username = getIntent().getStringExtra("Username");

        TextView tv = (TextView) findViewById(R.id.TVusername);
        tv.setText(username);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }


        });

       nfcAdapter = NfcAdapter.getDefaultAdapter(this);

        if(nfcAdapter!=null && nfcAdapter.isEnabled()) {

        }else{
            finish();
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {

        Toast.makeText(this, "NFC intent received!", Toast.LENGTH_LONG).show();

        super.onNewIntent(intent);
    }

        @Override
        protected void onResume() {

        Intent intent = new Intent(this, AttendanceRegistration.class);
        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,  0);
        IntentFilter[] intentFilter = new IntentFilter[]{};

        nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFilter, null);

         super.onResume();
     }


    @Override
    protected void onPause() {

        nfcAdapter.disableForegroundDispatch(this);

        super.onPause();
    }

         @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

1 个答案:

答案 0 :(得分:0)

Android不允许通过其UID /防冲突标识符/序列号为特定标签注册NFC标签检测通知。如果您希望仅通过特定NFC标签启动应用程序(通过在ANdroidManifest.xml中注册intent过滤器),则需要存储NDEF消息(包含可以过滤的自定义NDEF记录或Android应用程序记录标签

如果您不希望应用程序由标记启动,并且只想在活动位于前台时检测标记(您的代码已尝试通过注册前台调度系统来执行此操作),则可以接收所有已发现标记的通知,只需根据其UID过滤标记。

首先,您需要正确注册前台调度系统以接收任何标记的通知(请注意,您无法使用PendingIntent注册前台调度以进行其他活动!):

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

    Intent intent = new Intent(this, getClass());
    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,  0);
    nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
}

然后,您可以在onNewIntent中接收NFC发现意图,并根据标记UID对其进行过滤:

@Override
protected void onNewIntent(Intent intent) {
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction()) ||
        NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()) ||
        NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

        byte[] uid = tag.getId();
        byte[] referenceUid = new byte[]{ (byte)0x04, (byte)0x6a, (byte)0x0b, (byte)0x42, (byte)0x40, (byte)0x2b, (byte)0x84 };

        if (Arrays.equals(referenceUid, uid)) {
            // do something
        }
    }
}