Первое, что пользователи захотят сделать с новым умным домашним устройством, — это подключить его к своей беспроводной сети. На многих устройствах IoT отсутствует экран или клавиатура, поэтому один из способов сделать это — дать пользователям возможность подключить смартфон к устройству, чтобы они могли контролировать и настраивать устройство. Так работают Nest и Google Home, в том числе API-интерфейс Nearby Connections 2.0.

В этой статье вы познакомитесь с API-интерфейсом Nearby Connections 2.0 и узнаете, как его можно использовать для сопряжения смартфона Android с устройством Android Things, чтобы предоставить своим пользователям опыт сопутствующего устройства.
Что такое API ближайших соединений?
API соседних подключений позволяет двум устройствам связываться друг с другом напрямую через Bluetooth или по беспроводной сети без использования централизованной точки доступа. Устройство может выполнять две роли: рекламодатель , который сообщает другим устройствам, что оно доступно для подключения, и обнаружитель , который пытается найти рекламодателей и подключиться к ним. Как только набор устройств (также известный как «конечные точки» на этом этапе) соединяются вместе, они могут отправлять данные в любую другую конечную точку в сети Nearby Connections.
Существует две стратегии, которые API-интерфейс Nearby Connections может использовать для соединения устройств друг с другом. Первый, P2P_STAR , самый простой для работы. Он состоит из одного рекламодателя, который может поддерживать несколько открывателей, подключающихся к нему. Второй, P2P_CLUSTER , позволяет любому количеству устройств подключаться и принимать подключения от любого другого количества устройств. Это создает ячеистую сеть с менее централизованной точкой отказа, хотя она также требует большей пропускной способности. Эта стратегия идеально подходит для небольших полезных нагрузок, которым не нужно проходить через центральное устройство, например, для игр.
В этом руководстве основное внимание будет уделено использованию более простой стратегии «звезда» для подключения устройства IoT в качестве рекламодателя и использованию смартфона пользователя в качестве первооткрывателя. Однако к концу у вас также должно быть достаточно информации для реализации кластерной стратегии.
Давайте настроимся!
Для этого урока будет два модуля: мобильное приложение и приложение Android Things. После того, как вы создали их в Android Studio, вам нужно будет включить зависимость служб Google Play для ближайших подключений в файл build.gradle уровня модуля для обоих приложений.
|
1
|
compile ‘com.google.android.gms:play-services-nearby:11.6.2’
|
После того, как вы запустите синхронизацию, откройте файлы AndroidManifest.xml для обоих модулей и включите следующие разрешения в узлы application .
|
01
02
03
04
05
06
07
08
09
10
|
<uses-permission
android:name=»android.permission.BLUETOOTH»/>
<uses-permission
android:name=»android.permission.BLUETOOTH_ADMIN»/>
<uses-permission
android:name=»android.permission.ACCESS_WIFI_STATE» />
<uses-permission
android:name=»android.permission.CHANGE_WIFI_STATE» />
<uses-permission
android:name=»android.permission.ACCESS_COARSE_LOCATION» />
|
Устройствам Android Things будут предоставлены эти разрешения устройству после перезагрузки, хотя вам потребуется запросить разрешение на местоположение у пользователей в приложении для телефона.
Класс MainActivity в вещах и мобильных модулях должен будет реализовывать интерфейсы, используемые для обратных вызовов служб Google Play, например:
|
01
02
03
04
05
06
07
08
09
10
11
|
public class MainActivity extends FragmentActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
@Override
public void onConnected(@Nullable Bundle bundle) {}
@Override
public void onConnectionSuspended(int i) {}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {}
}
|
После того, как вы подтвердите, что у пользователя есть соответствующие разрешения для onCreate() местоположения в onCreate() , вы можете начать подключаться к сервисам Google Play, чтобы использовать API onCreate() подключений.
|
1
2
3
4
5
|
mGoogleApiClient = new GoogleApiClient
.Builder(this, this, this)
.addApi(Nearby.CONNECTIONS_API)
.enableAutoManage(this, this)
.build();
|
Когда GoogleApiClient завершит подключение, будет вызван метод onConnected() . Здесь вы начнете процесс рекламы или поиска для вашего устройства. Кроме того, обоим приложениям потребуется идентификатор службы, который является уникальным идентификатором String .
|
1
|
private static final String SERVICE_ID = «UNIQUE_SERVICE_ID»;
|
Реклама на близлежащих соединениях
При работе с API-интерфейсом Nearby Connections вам потребуется создать ConnectionLifecycleCallback , который, как следует из названия, будет запускаться при различных событиях жизненного цикла соединения. Для этой демонстрации мы будем использовать только метод onConnectionInitiated() . Он сохранит ссылку на первую конечную точку, которая пытается подключиться к ней, примет подключение и затем прекратит рекламу. Если соединение не установлено, приложение может перезапустить рекламу.
|
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
|
private final ConnectionLifecycleCallback mConnectionLifecycleCallback =
new ConnectionLifecycleCallback() {
@Override
public void onConnectionInitiated(String endpointId, ConnectionInfo connectionInfo) {
endpoint = endpointId;
Nearby.Connections.acceptConnection(mGoogleApiClient, endpointId, mPayloadCallback)
.setResultCallback(new ResultCallback<com.google.android.gms.common.api.Status>() {
@Override
public void onResult(@NonNull com.google.android.gms.common.api.Status status) {
if( status.isSuccess() ) {
//Connection accepted
}
}
});
Nearby.Connections.stopAdvertising(mGoogleApiClient);
}
@Override
public void onConnectionResult(String endpointId, ConnectionResolution result) {}
@Override
public void onDisconnected(String endpointId) {}
};
|
Возможно, вы заметили, что вышеуказанный метод также ссылается на объект PayloadCallback . У этого объекта есть методы, которые вызываются, когда полезная информация отправляется от рекламодателя конечной точке, а также когда данные принимаются от конечной точки. Метод onPayloadReceived() предназначен для обработки любых данных, отправляемых на наше устройство Android Things. Этот метод содержит объект Payload который можно превратить в массив байтов, и String представляющую адрес конечной точки отправляющего устройства.
|
1
2
3
4
5
6
7
8
9
|
private PayloadCallback mPayloadCallback = new PayloadCallback() {
@Override
public void onPayloadReceived(String endpoint, Payload payload) {
Log.e(«Tuts+», new String(payload.asBytes()));
}
@Override
public void onPayloadTransferUpdate(String endpoint, PayloadTransferUpdate payloadTransferUpdate) {}
};
|
На этом этапе вы можете начать рекламу на своем IoT-устройстве следующим способом:
|
1
2
3
4
5
6
|
Nearby.Connections.startAdvertising(
mGoogleApiClient,
«Device Name»,
SERVICE_ID,
mConnectionLifecycleCallback,
new AdvertisingOptions(Strategy.P2P_STAR));
|
Вы можете заметить, что именно здесь мы применяем стратегию P2P_STAR к нашей сети Nearby Connections.
Если вы хотите отправить полезную нагрузку на другое устройство, вы можете использовать метод Nearby.Connections.sendPayload() со ссылкой на клиент API Google, именем вашей конечной точки и байтовым массивом данных, которые вы хотите отправить.
|
1
|
Nearby.Connections.sendPayload(mGoogleApiClient, endpoint, Payload.fromBytes(«Message».getBytes()));
|
Совет: включите WiFi при перезагрузке
Один прием, который я нашел полезным при работе с API-интерфейсом Nearby Connections на устройстве Android Things, заключается в повторном включении WiFi при перезагрузке, поскольку устройство может в конечном итоге отключить беспроводную связь, если устройство выключено или теряет питание во время рекламы. Вы можете сделать это, WifiManager системную службу setWifiEnabled() и вызвав setWifiEnabled() .
|
1
2
|
wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(true);
|
Обнаружение устройств с соседними подключениями
Обнаружение устройства следует в основном аналогично рекламе. Устройство подключится к клиенту Google API и начнет обнаружение. Когда рекламодатель найден, обнаружитель запросит подключение к рекламодателю. Если рекламодатель одобрит запрос, оба устройства подключатся и смогут отправлять полезные данные туда и обратно. Обнаружитель будет использовать PayloadCallback же, как рекламодатель.
|
1
2
3
4
5
6
7
8
9
|
private PayloadCallback mPayloadCallback = new PayloadCallback() {
@Override
public void onPayloadReceived(String s, Payload payload) {
Log.e(«Tuts+», new String(payload.asBytes()));
}
@Override
public void onPayloadTransferUpdate(String s, PayloadTransferUpdate payloadTransferUpdate) {}
};
|
ConnectionLifecycleCallback открывателя (мобильного приложения) также будет выглядеть аналогично рекламодателю:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
private final ConnectionLifecycleCallback mConnectionLifecycleCallback =
new ConnectionLifecycleCallback() {
@Override
public void onConnectionInitiated(String endpointId, ConnectionInfo connectionInfo) {
Nearby.Connections.acceptConnection(mGoogleApiClient, endpointId, mPayloadCallback);
mEndpoint = endpointId;
Nearby.Connections.stopDiscovery(mGoogleApiClient);
}
@Override
public void onConnectionResult(String endpointId, ConnectionResolution result) {}
@Override
public void onDisconnected(String endpointId) {}
};
|
Отличие заключается в том, что обнаружителям потребуется EndpointDiscoveryCallback который будет использоваться, когда рекламодатель найден, но еще не подключен к нему. Этот объект инициирует запрос на подключение к рекламодателю.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
private final EndpointDiscoveryCallback mEndpointDiscoveryCallback =
new EndpointDiscoveryCallback() {
@Override
public void onEndpointFound(
String endpointId, DiscoveredEndpointInfo discoveredEndpointInfo) {
if( discoveredEndpointInfo.getServiceId().equalsIgnoreCase(SERVICE_ID)) {
Nearby.Connections.requestConnection(
mGoogleApiClient,
«Name»,
endpointId,
mConnectionLifecycleCallback);
}
}
@Override
public void onEndpointLost(String endpointId) {
Log.e(«Tuts+», «Disconnected»);
}
};
|
После того как ваш обнаружитель подключится к Сервисам Google Play, вы можете запустить обнаружение с помощью следующей команды:
|
1
2
3
4
5
|
Nearby.Connections.startDiscovery(
mGoogleApiClient,
SERVICE_ID,
mEndpointDiscoveryCallback,
new DiscoveryOptions(Strategy.P2P_STAR));
|
Наконец, когда вы хотите отключиться от рекламодателя, вы можете использовать метод disconnectFromEndpoint() из API ближайших подключений. Как правило, это хорошая идея сделать это в onDestroy() вашего Activity .
|
1
|
Nearby.Connections.disconnectFromEndpoint(mGoogleApiClient, mEndpoint);
|
Вывод
В этой статье вы узнали об API Nearby Connections 2.0 для Android в контексте создания сопутствующего приложения для устройства Android Things IoT.
Стоит отметить, что этот API можно использовать для любых устройств Android, которые вы хотели бы объединить в сеть, от телефонов и планшетов до коробок Android TV и умных часов Android Wear. API предоставляет простой способ подключения и связи без использования Интернета или централизованного маршрутизатора и добавляет отличную утилиту для вашей коллекции инструментов для разработки под Android.
Пока вы здесь, ознакомьтесь с некоторыми другими нашими статьями по разработке Android Things IoT!



