В этом руководстве вы познакомитесь с основами P2P (peer-to-peer) взаимодействия и создадите приложение для обмена большими файлами, такими как изображения и видео, с одного устройства на другое, используя NFC (ближняя связь) на Android.
1. Введение
NFC или Near Field Communication — это набор беспроводных технологий ближнего действия. Он обеспечивает обмен данными между тегом NFC и устройством с поддержкой NFC или между устройствами с поддержкой NFC на расстоянии не более 4 см.
Существует три режима работы NFC:
- Чтение и запись бесконтактных меток. Эти метки, как правило, очень маленькие и не требуют заряда аккумулятора. Они могут быть встроены во все виды объектов, таких как постеры фильмов, продукты, наклейки и так далее.
- Режим эмуляции карт: думайте об умных кредитных картах. Это позволяет устройству Android работать как смарт-карта. Очевидным преимуществом этого является то, что ваше устройство может действовать как одна карта, а затем действовать как другая при нажатии кнопки. Это один из способов, которым устройство Android может заменить ваш кошелек. Независимо от того, какую кредитную карту, проездной билет или билет вы используете, ваше устройство Android может олицетворять — конечно же, безопасно — этот элемент. Читатель на другой стороне транзакции считает, что он взаимодействует с этим элементом, хотя на самом деле он работает с устройством Android.
- Одноранговая связь: каждая сторона признает, что общается с другим устройством, а не просто с тегом. Протокол был разработан Google и позволяет двум устройствам отправлять сообщения туда и обратно.
Функция обмена данными между равноправными узлами (P2P) была добавлена в Android на уровне API 14 (Android 4.0, Ice Cream Sandwich) и называется Android Beam . Он обеспечивает быстрый обмен данными на коротких расстояниях между двумя устройствами Android с поддержкой NFC.
2. P2P-связь с Android Beam
Функция обмена данными Android Beam имеет два API: API передачи NDEF и API передачи файлов .
API передачи NDEF
Этот API был представлен на уровне API 14 (Android 4.0, Ice Cream Sandwich) и позволяет передавать небольшие объемы данных, такие как URL-адреса, контакты и т. Д. Данные для передачи должны быть отформатированы в NDEF (формат обмена данными NFC) и должны отправлено как сообщение NDEF.
API передачи файлов
API передачи файлов был представлен на уровне API 16 (Android 4.1, Jelly Bean) и позволяет передавать большие файлы, такие как изображения, видео и т. Д.
Есть некоторые предостережения, хотя. Android Beam работает только тогда, когда приложение, отправляющее данные, работает на переднем плане, а устройство, получающее данные, разблокировано.
API передачи файлов Android Beam имеет два дополнительных требования:
- Файлы, которые необходимо передать, должны находиться во внешнем хранилище.
- Файлы, которые необходимо передать, должны быть доступны для чтения всем.
В этом руководстве мы будем использовать API передачи файлов Android Beam из Android SDK, чтобы создать приложение, позволяющее пользователям обмениваться файлами между устройствами.
3. Требования
Из-за ограничений эмулятора приложение необходимо протестировать на двух физических устройствах Android с поддержкой NFC под управлением Android 4.1 или выше.
4. Начало работы
Используя Eclipse, создайте новый проект приложения для Android и назовите его NFCDemo .
Поскольку передача файлов Android Beam доступна только на устройствах под управлением Android 4.1+, нам необходимо установить для Minimum Required SDK значение API 16: Android 4.1 (Jelly Bean) .
5. Настройка файла манифеста
Чтобы использовать NFC в приложении Android, мы должны объявить разрешение NFC в файле манифеста, как показано ниже.
1
2
|
<uses-permission
android:name=»android.permission.NFC» />
|
Кроме того, для чтения файлов из внешнего хранилища объявите разрешение READ_EXTERNAL_STORAGE
как показано ниже.
1
2
|
<uses-permission
android:name=»android.permission.READ_EXTERNAL_STORAGE» />
|
Не каждое устройство Android поддерживает NFC. Чтобы убедиться, что наше приложение отображается в Google Play только для тех устройств, которые поддерживают NFC, добавьте элемент <uses-feature>
в файл манифеста.
1
2
3
|
<uses-feature
android:name=»android.hardware.nfc»
android:required=»true» />
|
Если NFC является необязательной функцией вашего приложения, вы можете пропустить элемент <uses-feature>
из файла манифеста и установить минимальную версию SDK на более низкий уровень API. В этом случае вам необходимо проверить, поддерживает ли устройство NFC и API Android Beam, и соответствующим образом обновить пользовательский интерфейс.
6. Создание макетов
Откройте файл макета activity_main.xml
и добавьте Button
как показано ниже. Как вы можете видеть, мы добавили Button
которую пользователь может нажать, чтобы начать передачу файла.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
<RelativeLayout
xmlns:android=»http://schemas.android.com/apk/res/android»
xmlns:tools=»http://schemas.android.com/tools»
android:layout_width=»match_parent»
android:layout_height=»match_parent»
android:padding=»16dp» >
<Button
android:layout_width=»fill_parent»
android:layout_height=»wrap_content»
android:padding=»8dp»
android:text=»Send File»
android:onClick=»sendFile» />
</RelativeLayout>
|
7. Реализация передачи файлов
Откройте класс MainActivity
и замените текущую реализацию показанной ниже. Не беспокойтесь о реализации на данный момент. Я объясню каждый шаг в данный момент.
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
package com.tutsplus.nfcdemo;
import java.io.File;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.nfc.NfcAdapter;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
private NfcAdapter nfcAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PackageManager pm = this.getPackageManager();
// Check whether NFC is available on device
if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
// NFC is not available on the device.
Toast.makeText(this, «The device does not has NFC hardware.»,
Toast.LENGTH_SHORT).show();
}
// Check whether device is running Android 4.1 or higher
else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
// Android Beam feature is not supported.
Toast.makeText(this, «Android Beam is not supported.»,
Toast.LENGTH_SHORT).show();
}
else {
// NFC and Android Beam file transfer is supported.
Toast.makeText(this, «Android Beam is supported on your device.»,
Toast.LENGTH_SHORT).show();
}
}
public void sendFile(View view) {
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
// Check whether NFC is enabled on device
if(!nfcAdapter.isEnabled()){
// NFC is disabled, show the settings UI
// to enable NFC
Toast.makeText(this, «Please enable NFC.»,
Toast.LENGTH_SHORT).show();
startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
}
// Check whether Android Beam feature is enabled on device
else if(!nfcAdapter.isNdefPushEnabled()) {
// Android Beam is disabled, show the settings UI
// to enable Android Beam
Toast.makeText(this, «Please enable Android Beam.»,
Toast.LENGTH_SHORT).show();
startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS));
}
else {
// NFC and Android Beam both are enabled
// File to be transferred
// For the sake of this tutorial I’ve placed an image
// named ‘wallpaper.png’ in the ‘Pictures’ directory
String fileName = «wallpaper.png»;
// Retrieve the path to the user’s public pictures directory
File fileDirectory = Environment
.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
// Create a new file using the specified directory and name
File fileToTransfer = new File(fileDirectory, fileName);
fileToTransfer.setReadable(true, false);
nfcAdapter.setBeamPushUris(
new Uri[]{Uri.fromFile(fileToTransfer)}, this);
}
}
}
|
8. Тестирование приложения
Прежде чем мы углубимся в код, давайте посмотрим, какие шаги нам нужно предпринять для передачи файла с одного устройства на другое.
Шаг 1
Подключите одно из двух устройств Android к рабочей станции разработчика через USB с включенной отладкой USB . Давайте назовем это устройство отправителем .
Шаг 2
Включить NFC и Android Beam на отправителя. Нажмите F11 для отладки приложения. Это установит и запустит NFCDemo на отправителе.
Шаг 3
Включите NFC на втором устройстве, приемнике .
Шаг 4
Нажмите кнопку « Отправить файл» и расположите устройства близко друг к другу, чтобы позволить NFC выполнять свою работу. На отправителе должно появиться сообщение Touch to ray. Нажмите на экран, чтобы начать передачу.
Шаг 5
Получатель должен отобразить уведомление в строке состояния, чтобы указать ход передачи файла.
Шаг 6
Если передача файла завершена успешно, пользователю отображается сообщение завершения луча .
9. Расшифровка кода
Давайте посмотрим на код, который делает все это возможным.
Определить возможности устройства
Как упоминалось ранее, если NFC является дополнительной функцией нашего приложения, мы должны проверить поддержку NFC и Android Beam. Эта проверка может быть выполнена в любом месте нашего приложения. В этом примере я поместил код в метод MainActivity
класса MainActivity
.
Шаг 1
Получите ссылку на PackageManager
.
1
|
PackageManager pm = this.getPackageManager();
|
Класс PackageManager
содержит информацию обо всех пакетах, установленных на устройстве.
Шаг 2
Вызовите метод hasSystemFeature
для объекта hasSystemFeature
чтобы определить, поддерживает ли устройство NFC. Этот метод возвращает true
если требуемая функция поддерживается устройством.
1
2
3
4
5
6
|
if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
// NFC is not available on the device.
}
else {
// NFC is available on the device.
}
|
Шаг 3
Если устройство поддерживает NFC, то мы должны проверить версию Android устройства. Версия Android (уровень API), работающая на устройстве, доступна через android.os.Build.VERSION.SDK_INT
. Если версия больше или равна 16, Build.VERSION_CODES.JELLY_BEAN
, то устройство поддерживает передачу файлов Android Beam.
01
02
03
04
05
06
07
08
09
10
|
if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
// NFC is not available on the device.
}
// Check whether device is running Android 4.1 or higher
else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
// Android Beam feature is not supported.
}
else {
// NFC and Android Beam file transfer is supported.
}
|
Инициировать передачу файлов
После того, как мы определили, что устройство обладает необходимыми возможностями, мы можем начать передачу файла с помощью Android Beam.
Шаг 1
Получите ссылку на NfcAdapter
.
1
|
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
|
Задача NfcAdapter
— управлять обменом данными между тегом NFC и устройством с поддержкой NFC или между двумя устройствами с поддержкой NFC.
Шаг 2
Адаптер можно включить или отключить. Чтобы определить, включен ли адаптер, вызовите метод NfcAdapter
объекта NfcAdapter
.
1
2
3
4
5
6
7
|
// Check whether NFC is enabled on device
if (!nfcAdapter.isEnabled()) {
// NFC is disabled, show the settings UI to enable NFC
}
else {
// NFC is enabled
}
|
Этот метод возвращает true
если NFC включен на устройстве. Если NFC отключен, мы предлагаем пользователю включить его и показать пользовательский интерфейс настроек NFC.
1
|
startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
|
Шаг 3
Аналогично, функция Android Beam также может быть включена или отключена. Чтобы проверить его состояние, вызовите метод NfcAdapter
объекта NfcAdapter
.
01
02
03
04
05
06
07
08
09
10
11
|
// Check whether NFC is enabled on device
if (!nfcAdapter.isEnabled()) {
// NFC is disabled, show the settings UI to enable NFC
}
// Check whether Android Beam feature is enabled on device
else if (!nfcAdapter.isNdefPushEnabled()) {
// Android Beam is disabled, show the settings UI to enable Android Beam
}
else {
// NFC and Android Beam both are enabled
}
|
Если этот метод возвращает false
, мы предлагаем пользователю включить его и показать пользовательский интерфейс настроек Android Beam.
1
|
startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS));
|
Если включены и NFC, и Android Beam, мы можем продолжить передачу файла.
Шаг 4
Создайте новый File
используя каталог, в котором расположен файл на устройстве, и имя файла. Чтобы проверить передачу файлов, я добавил изображение с именем wallpaper.png в каталог Pictures во внешнем хранилище.
1
2
|
// Create a new file using the specified directory and name
File fileToTransfer = new File(fileDirectory, fileName);
|
Шаг 5
Вызовите метод NfcAdapter
объекта NfcAdapter
и передайте URI файла для передачи.
1
2
|
nfcAdapter.setBeamPushUris(new Uri[]{Uri.fromFile(fileToTransfer)},
this);
|
Метод setBeamPushUris
принимает массив объектов Uri
. Если вы хотите отправить более одного файла, вы можете передать несколько URI адаптеру.
URI, переданные методу setBeamPushUris
помещаются в очередь адаптером и передаются на принимающее устройство, как только оно оказывается в непосредственной близости от отправляющего устройства.
Вывод
В этом уроке вы узнали об основах NFC на Android. Вы также узнали, как ограничить доступ к приложению неподдерживаемыми устройствами с помощью файла манифеста и определить возможности устройства во время выполнения. Для отправки файлов с использованием NFC мы использовали класс NfcAdapter
.
Хотя я попытался осветить основы работы с API-интерфейсом передачи файлов Android Beam, чтобы помочь вам начать работу, еще многое предстоит изучить. Если вы хотите узнать больше, я советую вам посетить портал разработчиков Android для получения дополнительной информации.