onDataChanged只调用一次?

时间:2016-07-31 19:08:51

标签: android wear-os android-wear-data-api

我正在为Android佩戴制作表盘。表盘会偶尔向掌上电脑询问信息,这些信息将用于更新表盘。不幸的是,onDataChanged和onMessageReceived仅在表面第一次加载时出现,而且从不再出现(我可以切换到另一个表面和背面,并再次使用一次)

我认为大部分样板都来自于实例。所以在表盘中我有

@Override
    public void onCreate() {
        Log.d(TAG, "onCreate - Creating service...");
        super.onCreate();
        initGoogleApiClient();
    }

    private void initGoogleApiClient() {
        mApiClient = new GoogleApiClient.Builder(mContext)
                .addApi(Wearable.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        Log.d(TAG, "Calling connect on mApiClient...");

        mApiClient.connect();
    }

@Override
    public void onMessageReceived(MessageEvent messageEvent) {
        Log.d(TAG, "onMessageReceived: " + messageEvent.getPath() + " " + messageEvent.getData());

        switch (messageEvent.getPath()) {
            case "case 1":
                    Log.d(TAG,"some data was sent to us...");
                if (!mApiClient.isConnected())
                    mApiClient.connect();
                break;
        }
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Log.d(TAG,"onConnected - adding Listeners");
        Wearable.DataApi.addListener(mApiClient, this);
        Wearable.MessageApi.addListener(mApiClient, this);
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.d(TAG,"onConnection suspended");
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.e(TAG,"onConnection failed");
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEventBuffer) {
        Log.d(TAG, "onDataChanged");
        for (DataEvent event : dataEventBuffer) {
            if (event.getType() == DataEvent.TYPE_CHANGED && event.getDataItem().getUri().getPath().equals("/image")) {
                Log.d(TAG, "Matched TYPE_CHANGED and /image");
                DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
                Asset photoAsset = dataMapItem.getDataMap().getAsset("photo");
                loadBitmapFromAsset(photoAsset);
            }
        }
    }

在掌上电脑中,日志记录显示在加载监视面(工作地点)和后续请求后,数据在第一个实例上以相同方式发送到可穿戴设备。不同之处在于后续请求,上述代码中没有任何记录发生,显示没有任何内容被触发。

有关如何发送数据的一些手持设备代码:

private void SendBitmap(final Bitmap bitmap) {
//snip - stuff to resize the bitmap
Log.d(TAG, "Resized image to " + cropped.getWidth() + "x" + cropped.getHeight());

final Bitmap croppedBitmap = cropped;

new Thread(new Runnable() {
    @Override
    public void run() {

        if (!nodeConnected || !mGoogleApiClient.isConnected())
        {
            Log.d(TAG,"No node connected. Attempting connection for 5 seconds...");
            mGoogleApiClient.blockingConnect(5, TimeUnit.SECONDS);
        }
        if (!nodeConnected)
        {
            Log.e(TAG, "Failed to connect to mGoogleApiClient within 5 seconds");
            return;
        }

        if (mGoogleApiClient.isConnected()) {
            Log.d(TAG, "Client is connected...");
            Asset asset = createAssetFromBitmap(croppedBitmap);
            PutDataMapRequest putDataMapRequest = PutDataMapRequest.create("/image").setUrgent();
            putDataMapRequest.getDataMap().clear(); //clear down current stuff
            putDataMapRequest.getDataMap().putAsset("photo", asset);
            putDataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis());
            PutDataRequest request = putDataMapRequest.asPutDataRequest().setUrgent();

            PendingResult<DataApi.DataItemResult> pendingResult =
                    Wearable.DataApi.putDataItem(mGoogleApiClient, request);

            Log.d(TAG,"DataItem is put");

            pendingResult.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
                @Override
                public void onResult(DataApi.DataItemResult dataItemResult) {
                    Log.d(TAG, "Sending task data: " + dataItemResult.getStatus().isSuccess());
                }
            });
        }
        else {
            Log.w(TAG,"Client is NOT connected...");
        }
    }
}).start();


