获取NTAG和MIFARE智能卡的NFC TagID

时间:2015-04-21 11:13:35

标签: android eclipse android-intent nfc mifare

我是NFC技术的新手,并且开始考虑读写标签。为了阅读目的,我使用的是MIRFARE 1K智能卡,写作我使用的是NTAG203。我想要的只是在读取过程中获取TagID并将TagID和日期时间戳发送到NTAG203。

的问题:

  1. 我的应用程序在编译时遇到困难。它一直给我生成错误生成最终存档:无法创建'C:\ Android WS \ TabletApp \ bin \ TabletApp.apks':访问被拒绝错误。我清理项目并重新启动Eclipse但是徒劳无功。只有当我重新启动笔记本电脑时它才会消失。有什么建议吗?

  2. 当应用程序运行时,它仍然没有给我ID。我扫描我的卡/标签,一次又一次地加载MainActivity(ScanningActivity)。控件不会比这更进一步。关于如何处理它的任何建议?

  3. public class ScanningActivity extends Activity {
        private NfcAdapter sNfcAdapter;
        Locale locale = new Locale("en", "US");
        byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
        boolean encodeInUtf8 = false;
        Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
        int utfBit = encodeInUtf8 ? 0 : (1 << 7);
        char status = (char)(utfBit + langBytes.length);
    
        static String bin2hex(byte[] data) {
            return String.format("%0" + (data.length * 2) + "X", new BigInteger(1, data));
        }
        /* write to tag */
    
        boolean writeNdefMessageToTag(NdefMessage message, Tag detectedTag) throws FormatException {
            int size = message.toByteArray().length;
            try {
                Ndef ndef = Ndef.get(detectedTag);
                if (ndef != null) {
                    ndef.connect();
                    if (!ndef.isWritable()) {
                        Toast.makeText(this, "Tag is read-only.", Toast.LENGTH_SHORT).show();
                        return false;
                    }
                    if (ndef.getMaxSize() < size) {
                        Toast.makeText(this,
                                       "The data cannot be written since the tag capacity is" + ndef.getMaxSize() +
                                       " bytes and the data to be transferred is " + size + " bytes",
                                       Toast.LENGTH_LONG).show();
                        return false;
                    }
    
                    ndef.writeNdefMessage(message);
                    ndef.close();
                    Toast.makeText(this, "Data sent to the Tag", Toast.LENGTH_LONG).show();
                    return true;
    
                } else {
                    NdefFormatable ndefFormat = NdefFormatable.get(detectedTag);
                    if (ndefFormat != null) {
                        try {
                            ndefFormat.connect();
                            ndefFormat.format(message);
                            ndefFormat.close();
                            Toast.makeText(this, "Data sent", Toast.LENGTH_LONG).show();
                            return true;
                        } catch (IOException e) {
                            Toast.makeText(this, "Unable to format tag", Toast.LENGTH_LONG).show();
                            return false;
                        }
                    } else {
                        Toast.makeText(this, "Not supported tag", Toast.LENGTH_LONG).show();
                        return false;
                    }
    
                }
            } catch (IOException e) {
                Toast.makeText(this, "Sending failed", Toast.LENGTH_LONG).show();
            }
            return false;
    
        }
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_scanning);
    
            TextView tg = (TextView)findViewById(R.id.tagid);
            final TextView tvtime = (TextView)findViewById(R.id.datetime);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss a");
            String currentTimeStamp = dateFormat.format(new Date()); // Find todays date
            tvtime.setText(currentTimeStamp);
    
            sNfcAdapter = NfcAdapter.getDefaultAdapter(this);
    
            IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
            tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
            if (sNfcAdapter == null) {
                Toast.makeText(this, "This device does not support NFC or you have not scanned the card properly",
                               Toast.LENGTH_LONG).show();
                return;
            }
    
            if (!sNfcAdapter.isEnabled()) {
                Toast.makeText(this, "Looks like the NFC is not enabled on your device", Toast.LENGTH_LONG).show();
                new AlertDialog.Builder(this).setTitle("NFC disabled").setMessage(
                        "Looks like the NFC is not enabled on your device. Please enable it.").setPositiveButton(
                        "Ok", null).show();
            }
            if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(getIntent().getAction())) {
                Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
                try {
                    String TagID = tag.getId().toString();
                    tg.setText(bin2hex(tag.getId()));
                    Toast.makeText(getApplicationContext(), bin2hex(tag.getId()), Toast.LENGTH_LONG).show();
                    Toast.makeText(this, TagID, Toast.LENGTH_LONG).show();
                } catch (Exception ex) {
                    new AlertDialog.Builder(this).setTitle("Error!").setPositiveButton("Ok",
                                                                                       new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            Intent i = new Intent(ScanningActivity.this, ScanningActivity.class);
                            startActivity(i);
                        }
                    }).setMessage(ex.getMessage() + "\n\nPlease click Ok. This will restart the application").create().show();
    
                    new AlertDialog.Builder(this).setTitle("Transferring the data").setPositiveButton("Ok",
                                                                                                      new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // TODO Auto-generated method stub
                            TextView tvData = (TextView)findViewById(R.id.Data);
                            if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
                                Tag tag1 = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
                                String DataToSend = tvtime.getText().toString() + tag1.getId().toString();
                                //String DataToSend = "Data";
                                //tvData.setText(tvtime.getText().toString()+tag.getId().toString());
                                byte[] textBytes = DataToSend.getBytes(utfEncoding);
                                byte[] dataa = new byte[1 + langBytes.length + textBytes.length];
                                dataa[0] = (byte)status;
                                System.arraycopy(langBytes, 0, dataa, 1, langBytes.length);
                                System.arraycopy(textBytes, 0, dataa, 1 + langBytes.length, textBytes.length);;
                                NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
                                                                       NdefRecord.RTD_TEXT, new byte[0], dataa);
                                NdefMessage newMessage = new NdefMessage(new NdefRecord[] { textRecord });
    
                                try {
                                    writeNdefMessageToTag(newMessage, tag1);
                                } catch (FormatException e) {
    
                                    e.printStackTrace();
                                }
                            }
                        }
                    }).setMessage(
                            "Place this tablet on the RFID Tag on the Microbiology Form. Keep it there until you get to the next screen").create().show();
    
                }
            }
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
    
            getMenuInflater().inflate(R.menu.scanning, menu);
            return true;
        }
    }
    

    和清单是

    <uses-permission android:name="android.permission.NFC"/>
    
    <uses-sdk
        android:minSdkVersion="13"
        android:targetSdkVersion="17" />
    
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.tabletapp.ScanningActivity"
            android:label="@string/app_name" >
            <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.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>
    </application>
    

    更新

    1. 该应用不会显示任何祝酒词。当我在设备上放一张卡片/标签时,我被问到我想要使用哪个应用程序。我选择了我们正在讨论的那个,并再次加载'ScanningActivity'(MainActivity)。既没有向我显示身份证也没有通过扫描活动。

    2. 我想从卡片中读取ID,然后将其与时间戳一起写入另一个标签。

