用户想要使用新的智能家居设备做的第一件事就是将其接入他们的无线网络。许多物联网设备没有屏幕或键盘,因此一种方法是允许用户将智能手机与设备配对,以便他们可以控制和配置设备。这就是Nest和 Google Home 的工作方式,而 Nearby Connections 2.0 api使之成为可能。
在本文中,您将了解 Nearby Connections 2.0 API 以及如何使用它来将 android 智能手机与 Android Things 设备配对,以便为您的用户提供配套设备体验。
什么是附近连接 API?
Nearby Connections API 允许两个设备直接通过蓝牙或无线相互通信,而无需使用集中式接入点。一个设备可以扮演两个角色:advertisinger,它让其他设备知道它可以连接,以及discoverer,它试图找到广告商并连接到它们。一旦一组设备(在此阶段也称为“端点”)连接在一起,它们就可以将数据发送到附近连接网络上的任何其他端点。
Nearby Connections API 可以使用两种策略将设备连接在一起。第一个P2P_STAR是最容易使用的。它由一个广告商组成,可以支持多个发现者连接到它。第二个,P2P_CLUSTER,允许任意数量的设备连接到任何其他数量的设备,并接受来自其他数量的设备的连接。这会创建一个故障点集中度较低的网状网络,尽管它也会占用更多带宽。这种策略非常适合不需要通过中央设备的较小有效负载,例如游戏。
本教程将重点介绍使用更简单的星型策略将物联网设备连接为广告商,并将用户的智能手机用作发现者。但是,到最后,您还应该有足够的信息来实施集群策略。
让我们开始吧!
本教程将包含两个模块:移动应用程序和 Android Things 应用程序。在 Android Studio 中创建这些内容后,您需要在两个应用的模块级build.gradle文件中包含 Google Play services 依赖项以用于 Nearby Connections。
compile ‘com.google.android.gms:play-services-nearby:11.6.2’
运行 gradle 同步后,打开两个模块的AndroidManifest.xml文件,并在application node中包含以下权限。
<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 设备将在重新启动后将这些权限授予设备,但您需要在手机应用程序上向用户请求位置权限。
things和mobile模块中的MainActivity类都需要实现用于 Google Play Services回调的接口,如下所示:
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(),您就可以开始连接到 Google Play 服务以使用 Nearby Connections API。
mGoogleApiClient = new GoogleApiClient .Builder(this, this, this) .addApi(Nearby.CONNECTIONS_API) .enableAutoManage(this, this) .build();
完成GoogleApiClient连接后,onConnected()将调用该方法。您将在此处开始设备的广告或发现过程。此外,这两个应用程序都需要一个服务 ID,它是一个唯一String标识符。
private static final String SERVICE_ID = "UNIQUE_SERVICE_ID";
在附近的连接上做广告
使用 Nearby Connections API 时,您将需要创建一个 ConnectionLifecycleCallback,顾名思义,它将在各种连接生命周期事件上触发。对于这个演示,我们将只使用该onConnectionInitiated()方法。它将保存对尝试连接到它的第一个端点的引用,接受连接,然后停止广播。如果连接不成功,应用可以休息艺术广告。
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表示发送设备的端点地址的对象。
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 设备上开始投放广告:
Nearby.Connections.startAdvertising( mGoogleApiClient, "Device Name", SERVICE_ID, mConnectionLifecycleCallback, new AdvertisingOptions(Strategy.P2P_STAR));
您可能会注意到,这是我们将 P2P_STAR 策略应用于我们的 Nearby Connections 网络的地方。
当您想将有效负载发送到另一台设备时,您可以使用该Nearby.Connections.sendPayload()方法与 Google API 客户端参考、端点名称以及您要发送的数据的字节数组。
Nearby.Connections.sendPayload(mGoogleApiClient, endpoint, Payload.fromBytes("Message".getBytes()));
提示:重启时启用 WiFi
在 Android Things 设备上使用 Nearby Connections API 时,我发现一个有用的技巧是在重新启动时重新启用 WiFi,因为如果设备在广告期间关闭或断电,设备最终可能会禁用无线。您可以通过检索WifiManager系统服务并调用setWifiEnabled().
wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);wifiManager.setWifiEnabled(true);
发现具有附近连接的设备
发现设备遵循与广告大体相似的模式。设备将连接到 Google API 客户端并开始发现。当找到广告商时,发现者将请求连接到广告商。如果广告商批准该请求,那么这两个设备将连接并能够来回发送有效负载。发现者将 PayloadCallback像广告商一样使用。
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外观也类似于广告商的:
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找到广告商但尚未连接到时使用的。该对象将发起连接到广告商的请求。
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 服务后,您可以使用以下命令启动发现:
Nearby.Connections.startDiscovery( mGoogleApiClient, SERVICE_ID, mEndpointDiscoveryCallback, new DiscoveryOptions(Strategy.P2P_STAR));
最后,当您想与广告商断开连接时,您可以使用 disconnectFromEndpoint()Nearby Connections API 中的方法。在您Activity的onDestroy()回调中执行此操作通常是一个好主意。
Nearby.Connections.disconnectFromEndpoint(mGoogleApiClient, mEndpoint);
结论
在本文中,您在为 Android Things IoT 设备创建配套应用程序的上下文中了解了适用于 Android 的 Nearby Connections 2.0 API。
值得注意的是,此 API 可用于您想要联网的任何 Android 设备,从手机和平板电脑到 Android 电视盒和 Android Wear 智能手表。API 提供了一种简单的连接和通信方式,无需使用 Internet 或集中式路由器,并为您的 Android 开发工具集合添加了一个很好的实用程序。
- 提示:重启时启用 WiFi