Using GoogleApiClient from Push Notification Inten

2019-04-09 02:25发布

问题:

This is a follow up question to... Android Wear Bundled Notifications and Background Images

I'd like to create a Android Wear GridViewPager layout that get's created when a new push notification comes in.

Below is my code that initializes a GoogleApiClient connection when a new message comes in so I can then send data to the wear app which then creates the GridView Pager.

My problem is that the GoogleApiClient never gets a connection. I've successfully run the SynchonizedNotifications sample app in the sdk folder so I know my device and watch are paired correctly.

Below is current code...

public class GCMIntentService extends IntentService implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener{

    @Override
    protected void onHandleIntent(Context context, Intent intent) {

        mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Wearable.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

        ConnectionResult connectionResult =   mGoogleApiClient.blockingConnect(30, TimeUnit.SECONDS);

        // Extract the payload from the message
        Bundle extras = intent.getExtras();
        if (this.mGoogleApiClient.isConnected())        {

           // sending a simple message works
           MessageApi.SendMessageResult result = Wearable.MessageApi.sendMessage(mGoogleApiClient,
                node.getId(), "path", null).await();

            PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(Constants.BOTH_PATH);
            putDataMapRequest.getDataMap().putString(Constants.KEY_CONTENT, "content");
            putDataMapRequest.getDataMap().putString(Constants.KEY_TITLE, "title");
            PutDataRequest request = putDataMapRequest.asPutDataRequest();

            // push data to wear app here
            Wearable.DataApi.putDataItem(mGoogleApiClient, request)
                .setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
                    @Override
                    public void onResult(DataApi.DataItemResult dataItemResult) {
                        if (!dataItemResult.getStatus().isSuccess()) {
                            Log.e(TAG, "Failed to set the data, status: " + dataItemResult.getStatus().getStatusCode());
                        }else{
                            // get here, but no message received from wear
                            Log.i(TAG,"SUCCESSFUL RESPONSE RECEIVED FROM WEAR");
                        }
                        mGoogleApiClient.disconnect();
                    }
                });

        } else {
            Log.e(TAG, "no Google API Client connection");
        }
    }
}

回答1:

It looks like your data isn't ever changing. When you're using the DataItem API approach, don't think of it as sending data over from the device to the wearable (or vice versa). Instead, remember that you're just manipulating a cache that is shared across devices: you're syncing data, not transferring it.

This ultimately means that your listener won't trigger unless the data is changed. That's why the method is called onDataChanged(). The underlying API handles updating the cache with your PutDataRequest intelligently to be much more efficient. If you're syncing a payload that contains the same information, you won't notice anything.

So try this: add a timestamp to your payload. Maybe something like putDataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis()); Your payload will be different each time, and you should see that onDataChanged() will now trigger.

Yeah, it took me a while to figure this out!



回答2:

First of all, if this is your full code, you're not actually calling connect() on the GoogleApiClient.

Secondly, connect() is asynchronous, so you cannot just do something like

mGoogleApiClient.connect();
if (mGoogleApiClient.isConnected()) ... 

You need to wait for the connection callbacks instead. Or, if you're executing this code in a background thread, you can use blockingConnect() instead.