Android Wear:发送给Wearable的DataItem也被本地Binding接收 - 如何防止这种情况?

时间:2015-07-26 07:25:54

标签: android

我对Android Wear有疑问:Wearable.DataApi.putDataItem

我的应用程序通过使用以下方式将一些数据从手机发送到磨损:

dataToWearRequest = PutDataRequest.create("/image");
dataToWearRequest.setData(compressedPictureAsByteArray);
Wearable.DataApi.putDataItem(mGoogleApiClient, dataToWearRequest);

通过使用实现DataApi.DataListener

的活动,磨损正在接收数据
public void onDataChanged(DataEventBuffer dataEvents) {
    for (DataEvent event : dataEvents) {
        if (event.getType() == DataEvent.TYPE_CHANGED &&
                event.getDataItem().getUri().getPath().equals("/image")) {
            DataItem dataItem = event.getDataItem();
            byte content[] = dataItem.getData();
            if (mDebug) System.out.println("onDataChanged: receiver: content.length="+ content.length);
        }
    }
}

但我的移动应用程序还有一个WearableListenerService,希望从服装中接收消息。 WearableListenerService类本身也实现了DataApi.DataListener(正如我所说:在移动设备上)。在此服务中,onDataChanged方法还接收发送到磨损的数据包。它的实现非常简单(在我的例子中,因为我不需要磨损的数据包):

public void onDataChanged(DataEventBuffer dataEvents) {
    //super.onDataChanged(dataEvents);
    for (DataEvent event : dataEvents) {
        System.out.println("WEAR Data changed: "+event.getDataItem().getUri().toString());
    }
    dataEvents.close();
}

此移动服务的相应清单条目与往常一样:

<service android:name=".RemoteControlWearService">
    <intent-filter>
        <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
    </intent-filter>
</service>

我尝试在移动设备的清单文件中设置一个意图过滤器,其路径未知,以防止它接收/ image数据。但这没有帮助。

我问这个问题,因为移动设备确实复制了发送到磨损的数据包,以便能够调用onDataReceived。在Wearable.DataApi.putDataItem内部似乎是一个内存泄漏:当您发送许多图像时,移动设备的内存消耗正在增加,并且从不垃圾收集(这是本机缓冲区)。我想通过阻止将不需要的包裹发送到本地服务来减少移动应用程序的内存消耗。

有人知道如何阻止我的本地移动服务仅接收针对该服装的数据包吗?

1 个答案:

答案 0 :(得分:0)

您可以检索本地节点ID see here,然后通过调用DataEvent将其与触发dataItem.getUri().getHost()的节点进行比较。比较的最佳方法是在equals()返回的值上调用dataItem.getUri().getHost()并将localNodeId作为参数。

您可以在下面看到我的实施:

@Override
public void onDataChanged(DataEventBuffer dataEvents) {
    String localNodeId = NodeUtils.getLocalNodeId(this);
    for (DataEvent dataEvent : dataEvents) {
        if (dataEvent.getType() == DataEvent.TYPE_CHANGED) {
            DataItem dataItem = dataEvent.getDataItem();
            String host = dataItem.getUri().getHost();
            if (host.equals(localNodeId)) continue; // Ignore local changes
            if (dataItem.getUri().getPath().equals(THE_DATA_PATH_I_WANT)) {
                DataMap dataMap = DataMapItem.fromDataItem(dataItem).getDataMap();
                // Do something with my DataMap
            }
        }
    }
}

使用用于获取节点标识的代码

public class NodeUtils {

@Nullable
public static String getLocalNodeId(@NonNull Context context) {
    GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
            .addApi(Wearable.API)
            .build();
    ConnectionResult connectionResult = googleApiClient.blockingConnect(30, TimeUnit.SECONDS);
    return connectionResult.isSuccess() ? getLocalNodeId(googleApiClient) : null;
}

@Nullable
public static String getLocalNodeId(@NonNull GoogleApiClient googleApiClient) {
    NodeApi.GetLocalNodeResult nodeResult =
            Wearable.NodeApi.getLocalNode(googleApiClient).await(10, TimeUnit.SECONDS);
    if (nodeResult.getStatus().isSuccess()) {
        return nodeResult.getNode().getId();
    } else {
        Timber.wtf("couldn't get local node? status: %s", nodeResult.getStatus());
        return null;
    }
}

}