chris
chris

Reputation: 4351

Accessing app content provider from wearable

I am working on the udacity wearable course and unable to get my wearable emulator to send dataEvents to the wearable device.

On both the handheld and the wearable I have services that extend the WearableListenerService (WLS). The handheld version is currently started via a startService call in the activity, the wearable service is started in the watchface service also with startService, both services can be seen as started.

The device WLS successfully makes a call to the content provider and attempts at sending the data to the wearable, but putDataItem resultCallback is never called.

The wearable seems to be paired with my phone as I receive various notifications on it from my phone, so the setup is good. Both the handheld and wearable modules have the service added to the manifest with the required intent-filter, and with logging I can see they are both starting up as expected.

I am following the docs, but I must be missing something.

Thanks for any help.

Handheld service

public class WeatherDataService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private static final String TAG = "HandheldService";
    private GoogleApiClient mGoogleClientApi;

    @Override
    public void onCreate() {
        super.onCreate();

        Log.d(TAG, "initializing");
        mGoogleClientApi = new GoogleApiClient.Builder(this)
                .addApi(Wearable.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        mGoogleClientApi.connect();
    }

    @Override
    public void onPeerConnected(Node peer) {
        super.onPeerConnected(peer);
        Log.d(TAG, "onPeerConnected: " + peer.getDisplayName());

        String[] temps = getCurrentTemps();

        if (temps != null && temps.length == 2) {
            Log.d(TAG, String.format("onPeerConnected: temps %s %s", temps[0], temps[1]));
            notifyWearables(mGoogleClientApi, temps[0], temps[1]);
        }
    }

    private void notifyWearables(GoogleApiClient client, String low, String high) {
        Log.d(TAG, String.format("notifyWearables: %s %s", low, high));
        PutDataMapRequest map = PutDataMapRequest.create("/weather");
        map.getDataMap().putString("tempLow", low);
        map.getDataMap().putString("tempHigh", high);

        PutDataRequest request = map.asPutDataRequest();
        Wearable.DataApi.putDataItem(client, request).setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
            @Override
            public void onResult(DataApi.DataItemResult result) {
                Log.d(TAG, String.format("onResult, %s", result.getStatus().getStatusMessage()));
                if (!result.getStatus().isSuccess()) {
                    Log.d(TAG, "onResult: Failed to send data");
                }
            }
        });



    ...
}

Wearable service

public class WeatherDataService extends WearableListenerService {

    private static final String TAG = "Wearable:Service";

    @Override
    public void onCreate() {
        super.onCreate();
        // this is called
        Log.d(TAG, "onCreate");
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        // NEVER makes it here
        Log.d(TAG, "onDataChanged: ");
        for (DataEvent dataEvent : dataEvents) {
            Log.d(TAG, "onDataChanged: " + dataEvent.getDataItem().getUri().getPath());
            if (dataEvent.getType() == DataEvent.TYPE_CHANGED) {
                Log.d(TAG, "onDataChanged: TYPE_CHANGED");
                DataMap dataMap = DataMapItem.fromDataItem(dataEvent.getDataItem()).getDataMap();
                String path = dataEvent.getDataItem().getUri().getPath();
                if (path.equals("/weather")) {
                    Log.d(TAG, "onDataChanged: /weather");
                    String tempLow = dataMap.getString("tempLow");
                    String tempHigh = dataMap.getString("tempHigh");

                    Log.d(TAG, "onDataChanged: " + tempLow + " " + tempHigh);
                }
            }
        }
    }
}

Update

I was missing the mGoogleApiClient.connect() method call. The putDataItem resultCallback is now being called, unforunately the wearable device's onDataChanged event is not being called.

Upvotes: 0

Views: 138

Answers (2)

chris
chris

Reputation: 4351

It turned out there was a couple things wrong with things.

The first was what @mahmoud mentioned, although I missed it the first time I read it, in that mGoogleClientApi.connect() needed to be called. When @mahmoud said connect to the client in onStart() I didn't read that as call the .connect() method.

The second things that was wrong was that the manifest package attributes did not match for each the modules. I thought they needed the same parent namespaces.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.sunshine.app">

Upvotes: 0

mahmoud moustafa
mahmoud moustafa

Reputation: 223

onDataChanged

doesn't call because you doesn't change any data that sent to wear every time(it's call only when the data really did change), try to send different data and it will work, and make sure to connect your mGoogleClientApi in onStrart();

Upvotes: 0

Related Questions