👁 2070
Привет! У нас тут возникла задачка на работе, о решении которой я хотел бы с вами поделиться.
В общем, у нас есть внутрикорпоративное приложение с 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();
}
}
}
Собственно, там я написал уже обработчик, который просто сравнивал массивы данных и делал свою работу.
Мне кажется, довольно просто вышло.

Теперь отмечаемся вот такой штуковиной.