1

I'm developing an Android app that includes some wearable features. I have some notifications using WearableExtender and they're working fine. But when I try to use the Data Layer Api it doesn't work.

I've used the code proposed in the answer of this post: Android Wear Watchface Settings on host but onDataChanged(DataEventBuffer dataEvents) is never called. I'm using Android emulator for mobile and watch.

This is what I get on the watch's LogCat:

11-10 05:43:44.777: D/DataItems(1333): inserted data item row 60 for DataItemRecord
[es.example.rebeca.prueba,10b8f01e736f2a1276b2bbf41a6c6dd18c005e65,DataItemInternal
[f702125c, dataSz=65, host=db03afd0-746e-48ad-8b0d-98ff360bf672, path=/SAMPLE, numAssets=0],
db03afd0-746e-48ad-8b0d-98ff360bf672,seqId=13136,assetsAreReady=false]

it seems like something is received on the watch with the appropiate path (path=/SAMPLE). However, I can't see any messages (I put a few Logs to check if the data gets to the watch).

Any hint would be appreciated.

EDIT:

The code I use on the phone side:

public class MainActivity extends Activity {
    private GoogleApiClient mGoogleApiClient;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
       mGoogleApiClient = new GoogleApiClient.Builder(this)
           .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                @Override
                public void onConnected(Bundle connectionHint) {
                   Log.d("DataLayerApi", "onConnected()"); //This is shown
           }
                @Override
                public void onConnectionSuspended(int cause) { }
                })
           .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(ConnectionResult result) {}
           })
           .addApi(Wearable.API)
           .build();
        mGoogleApiClient.connect();
    }

    public void sendWearable(View v) {  //This is a button
        syncSampleDataItem();
    }

    private void syncSampleDataItem() {
        if(mGoogleApiClient == null)
        return;

        final PutDataMapRequest putRequest = PutDataMapRequest.create("/SAMPLE");
        final DataMap map = putRequest.getDataMap();
        map.putInt("color", Color.RED);
        map.putString("string_example", "Sample String");
        Wearable.DataApi.putDataItem(mGoogleApiClient,  putRequest.asPutDataRequest());
    }
}

in the AndroidManifest.xml:

<uses-feature android:name="android.hardware.type.watch" />

The code I use on the wearable side:

public class ListenerService extends WearableListenerService { 

String myTag = "DataLayerApi";

@Override
public void onDataChanged(DataEventBuffer dataEvents) {
    super.onDataChanged(dataEvents);
    Log.d(myTag, "onDataChanged()" + dataEvents); //This is NEVER shown

    final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
    for(DataEvent event : events) {
        final Uri uri = event.getDataItem().getUri();
        final String path = uri!=null ? uri.getPath() : null;
        if("/SAMPLE".equals(path)) {
            final DataMap map = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
            // read your values from map:
            int color = map.getInt("color");
            String stringExample = map.getString("string_example");
            Log.d(myTag, color + stringExample); //This is NEVER shown
        }
    }
}

in the AndroidManifest.xml:

<service android:name=".ListenerService"
        android:exported="true" >
        <intent-filter>
            <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
        </intent-filter>
</service>

and in both Manifests I have the line:

<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

inside the application tag

Community
  • 1
  • 1
rgc92
  • 125
  • 9

2 Answers2

2

So it turns out that you need to use the SAME package name in both wearable and handheld modules. I changed it and now the code is working!

rgc92
  • 125
  • 9
  • good to hear. But I have difficult time on putting sample code app on wearable. I have moto 360. I use this sample. https://developer.android.com/samples/Quiz/index.html I signed the apk. the Quiz app just never shows. Can you give it a try? – Liangjun Nov 11 '14 at 18:45
  • Have you tried with Android Wear emulator? I can only try with it because I haven't got a watch. – rgc92 Nov 11 '14 at 19:31
  • Yes. I tried on emulator. Not working either. Please go ahead to give it a try and let me know your result. Have been battling it for a few hours. – Liangjun Nov 11 '14 at 19:32
  • Use the code sample available with Android Studio (Program Files (x86)/Android/android-studio/sdk/samples/android-20), not the code from the page you posted because they are different! I tried to execute the one you suggested and I was able to run only the mobile module. You should've seen that the wear and handheld packages are **different!** So it wouldn't work. However, in the directory that I'm telling you, the packages are **equal**: package com.example.android.wearable.quiz; Try it and let me know! – rgc92 Nov 11 '14 at 21:23
  • Right. mobile module runs fine. wonder why the wearable doesn't work. – Liangjun Nov 11 '14 at 21:25
  • I didn't. but seems the code works for some reason. I am not sure what I have done, honestly. Now the quiz is showing on my Moto360. – Liangjun Nov 13 '14 at 16:37
0

From the looks of it, your wearable side is incorrect. Your wear app also needs it own instance of the GoogleApiClient.

gatlingxyz
  • 781
  • 6
  • 12
  • Why does it need the GoogleApiClient? – rgc92 Nov 11 '14 at 08:46
  • In order to get the data that's been changed, the wearable app needs to communicate with Google Play Services. In order to do this, you need a `GoogleApiClient`. Edit: Though, apparently you've got it working so I might be wrong. – gatlingxyz Nov 11 '14 at 20:46
  • I would need it if I want to communicate back to handheld. – rgc92 Nov 12 '14 at 08:54