@Override protected String doInBackground(Intent... params) { Intent mIntent = params[0]; Tag tagFromIntent = mIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG); MifareClassic tag = MifareClassic.get(tagFromIntent); try { tag.connect(); } catch (IOException e) { // Die Karte wurde schnell entfernt, ist nicht schlimm, wir brauchen an // dieser Stelle nichts zu tun, es ist vorgesehen, dass es einfach weiter geht. } while (tag.isConnected()) { // Hier passiert nichts! Waehrend dieser Schleife werden naemlich // die Daten des Fahrers dargestellt. Man bleibt in der Schleife, // so lange man den Tag an dem NFC-Lesegeraet haelt. Wird der Tag // vom Lesegeraet entfernt, dann verlassen wir die Schleife. } return null; }
/** * Check if the reader is connected to the tag. * * @return True if the reader is connected. False otherwise. */ public boolean isConnected() { return mMFC.isConnected(); }
/** * Read a as much as possible from a sector with the given key. Best results are gained from a * valid key B (except key B is marked as readable in the access conditions). * * @param sectorIndex Index of the Sector to read. (For Mifare Classic 1K: 0-63) * @param key Key for the authentication. * @param useAsKeyB If true, key will be treated as key B for authentication. * @return Array of blocks (index 0-3 or 0-15). If a block or a key is marked with {@link * #NO_DATA} or {@link #NO_KEY} it means that this data could be read or found. On * authentication error "null" will be returned. * @throws TagLostException When tag is lost. * @see #mergeSectorData(String[], String[]) */ public String[] readSector(int sectorIndex, byte[] key, boolean useAsKeyB) throws TagLostException { boolean auth = authenticate(sectorIndex, key, useAsKeyB); String[] ret = null; // Read sector. if (auth) { // Read all blocks. ArrayList<String> blocks = new ArrayList<String>(); int firstBlock = mMFC.sectorToBlock(sectorIndex); int lastBlock = firstBlock + 4; if (mMFC.getSize() == MifareClassic.SIZE_4K && sectorIndex > 31) { lastBlock = firstBlock + 16; } for (int i = firstBlock; i < lastBlock; i++) { try { byte blockBytes[] = mMFC.readBlock(i); // mMFC.readBlock(i) must return 16 bytes or throw an error. // At least this is what the documentation says. // On Samsungs Galaxy S5 however, it sometimes // returns < 16 bytes for unknown reasons. if (blockBytes.length != 16) { throw new IOException(); } blocks.add(Common.byte2HexString(blockBytes)); } catch (TagLostException e) { throw e; } catch (IOException e) { // Could not read block. // (Maybe due to key/authentication method.) Log.d(LOG_TAG, "Error while reading block " + i + " from tag."); blocks.add(NO_DATA); if (!mMFC.isConnected()) { throw new TagLostException("Tag removed during readSector(...)"); } // After error reauthentication is needed. auth = authenticate(sectorIndex, key, useAsKeyB); } } ret = blocks.toArray(new String[blocks.size()]); int last = ret.length - 1; // Merge key in last block (sector trailer). if (!useAsKeyB) { if (isKeyBReadable(Common.hexStringToByteArray(ret[last].substring(12, 20)))) { ret[last] = Common.byte2HexString(key) + ret[last].substring(12, 32); } else { ret[last] = Common.byte2HexString(key) + ret[last].substring(12, 20) + NO_KEY; } } else { if (ret[0].equals(NO_DATA)) { // If Key B may be read in the corresponding Sector Trailer, // it cannot serve for authentication (according to NXP). // What they mean is that you can authenticate successfully, // but can not read data. In this case the // readBlock() result is 0 for each block. ret = null; } else { ret[last] = NO_KEY + ret[last].substring(12, 20) + Common.byte2HexString(key); } } } return ret; }