没有在android上调用onDataChanged方法

时间:2015-12-24 01:15:01

标签: android wear-os

我已按照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>

1 个答案:

答案 0 :(得分:0)

不需要发送方的循环;事实上,如果你查看循环内部,你没有使用&#34;节点&#34;你正在循环。添加数据项将在所有连接的节点上同步。此外,在最新的Play服务中,DataApi的同步过程不是即时的;它是批量运行并定期运行(可能需要长达20分钟,但通常需要几分钟),这样做是为了节省电池和其他资源,但如果应用需要立即同步,那么必须设置适当的紧急标志关于该项目(见setUrgent())。请执行以下操作:

  1. 删除循环
  2. 如果需要,请设置紧急标志。