1 个答案:

答案 0 :(得分:1)

你的代码中存在很多问题,所以我只关注最明显的问题:

  1. 您在AndroidManifest.xml中注册了NDEF_DISCOVERED。但是,在onCreate()中,只有在获得TAG_DISCOVERED意图时才会读取ID。您必须更改此设置以匹配NDEF_DISCOVERED意图。 (我在此假设您的标签包含与您的意图过滤器匹配的文本记录。)

  2. tag.getId().toString()不会为您提供更多有用信息,因为tag.getId()会返回一个字节数组。您可能总是希望使用bin2hex()方法将ID转换为人类可读的字符串。

  3. 单击按钮时,应避免与NFC标签进行任何交互。 (即您目前在onClick(DialogInterface dialog, int which)中所做的事情。)两者都应该将按钮点击和NFC交互视为人工输入,您应该避免同时需要两个人工输入。 (此外,Bott是基于事件的,您不能直接组合它们。)您可以在onClick()方法中设置一个标志,指示在下次NFC发现事件时应将数据写入标签。

  4. 如果您要扫描第一个标记,由于此事件而启动您的活动,并在扫描第二个标记时保持活动处于打开状态,则应使用foreground dispatch system(另请参阅{{3 }})。这样,前台活动可以处理标签的重复扫描而不会重新启动(并且不会控制任何其他可能由标签触发的活动)。