Статьи

Создание интерфейса API Restful с использованием Android Things

Создание интерфейса API Restful с использованием Android Things полезно, когда нам нужно подключить Android Things к внешней системе. В этой статье объясняется, как создать интерфейс API Restful с помощью Android Things, чтобы другие приложения или приложения могли вызывать этот API. Существует несколько сценариев, в которых Android Things должен быть интегрирован с внешними системами, и для вызова его сервисов необходим интерфейс Restful. Даже если существуют разные решения этой проблемы интеграции, реализация интерфейса API Restful в Android Things гарантирует большую совместимость с другими системами, реализованными с использованием других технологий.

Мы уже обсуждали, как обмениваться данными между Android Things и Firebase или как интегрировать Android Things с облачной платформой. В этой статье рассматривается другой аспект интеграции. В зависимости от сценария, с которым нам приходится сталкиваться, мы можем выбрать правильную стратегию интеграции. Мы не должны забывать, что одним из лучших вариантов обмена данными между различными системами является использование протокола MQTT.

Чтобы сосредоточить наше внимание на процессе создания интерфейса API Restful в Android Things, мы будем использовать простой датчик, который считывает температуру, давление и влажность. Этот датчик является BMP280, который является датчиком I2C.

Этот учебник состоит из двух частей:

  1. Схема: как подключить сенсор к Android Things
  2. Как создать интерфейс API Restful для чтения данных датчика

Как подключить BMP280 к Android Things

На этом первом шаге мы расскажем, как подключить датчик BMP280 к Android Things. В любом случае, эта тема несколько раз освещалась в этом блоге, просто чтобы освежить вашу память, BMP280 — это датчик I2C, поэтому он подключается к Android Things с помощью 4 контактов:

  1. Vcc
  2. земля
  3. Часы (CLK)
  4. Данные (SDA)

Схема, показывающая соединения:

Пожалуйста, обратитесь к вводу / выводу Android Things Peripherals, чтобы узнать контакты, используемые в этом проекте. В этом проекте используется Raspberry Pi, в любом случае вы можете использовать любую платформу, совместимую с Android Things.

Создайте новый проект с помощью Android Things Studio и добавьте следующую зависимость в файл Gradle:

1
2
3
4
dependencies {
 ...
 compile 'com.google.android.things.contrib:driver-bmx280:0.4'
}

Давайте создадим новый класс, который управляет подключением к датчику и читает температуру и давление:

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
package com.survivingwithandroid.androidthings.api;
 
import com.google.android.things.contrib.driver.bmx280.Bmx280;
import com.google.android.things.pio.PeripheralManagerService;
import java.io.IOException;
 
public class DeviceManager {
 
    private static DeviceManager me;
    private static final String I2C_BUS = "I2C1";
    private Bmx280 sensor;
 
    private DeviceManager() {
        init();
    }
 
    public static final DeviceManager getInstance() {
        if (me == null)
            me = new DeviceManager();
 
        return me;
    }
 
    private void init() {
        try {
            sensor = new Bmx280(I2C_BUS);
            sensor.setTemperatureOversampling(Bmx280.OVERSAMPLING_1X);
            sensor.setPressureOversampling(Bmx280.OVERSAMPLING_1X);
        }
        catch(IOException ioe) {
            ioe.printStackTrace();
        }
 
    }
 
    public float readTemp() {
        if (sensor != null)
            try {
                return sensor.readTemperature();
            } catch (IOException e) {
                e.printStackTrace();
            }
 
        return 0;
    }
 
    public float readPress() {
        if (sensor != null)
            try {
                return sensor.readPressure();
            } catch (IOException e) {
                e.printStackTrace();
            }
 
        return 0;
    }
}

Вот и все, теперь Android Things подключен к датчику, а приложение Android Things может считывать его значения.

Создание интерфейса API Restful с использованием Android Things

Это самая интересная часть этой статьи. Цель этого параграфа — создание интерфейса API Restful с использованием Android Things, чтобы мы могли предоставить набор служб для считывания температуры и давления с датчика. Другими словами, мы можем представить, что у нас есть внешнее приложение или приложение, которое хочет удаленно считывать температуру и давление с датчика.

Для этого в проекте Android Things используется среда Restlet . Эта структура предоставляет несколько реализаций, и одна из них предназначена для ОС Android. Он очень прост в использовании и упрощает процесс создания интерфейса API Restful в Android.

Процесс предоставления интерфейса Restful API состоит из трех этапов:

  1. Определение ресурсов для предоставления в качестве службы
  2. Создайте службу Android для обработки входящих запросов
  3. Определите простое действие Android для запуска и остановки службы

Прежде чем углубляться в детали реализации, необходимо добавить в наш проект Android Things следующие библиотеки:

  1. org.restlet.jar
  2. org.restlet.ext.nio.jar
  3. org.restlet.ext.json.jar

Эти библиотеки необходимы для реализации интерфейса API Restful с использованием Android-вещей.

Давайте посмотрим, как реализовать все эти шаги.

Шаг 1. Определение ресурса для предоставления в качестве службы

