👁 2037
Привет! У нас тут возникла задачка на работе, о решении которой я хотел бы с вами поделиться.
В общем, у нас есть внутрикорпоративное приложение с 3 кнопками (пришел, ушел на обед, ушел домой), которое внутри нашей электронной системы отмечает нас. Его написал мой напарник. Моя задача состояла в том, чтобы облегчить жизнь людям и запилить работу этого приложения с NFC-меткой.
Сперва, конечно, читаем доку.
У нас для такой цели была гордо выдана карточка московского метро 2013 года выпуска. Как потом оказалось, это карта типа Mifare Ultralight. Ну да ладно, читать её проще, чем Classic, а для идентификации просто строку байт будем использовать.
Добавим волшебные строчки с разрешениями в AndroidManifest.xml
<uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc" android:required="true" /> ...
Для активити, в которой у нас будет обрабатываться Intent с NFC, пропишем intent-filter и meta-data
<intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED"/> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" />
В ресурсе nfc_tech_filter.xml укажем, с какого типа картой NFC будем работать
<?xml version="1.0" encoding="utf-8"?> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.MifareUltralight</tech> </tech-list> </resources>
Теперь открываем Activity. Вот отрывок из моего onCreate-метода (тут важное замечание, вся работа с NFC описывается только в Activity)
mNfcAdapter = NfcAdapter.getDefaultAdapter(this); if (mNfcAdapter == null) { Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show(); } else { mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); try { ndef.addDataType("*/*"); } catch (IntentFilter.MalformedMimeTypeException e) { throw new RuntimeException("fail", e); } mFilters = new IntentFilter[] { ndef, }; mTechLists = new String[][] { new String[] { MifareUltralight.class.getName() } }; handleIntent(getIntent()); }
Соответственно, напишем метод handleIntent, куда будем передавать наш NFC-шный интент:
public void handleIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
MifareUltralight mul = MifareUltralight.get(tagFromIntent);
byte[] data;
try {
mul.connect();
if (mul.getType() == MifareUltralight.TYPE_ULTRALIGHT) {
AppLog.d("type is ULTRALIGHT");
}
if (mul.getType() == MifareUltralight.TYPE_ULTRALIGHT_C) {
AppLog.d("type is ULTRALIGHT_C");
}
if (mul.getType() == MifareUltralight.TYPE_UNKNOWN) {
AppLog.d("type is UNKNOWN");
}
data = mul.readPages(0);
String dataString = byteArrayToHex(data);
AppLog.d(dataString);
//а тут будем делать обработку данных, которые у нас уже есть
} catch (IOException e) {
e.printStackTrace();
}
}
}
Собственно, там я написал уже обработчик, который просто сравнивал массивы данных и делал свою работу.
Мне кажется, довольно просто вышло.
Теперь отмечаемся вот такой штуковиной.