Kristy
Kristy

Reputation: 131

WearableDataListener Service doesn't invoke onDataChanged method

I am making a wear app which fetches data from database(which is on handheld) on launch of app home screen. So when the homepage activity launches, It sends a message using Wearable.MessageApi.sendMessage function from the android wear to handheld. On the handheld I have the WearableListenerService which receives this message in onMessageReceived function and reads database. After reading database it sends putDatamapRequest to the wear.

Now on the wear side, I have another WearableListenerService. In this service, onDataChanged() function is never invoked. It runs at times, so far it ran for 2-3 times but otherwise it doesn't run. It's very random. Also once the data is received in Wear side, I set a static Arraylist, which I use to display data in Activity. But since the onDataChanged function is not always called, it gives empty array list.

Here is my AndroidManifest file of wear app where I declared the service:

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

Here is my code to send message from wear to handheld:

mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {

        @Override
        public void onConnected(Bundle bundle) {
                                    Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
                        @Override
                        public void onResult(NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
                            if(!getConnectedNodesResult.getNodes().isEmpty())
                            {
                                node = getConnectedNodesResult.getNodes().get(0);
                                System.out.println("Connected: "+ node.getId());
                                Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), FETCH_ALL_DEALS, null).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
                                    @Override
                                    public void onResult(MessageApi.SendMessageResult sendMessageResult) {
                                        if (!sendMessageResult.getStatus().isSuccess()) {
                                            Log.e("Wear:", "ERROR: failed to send Message: " + sendMessageResult.getStatus());
                                        }
                                        else
                                            System.out.println("success");
                                    }
                                });

                            }
                            else
                                System.out.println("Wear not connected to Phone");
                        }
                    });

        }

            @Override
            public void onConnectionSuspended(int i) {

            }



        })
        .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
            @Override
            public void onConnectionFailed(ConnectionResult result) {
                Log.v("Phone to wear connection failed", "onConnectionFailed: " + result);
            }
        })
        .addApi(Wearable.API)
        .build();
        mGoogleApiClient.connect();

Here is my code for onMessageReceive on Handheld:

 public void onMessageReceived(MessageEvent messageEvent) {
    System.out.println("Message Received on Phone on launch of wear homepage");
    if(messageEvent.getPath().equals(FETCH_ALL_DEALS)) {
        sendSavedDeals(); //fetch from db and make a datamap object using PutDataRequest
        System.out.println("Message Received on Phone on launch of wear homepage");
    }
    else {
        System.out.println("Unable to recognise action for "+messageEvent.getPath());
    }

}

Now on my wear side I have a WearableListenerService but it's onDataChanged method never gets called. Could you please help me with that.

Upvotes: 4

Views: 4178

Answers (3)

Anees
Anees

Reputation: 522

Data should be changed or deleted to get call-back to onDataChanged in WearabaleListenerService in your wear. if you want make changes open APP-info from settings and clear-data then after force stop . Finally launch your app in phone..but ensure that wearable listener service should be already started in your wear..

Upvotes: 1

Pierre Maoui
Pierre Maoui

Reputation: 6384

When onDataChanged() is not being called :

Firstly, ensure that the handheld activity is connecting to the API at the start :


    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

otherwise, it fails silently.

If it still doesn't work, to facilitate the debug, add this override method and this class in the handheld activity to generate data every 5 seconds :


    @Override
    public void onResume() {
        super.onResume();
        mDataItemGeneratorFuture = mGeneratorExecutor.scheduleWithFixedDelay(
            new DataItemGenerator(), 1, 5, TimeUnit.SECONDS
        );
    }


    /** Generates a DataItem based on an incrementing count. */
    private class DataItemGenerator implements Runnable {
        private int count = 0;

        @Override
        public void run() {
        PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(COUNT_PATH);
        putDataMapRequest.getDataMap().putInt(COUNT_KEY, count++);
        PutDataRequest request = putDataMapRequest.asPutDataRequest();

        Log.d("yourApp", "Generating DataItem: " + request);
        if (!mGoogleApiClient.isConnected()) {
            return;
        }
        Wearable.DataApi.putDataItem(mGoogleApiClient, request)
            .setResultCallback(new ResultCallback() {

                @Override
                public void onResult(DataItemResult dataItemResult) {
                    if (!dataItemResult.getStatus().isSuccess()) {
                        Log.e("YourApp", "ERROR: failed to putDataItem, status code: "
                            + dataItemResult.getStatus().getStatusCode());
                    }
                }
            });
        }
    }

Upvotes: 0

Tom
Tom

Reputation: 5068

onDataChanged() is only called when the data really did change. If you put the same data into the DataApi multiple times, the method is only called once until you write different data.

To trigger an action on the wear side, even when the data didn't change, send a message after putting data into the DataApi.

Upvotes: 13

Related Questions