Ранее мы предполагали реализовать два API Restful: один для чтения температуры, а другой для чтения давления. Для этого необходимо реализовать два разных класса:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
public class SensorTempResource extends ServerResource {
 
    @Get("json")
    public Representation getTemperature() {
        JSONObject result = new JSONObject();
        float temp = DeviceManager.getInstance().readTemp();
 
        try {
            result.put("temp", temp);
        }
        catch(JSONException jsoe) {
 
        }
 
        return new StringRepresentation(result.toString(), MediaType.APPLICATION_ALL_JSON);
    }
}

а другой для давления:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
public class SensorPressResource extends ServerResource {
 
    @Get("json")
    public Representation getPressure() {
        JSONObject result = new JSONObject();
        float press = DeviceManager.getInstance().readPress();
        try {
            result.put("press", press);
        }
        catch(JSONException jsoe) {
 
        }
 
        return new StringRepresentation(result.toString(), MediaType.APPLICATION_ALL_JSON);
    }
}

Оба класса расширяют ServerResource и внешнее приложение может вызывать их с помощью HTTP-запроса GET, потому что мы хотим прочитать информацию с датчика.
Кроме того, этот API возвращает структуру данных JSON. В предыдущих классах вы можете заметить, что они вызывают DeviceManager , реализованный на предыдущих шагах, который обрабатывает соединение с датчиком.

Шаг 2. Создайте службу Android для обработки входящих запросов.

На этом этапе необходимо реализовать службу Android для обработки входящих запросов. Как вы, возможно, уже знаете, мы должны использовать Службу Android, потому что Служба Android имеет «более длительный» срок действия, чем активность Android, и если мы хотим, чтобы задача была выполнена, даже если пользовательский интерфейс приложения больше не доступен.
Этот проект Android Things использует IntentService и класс:

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
public class APIServerService extends IntentService {
 
    private String LOG_NAME = getClass().getName();
    private Component restComponent;
    private static final int PORT = 8090;
 
    public static final String START_API_SERVER = "com.survivingwithandroid.api.start";
    public static final String STOP_API_SERVER = "com.survivingwithandroid.api.stop";
 
    public APIServerService() {
        super("APiServerService");
 
        // start the Rest server
        restComponent = new Component();
        restComponent.getServers().add(Protocol.HTTP, PORT); // listen on 8090
        // Router to dispatch Request
        Router router = new Router();
        router.attach("/temp", SensorTempResource.class);
        router.attach("/press", SensorPressResource.class);
 
        restComponent.getDefaultHost().attach("/sensor", router);
    }
 
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        if (intent != null) {
            String action = intent.getAction();
            try {
                if (action.equals(START_API_SERVER)) {
                    Log.d(LOG_NAME, "Starting API Server");
                    restComponent.start();
                }
                else if (action.equals(STOP_API_SERVER)) {
                    Log.d(LOG_NAME, "Stopping API Server");
                    restComponent.stop();
                }
            }
            catch(Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}

Этот класс очень прост: вначале он определяет порт, который слушает сервер, а затем определяет маршрутизатор. В этом контексте маршрутизатор необходим для отправки запросов на разные ресурсы. Мы можем предположить присоединить следующий URI:

  1. / темп, чтобы получить текущую температуру
  2. / нажмите, чтобы получить текущее давление

Затем класс реализует onHandleIntent для управления запуском и остановкой сервера.

Шаг 3: Определение действия

Это последний шаг в этом процессе, который предполагает создание Android Things Activity:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
public class MainActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      Intent i = new Intent(this, APIServerService.class);
      i.setAction(APIServerService.START_API_SERVER);
      startService(i);
    }
 
    @Override
    protected void onDestroy() {
     super.onDestroy();
     Intent i = new Intent(this, APIServerService.class);
     i.setAction(APIServerService.STOP_API_SERVER);
 
     startService(i);
    }
}

Просто в этом классе приложение Android Things вызывает службу Intent, определенную ранее, используя два типа Intents.
Вот и все, мы можем запустить приложение Android Things и протестировать его.

Тестирование интерфейса Restful API с помощью Android Things

На этом этапе мы можем протестировать приложение и проверить результаты.

Например, чтобы узнать температуру, давайте откроем браузер и напишем следующий URL:

1
http://<raspberry_ip>:port/sensor/temp

в то время как получить давление:

1
http://<raspberry_ip>:port/sensor/temp

Результатом являются данные в формате JSON, содержащие температуру или давление.

Резюме

Надеемся, что в конце этого поста вы узнали, как реализовать интерфейс API Restful с помощью Android Things и как его вызывать. Это простой проект, но он демонстрирует, как мы можем использовать интерфейс API Restful для интеграции Android-вещей с внешними системами. Мы можем еще больше расширить этот проект Android Things, реализуя другие API. Например, мы можем использовать запросы POST для отправки данных и управления удаленными периферийными устройствами, такими как двигатели или светодиоды.

Опубликовано на Java Code Geeks с разрешения Франческо Аццолы, партнера по нашей программе JCG. См. Оригинальную статью здесь: Создание интерфейса API Restful с использованием Android Things

Мнения, высказанные участниками Java Code Geeks, являются их собственными.