我一直在阅读如何在官方网站上的手表和手机之间使用Capability API和Message API:https://developer.android.com/training/wearables/data-layer/messages.html我可以毫不费力地将信息从手表发送到手机。
但是,我确实遇到了麻烦,使用下面显示的方法从手机向手表发送消息。我不确定为什么,因为我似乎使用相同的方法实现了API(我甚至开发了一个更抽象的类来简化API调用)。我的手机似乎无法使用功能过滤器找到手表。这是一个已知问题,还是我的实施有问题?
移动/值/ wear.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="CAPABILITY_MOBILE">MOBILE</string>
<string name="CAPABILITY_ANDROID_WEAR">WEARABLE</string>
<string-array name="android_wear_capabilities">
<item>@string/CAPABILITY_MOBILE</item>
</string-array>
</resources>
WEAR /值/ wear.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="CAPABILITY_MOBILE">MOBILE</string>
<string name="CAPABILITY_ANDROID_WEAR">WEARABLE</string>
<string-array name="android_wear_capabilities">
<item>@string/CAPABILITY_ANDROID_WEAR</item>
</string-array>
</resources>
发送消息的方法
gapi = new GoogleApiClient.Builder(getApplicationContext())
.addApi(Drive.API)
.addApi(Games.API)
.addApi(Plus.API)
.addApiIfAvailable(Wearable.API)
.addApiIfAvailable(Fitness.HISTORY_API)
.addScope(Drive.SCOPE_FILE)
.addScope(Games.SCOPE_GAMES)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
final int action_watch = intent.getIntExtra(ACTION_WATCH, ACTION_NULL);
//For any action, open Home.class on watch
if(action_watch != ACTION_NULL) {
final ConnectionUtils.NodeManager nodeManager =
new ConnectionUtils.NodeManager(gapi, getString(R.string.CAPABILITY_ANDROID_WEAR), MessageListener.NOTIFICATION_ACTIONS_PATH);
Log.d(TAG, "Start looking for nodes");
nodeManager.setNodeListener(new ConnectionUtils.NodeListener() {
@Override
public void onNodeFound() {
nodeManager.sendMessage(action_watch+"");
Log.d(TAG, "Sending "+action_watch+" to node");
}
});
} else {
Log.d(TAG, "No watch action requested");
}
}
@Override
public void onConnectionSuspended(int i) {
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Error occurred");
}
})
.build();
gapi.connect();
我使用自定义类NodeManager自动处理功能过滤器和节点管理。
package com.felkertech.n.virtualpets.Utils;
import android.util.Log;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Result;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.wearable.CapabilityApi;
import com.google.android.gms.wearable.CapabilityInfo;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.MessageApi;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class ConnectionUtils {
public static class NodeManager {
private String transcriptionNodeId = null;
private GoogleApiClient mGoogleApiClient;
private String CAPABILITY;
private String PATH;
private NodeListener listener;
private int nodesPinged = 0;
public NodeManager(final GoogleApiClient mGoogleApiClient, String CAPABILITY, String PATH) {
this.mGoogleApiClient = mGoogleApiClient;
this.CAPABILITY = CAPABILITY;
this.PATH = PATH;
setupNode();
}
public void setNodeListener(NodeListener nodeListener) {
listener = nodeListener;
}
private void setupNode() {
new Thread(new Runnable() {
@Override
public void run() {
CapabilityApi.GetCapabilityResult result =
Wearable.CapabilityApi.getCapability(
mGoogleApiClient, CAPABILITY,
CapabilityApi.FILTER_REACHABLE).await();
updateTranscriptionCapability(result.getCapability());
CapabilityApi.CapabilityListener capabilityListener =
new CapabilityApi.CapabilityListener() {
@Override
public void onCapabilityChanged(CapabilityInfo capabilityInfo) {
updateTranscriptionCapability(capabilityInfo);
}
};
Wearable.CapabilityApi.addCapabilityListener(
mGoogleApiClient,
capabilityListener,
CAPABILITY);
}
}).start();
}
private void updateTranscriptionCapability(CapabilityInfo capabilityInfo) {
if(capabilityInfo == null)
return; //TODO Send this in update
Set<Node> connectedNodes = capabilityInfo.getNodes();
transcriptionNodeId = pickBestNodeId(connectedNodes);
if(listener != null) {
listener.onNodeFound();
if(nodesPinged == 0)
listener.onFirstNodeFound();
nodesPinged++;
}
}
private String pickBestNodeId(Set<Node> nodes) {
String bestNodeId = null;
// Find a nearby node or pick one arbitrarily
for (Node node : nodes) {
if (node.isNearby()) {
return node.getId();
}
bestNodeId = node.getId();
}
return bestNodeId;
}
public void sendMessage(String msg) {
byte[] voiceData = msg.getBytes();
if (transcriptionNodeId != null) {
Wearable.MessageApi.sendMessage(mGoogleApiClient, transcriptionNodeId,
PATH, voiceData).setResultCallback(
new ResultCallback() {
@Override
public void onResult(Result result) {
MessageApi.SendMessageResult sendMessageResult = (MessageApi.SendMessageResult) result;
if (!sendMessageResult.getStatus().isSuccess()) {
// Failed to send message
}
}
}
);
} else {
// Unable to retrieve node with transcription capability
}
}
private Collection<String> getNodes() {
HashSet<String> results = new HashSet<String>();
NodeApi.GetConnectedNodesResult nodes =
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
for (Node node : nodes.getNodes()) {
results.add(node.getId());
}
return results;
}
}
public static void sendLaunchCommand(final GoogleApiClient mGoogleApiClient) {
new Thread(new Runnable() {
@Override
public void run() {
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
for(Node node : nodes.getNodes()) {
Log.i("test", "pinging to: " + node.getDisplayName());
MessageApi.SendMessageResult result = Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), "/messageapi/launcher", "Hello World".getBytes()).await();
if(!result.getStatus().isSuccess()){
Log.e("test", "error");
} else {
Log.i("test", "success!! sent to: " + node.getDisplayName());
}
}
}
}).start();
}
public static void sendData(GoogleApiClient mGoogleApiClient, String name, String type, Object value) {
PutDataMapRequest dataMap = PutDataMapRequest.create("/dataitem/data");
if(type.equals("boolean"))
dataMap.getDataMap().putBoolean(name, (Boolean) value);
if(type.equals("int"))
dataMap.getDataMap().putInt(name, (Integer) value);
PutDataRequest request = dataMap.asPutDataRequest();
PendingResult<DataApi.DataItemResult> pendingResult =
Wearable.DataApi.putDataItem(mGoogleApiClient, request);
pendingResult.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
Log.d("TAG", "onResult: " + dataItemResult.getStatus().toString());
}
});
}
public interface NodeListener {
void onNodeFound();
void onFirstNodeFound();
}
}
答案 0 :(得分:0)
我创建了一个简单的项目,看看我是否可以重现这个。在我的项目中,我已从客户端移除了非磨损apis,我能够成功地从手机中看到“磨损”节点;我没有发送任何消息,或任何花哨的东西,但确实使用你的ConnectionUtils使它尽可能接近你。您可能希望尝试简化此操作以找出问题所在: 1.从GoogleApiClient中删除所有非磨损api,使测试更简单 2.确保通过添加日志语句确实发生了您期望获取的路径 3.尝试添加日志消息以查看(a)Google Api Client是否已在移动设备上连接,(b)节点侦听器是否返回节点。
我注意到您的代码中有一些您可能想要查看的内容;例如,你有MessageListener.NOTIFICATION_ACTIONS_PATH;来自Play服务的MessageListener没有这样的常量,或者当你调用getcpability(..)。await()时,总是添加一个超时(我看不到使用阻塞版本开始的原因)。