//send a message to trigger connection?
SendToDataLayerThread photoTrigger = new SendToDataLayerThread("case 1", "Photo sent...".getBytes());
photoTrigger.run();
Log.d(TAG, "Photo sent to the Google API");
}

private static Asset createAssetFromBitmap(Bitmap bitmap) {
final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
return Asset.createFromBytes(byteStream.toByteArray());
}

public class SendToDataLayerThread extends Thread {
    String path;
    byte[] message;

    // Constructor to send a message to the data layer
    SendToDataLayerThread(String p, byte[] msg) {
        path = p;
        message = msg;
    }

    public void run() {
        Wearable.NodeApi.getConnectedNodes(mGoogleApiClient)
                .setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
                    @Override
                    public void onResult(NodeApi.GetConnectedNodesResult nodes) {
                        for (final Node node : nodes.getNodes()) {
                            Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), path, message).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
                                @Override
                                public void onResult(MessageApi.SendMessageResult sendMessageResult) {
                                    if (sendMessageResult.getStatus().isSuccess()) {
                                        Log.d(TAG, "Message: {" + message + "} sent to: " + node.getDisplayName());
                                    } else {
                                        // Log an error
                                        Log.d(TAG, "ERROR: failed to send Message");
                                    }
                                }
                            });
                        }
                    }
                });
    }
}

我尝试过的事情,基于其他帖子:

  • 使用setUrgent()
  • 除了发送我的图片,发送时间戳以使数据“唯一”
  • 发送消息以“唤醒”可穿戴设备上的连接

我在这一点上很难过。我确定我错过了一些明显的东西,但我不确定下一步该尝试什么...

1 个答案:

答案 0 :(得分:1)

经过一系列的改变,我最终得到了它。在磨损应用程序上我最终得到:

    DataLayerListener.java中的
  • @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        Log.d(TAG, "onDataChanged");
    
        GoogleApiClient mApiClient = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .build();
    
        ConnectionResult result = mApiClient.blockingConnect(250, TimeUnit.MILLISECONDS);
        if (!result.isSuccess()) {
            Log.e(TAG, "Failed to connect to mApiClient when receiving image...");
        }
    
        for (DataEvent event : dataEvents) {
            if (event.getType() == DataEvent.TYPE_CHANGED && event.getDataItem().getUri().getPath().equals("/myapp")) {
                Log.d(TAG, "Matched TYPE_CHANGED and /myapp");
                DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
                Asset photoAsset = dataMapItem.getDataMap().getAsset("photo");
                InputStream assetInputStream = Wearable.DataApi.getFdForAsset(mApiClient, photoAsset).await().getInputStream();
    
                Bitmap background = BitmapFactory.decodeStream(assetInputStream);
                Intent intent = new Intent("background");
                intent.putExtra("message", background);
                LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
            }
        }
    }
    

在清单中:

    <service
        android:name=".MyWatchFace"
        android:label="@string/my_watch_face_name"
        android:permission="android.permission.BIND_WALLPAPER">
        <meta-data ... />
        <meta-data ... />
        <intent-filter>
            <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
            <action android:name="android.service.wallpaper.WallpaperService" />
            <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" />
        </intent-filter>
    </service>
    <service android:name=".DataLayerListener">
        <intent-filter>
            <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
            <action android:name="com.google.android.gms.wearable.CAPABILITY_CHANGED" />
            <action android:name="com.google.android.gms.wearable.CHANNEL_EVENT" />
            <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
            <data
                android:host="*"
                android:path="/myapp"
                android:pathPrefix="/myapp"
                android:scheme="wear" />
        </intent-filter>
    </service>

表面本身注册BroadcastReceivers以处理从DataLayerListener广播的消息。

我认为明显的变化是重要的一点......希望如果你遇到同样的问题就会给出一个线索