Статьи

Первые шаги с NFC в Android

1425864749_nfc-256 Этот пост описывает, как использовать NFC в Android . Технология NFC расшифровывается как Near Field Communication, и вы можете найти спецификацию на NFC Forum . В этом первом посте мы проанализируем некоторые основные аспекты NFC и опишем, как мы можем реализовать приложение в Android, которое обрабатывает теги NFC.

Если вы хотите поэкспериментировать с NFC, есть несколько веб-сайтов, где вы можете купить NFC за несколько евро.

NFC можно использовать в разных ситуациях: мы можем использовать его для включения нашей Жены, когда мы дома, или запускаем задачи и так далее.

Мы сосредоточим наше внимание на данных NDEF, которые представляют собой особый тип тега NFC. Есть несколько основных шагов, которые мы должны выполнить перед использованием NFC.

NFC фильтр

Когда мы используем тег NFC, первое, что мы хотим, — это наше приложение уведомляется, когда мы приближаемся к тегу NFC. Для этой цели мы используем фильтр намерений . Android SDK предоставляет три разных фильтра, которые мы можем использовать с разным уровнем приоритета:

  • ACTION_NDEF_DISCOVERED
  • ACTION_TECH_DISCOVERED
  • ACTION_TAG_DISCOVERED

Мы концентрируем наше внимание на ACTION_NDEF_DISCOVERED, который имеет самый высокий уровень приоритета. Как уже было сказано, наша цель — получать уведомления, когда смартфон находится рядом с тегом NFC, и, если у нас установлено только это приложение и мы можем обрабатывать этот тег NFC, мы хотим, чтобы приложение запускалось немедленно. Для этого мы регистрируем фильтр в Manifest.xml:

01
02
03
04
05
06
07
08
09
10
    package="com.survivingwithandroid.nfc" >
 
    ....
     <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data  android:mimeType="text/plain"/>
     </intent-filter>
<manifest>

В строке 6 мы регистрируем наше приложение, чтобы оно могло быть уведомлено с помощью ACTION_NDEF_DISCOVERED . Мы можем использовать разные типы фильтров, в этом примере (в строке 8) мы использовали mime-тип . Другими словами, когда NFC-тег NDEF обнаружен и у него есть текст MIME-типа / обычный текст, наше приложение будет запущено. Мы можем фильтровать, используя несколько типов пантомимы, а не только текст / боль. Более того, мы можем использовать фильтры другого типа, такие как android: схема, для фильтрации по протоколу или по строковому шаблону.

Отправка NFC Foreground

Фильтрация с намерениями работает, если наше приложение не на переднем плане. Если наше приложение работает на переднем плане, оно не будет уведомлено, если поднесет наш смартфон к тегу NFC. В этом случае мы должны использовать другую технику, называемую диспетчеризацией NFC Foreground . Первым шагом является определение в нашем коде фильтра намерений (как мы это делали в manifest.xml):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
@Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        Intent nfcIntent = new Intent(this, getClass());
        nfcIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
 
        nfcPendingIntent =
                PendingIntent.getActivity(this, 0, nfcIntent, 0);
 
        IntentFilter tagIntentFilter =
                new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        try {
            tagIntentFilter.addDataType("text/plain");
            intentFiltersArray = new IntentFilter[]{tagIntentFilter};
        }
        catch (Throwable t) {
            t.printStackTrace();
        }
    }

Теперь мы должны зарегистрировать наш фильтр и сделать это в методе onResume следующим образом:

1
2
3
4
5
6
7
8
9
protected void onResume() {
        super.onResume();
       nfcAdpt.enableForegroundDispatch(
                this,
                nfcPendingIntent,
                intentFiltersArray,
                null);
        handleIntent(getIntent());
    }

Также следует помнить о том, что необходимо отключить диспетчеризацию переднего плана, как только приложение перейдет в фоновый режим, и лучшее место для этого — метод onPause.

1
2
3
4
5
@Override
    protected void onPause() {
        super.onPause();
        nfcAdpt.disableForegroundDispatch(this);
    }

где nfcAdpt — это адаптер NFC.

Обработка NFC с помощью NFCAdapter

После того, как мы создали наши фильтры, нам нужно взаимодействовать с компонентом NFC в нашем смартфоне. Для этого мы используем NfcAdapter , предоставляемый Android SDK. Используя этот класс, мы можем проверить, например, поддерживается ли NFC нашим смартфоном или NFC включен или выключен:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
@Override
    protected void onCreate(Bundle savedInstanceState) {
       ...
       nfcAdpt = NfcAdapter.getDefaultAdapter(this);
       // Check if the smartphone has NFC
       if (nfcAdpt == null) {
            Toast.makeText(this, "NFC not supported", Toast.LENGTH_LONG).show();
            finish();
       }
       // Check if NFC is enabled
       if (!nfcAdpt.isEnabled()) {
            Toast.makeText(this, "Enable NFC before using the app", Toast.LENGTH_LONG).show();
       }
    }

Данные NFC: полезная нагрузка

Как только мы знаем, как обрабатывать теги NFC, мы хотим прочитать содержимое тегов. Существует несколько типов контента, определенных в спецификациях NFC:

  • Форум NFC известного типа
  • Медиа-тип
  • Абсолютный URI
  • NFC Forum внешний тип

У каждого типа есть своя полезная нагрузка. Вообще говоря, данные NDEF NFC состоят из сообщения . Сообщение может содержать одну или несколько записей . Каждую запись составляют заголовок и полезная нагрузка (реальная информация). К настоящему времени, если мы хотим прочитать данные внутри NFC-тега NFC, мы можем использовать:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Override
    public void onNewIntent(Intent intent) {
        Log.d("Nfc", "New intent");
        getTag(intent);
    }
 
    private void getTag(Intent i) {
        if (i == null)
            return ;
 
        String type = i.getType();
        String action = i.getAction();
        List dataList = new ArrayList();
 
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
            Log.d("Nfc", "Action NDEF Found");
            Parcelable[] parcs = i.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
 
            for (Parcelable p : parcs) {
                recNumberTxt.setText(String.valueOf(numRec));
                NdefRecord[] records = msg.getRecords();
                for (NdefRecord record: records) {
                    short tnf = record.getTnf();
                    // Here we handle the payload
 
                }
            }
       }
    }
Ссылка: Первые шаги с NFC в Android от нашего партнера JCG Франческо Аццолы в блоге Surviving w / Android .