Wearable.NodeApi.getConnectedNodes result never ca

2020-07-05 07:05发布

问题:

i developing an app for android wear. Below code with explanation of the problem

 if(mGoogleApiClient.isConnected()){
            K.i("Always called!");
            Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
                @Override
                public void onResult(NodeApi.GetConnectedNodesResult nodes) {
                    K.i("Never called :( ");
                    for (Node node : nodes.getNodes()) {
                        Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), message, null);
                    }
                }
            });      
        }

UPD: I solve problem by turn off and turn on my phone again (Nexus 5) May be is there easier way to solve problem?

Tried to add .await() and AsyncTask, but result is the same

回答1:

I believe you can only call getConnectedNodes once per GoogleApiClient connection. You want to cache the node ID the first time you get the result, and then use the onPeerConnected/Disconnected() callbacks to track whether the node ID is still relevant.



回答2:

If you check out the google wear samples, there's a project called FindMyPhone. I think the way they solve your problem is a lot cleaner. They check if the device is connected or disconnected with a background service.

package com.example.android.wearable.findphone;

import android.app.Notification;
import android.app.NotificationManager;

import com.google.android.gms.wearable.WearableListenerService;

/**
 * Listens for disconnection from home device.
 */
public class DisconnectListenerService extends WearableListenerService {

    private static final String TAG = "ExampleFindPhoneApp";

    private static final int FORGOT_PHONE_NOTIFICATION_ID = 1;

    @Override
    public void onPeerDisconnected(com.google.android.gms.wearable.Node peer) {
        // Create a "forgot phone" notification when phone connection is broken.
        Notification.Builder notificationBuilder = new Notification.Builder(this)
                .setContentTitle(getString(R.string.left_phone_title))
                .setContentText(getString(R.string.left_phone_content))
                .setVibrate(new long[] {0, 200})  // Vibrate for 200 milliseconds.
                .setSmallIcon(R.drawable.ic_launcher)
                .setLocalOnly(true)
                .setPriority(Notification.PRIORITY_MAX);
        Notification card = notificationBuilder.build();
        ((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
                .notify(FORGOT_PHONE_NOTIFICATION_ID, card);
    }

    @Override
    public void onPeerConnected(com.google.android.gms.wearable.Node peer) {
        // Remove the "forgot phone" notification when connection is restored.
        ((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
                .cancel(FORGOT_PHONE_NOTIFICATION_ID);
    }

}

They also add this to the AndroidManifest.xml

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


回答3:

I got it working:

Init the Google API client:

private void initGoogleApiClient() {

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Wearable.API)
            .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                @Override
                public void onConnected(Bundle bundle) {
                    Log.d(TAG, "ConnectionCallback onConnected");
                    if (servicesAvailable()) {
                        // new CheckWearableConnected().execute();
                        resolveNodes();
                    }
                }

                @Override
                public void onConnectionSuspended(int i) {
                    Log.d(TAG, "ConnectionCallback onConnectionSuspended");
                }
            })
            .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(ConnectionResult connectionResult) {
                    Log.d(TAG, "ConnectionCallback onConnectionFailed");
                    //TODO do something on connection failed
                }
            })
            .build();

}

Then in your onStart method connect the API client:

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

And to clean up, in your onStop method:

@Override
protected void onStop() {
    super.onStop();
    Log.d(TAG, "onStop");
    if (mGoogleApiClient != null)
        if (mGoogleApiClient.isConnected()) mGoogleApiClient.disconnect();
}


回答4:

Here's a full code of how to check it:

add this to the gradle file:

compile 'com.google.android.gms:play-services-wearable:9.4.0'

And use this function to check if a wearable is connected:

@WorkerThread
public boolean isWearableAvailable(Context context) {
    NotificationManagerCompat.from(context).cancel(NotificationType.WEARABLE_IN_CALL.getId());
    final GoogleApiClient googleApiClient = new Builder(context).addApi(Wearable.API).build();
    final ConnectionResult connectionResult = googleApiClient.blockingConnect();
    if (connectionResult.isSuccess()) {
        NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await();
        for (Node node : nodes.getNodes()) {
            if (node.isNearby()) 
                return true;
        }
    }
    return false;
}