我已按照this帖子在我的服装和移动设备之间建立了连接。我正在从可穿戴设备向他的掌上电脑发送资产。但是,即使设备已连接且数据项目已成功发送,也不会调用onDataChanged方法。我尝试了大多数其他解决方案,包括确保我的build.gradles具有相同的appId,相同的可穿戴版本号。我已经为数据图添加了时间戳,但它仍然无法正常工作。有没有其他人遇到过这个问题或有任何其他想法,为什么它可能没有被调用?感谢。
这是我正在进行发送的可穿戴代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_wear);
mContainerView = (BoxInsetLayout) findViewById(R.id.container);
//...
// Build a new GoogleApiClient for the Wearable
googleClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
@Override
protected void onStart() {
super.onStart();
if(!googleClient.isConnected()) {
googleClient.connect();
}
}
public void sendToPhone(View view){
// Send audio
if(audioAsset != null){
new SendToDataLayer().start();
}
}
private class SendToDataLayer extends Thread{
public void run(){
// Sending audio
// Get connected wearable nodes
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleClient).await();
for(Node node : nodes.getNodes()){
// Send the audio
PutDataMapRequest request = PutDataMapRequest.create("/audio");
DataMap map = request.getDataMap();
map.putLong("time", new Date().getTime());
map.putAsset("audioAsset", audioAsset);
Wearable.DataApi.putDataItem(googleClient, request.asPutDataRequest());
Log.d("PUTDAT", "Data put on data item, for node: " + node.getDisplayName());
}
}
}
使用log.d调用我可以看到设备已连接且数据正在发送,或者至少看起来是。
我的手持接收端代码:
public class MainHandheldActivity extends AppCompatActivity implements DataApi.DataListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
GoogleApiClient googleClient;
MessageReceiver messageReceiver;
IntentFilter messageFilter;
byte[] audioBytes;
private final Handler handler = new Handler();
private String nodeId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_handheld);
audioBytes = null;
// Build a new GoogleApiClient
googleClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
retrieveDeviceNodes();
// Register the local broadcast receiver
messageFilter = new IntentFilter(Intent.ACTION_SEND);
messageReceiver = new MessageReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(messageReceiver, messageFilter);
}
private void retrieveDeviceNodes(){
new Thread(new Runnable() {
@Override
public void run() {
googleClient.blockingConnect(3000, TimeUnit.MILLISECONDS);
NodeApi.GetConnectedNodesResult result =
Wearable.NodeApi.getConnectedNodes(googleClient).await();
List<Node> nodes = result.getNodes();
if (nodes.size() > 0) {
nodeId = nodes.get(0).getId();
}
googleClient.disconnect();
}
}).start();
}
@Override
public void onDataChanged(DataEventBuffer dataEventBuffer) {
Toast.makeText(this, "Data Changed!", Toast.LENGTH_LONG).show();
for (DataEvent event : dataEventBuffer) {
Log.d(TAG, "Data received: " + event.getDataItem().getUri());
if (event.getType() == DataEvent.TYPE_CHANGED &&
event.getDataItem().getUri().getPath().equals("/audio")) {
DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
Asset audioAsset = dataMapItem.getDataMap().getAsset("audioAsset");
audioBytes = loadBytesFromAsset(audioAsset);
}
// Enable player
handler.post(onNewAudio());
}
}
public byte[] loadBytesFromAsset(Asset asset) {
if (asset == null) {
throw new IllegalArgumentException("Asset must be non-null");
}
ConnectionResult result = googleClient.blockingConnect(3000, TimeUnit.MILLISECONDS);
if(!result.isSuccess()){
return null;
}
// Convert asset into a file descriptor and block until it's ready
InputStream assetInputStream = Wearable.DataApi.getFdForAsset(googleClient, asset).await().getInputStream();
if (assetInputStream == null) {
Log.w(TAG, "Requested an unknown Asset.");
return null;
}
// Decode the stream into a byte[]
return getBytesFromInputStream(assetInputStream);
}
private Runnable onNewAudio() {
return new Runnable() {
@Override
public void run() {
// Enable player
}
};
}
@Override
public void onConnected(Bundle bundle) {
Wearable.DataApi.addListener(googleClient, this);
Toast.makeText(this, "AddedListener!", Toast.LENGTH_LONG).show();
}
@Override
protected void onStart() {
super.onStart();
if(!googleClient.isConnected()) {
googleClient.connect();
}
LocalBroadcastManager.getInstance(this).registerReceiver(messageReceiver, messageFilter);
}
}
onDataChanged()中的Toast永远不会显示,日志也不会调用。此外,这是我的掌上电脑清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="glasgow.comsTest"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
<service
android:name=".ListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER"/>
</intent-filter>
</service>
<activity android:name=".MainHandheldActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
答案 0 :(得分:0)
不需要发送方的循环;事实上,如果你查看循环内部,你没有使用&#34;节点&#34;你正在循环。添加数据项将在所有连接的节点上同步。此外,在最新的Play服务中,DataApi的同步过程不是即时的;它是批量运行并定期运行(可能需要长达20分钟,但通常需要几分钟),这样做是为了节省电池和其他资源,但如果应用需要立即同步,那么必须设置适当的紧急标志关于该项目(见setUrgent())。请执行以下操作: