Android Nearby Connections cannot connect to device. Always returns 8011

688 views Asked by At

I am trying to use Google Nearby Connections API to connect two Android devices to exchange data but no success. The devices can found eachother none of them can connect to the other. It always fails at onConnectionInitiated() with STATUS_ENDPOINT_UNKNOWN when I try to accept the connection.

I tried it with Strategy.P2P_POINT_TO_POINT Strategy.CLUSTER and Strategy.STAR but I get the same result.

Anyone can help me what do I miss?

Both devices are physical and running on Android 9.0

This is the code:

    public static ConnectionLifecycleCallback connectionLifecycleCallback;
    public static EndpointDiscoveryCallback endpointDiscoveryCallback;
    public static PayloadCallback payloadCallback;
    public static String SERVICE_ID;
    public Context ctx;
    public static Strategy STRATEGY;

    public NearbyHandler(Context ctx,Strategy STRATEGY){
        this.ctx = ctx;
        this.STRATEGY = STRATEGY;
        SERVICE_ID = ctx.getPackageName();
        payloadCallback = new PayloadCallback() {
            @Override
            public void onPayloadReceived(@NonNull String s, @NonNull Payload payload) {
                Log.d("NEARBY_", "PAYLOAD RECEIVED " + s);
            }

            @Override
            public void onPayloadTransferUpdate(@NonNull String s, @NonNull PayloadTransferUpdate payloadTransferUpdate) {
                Log.d("NEARBY_", "PAYLOAD TRANSFER UPDATE " + s);
            }
        };
        connectionLifecycleCallback = new ConnectionLifecycleCallback() {
            @Override
            public void onConnectionInitiated(@NonNull String s, @NonNull ConnectionInfo connectionInfo) {
                Nearby.getConnectionsClient(ctx)
                        .acceptConnection(s, payloadCallback)
                        .addOnSuccessListener(new OnSuccessListener<Void>() {
                            @Override
                            public void onSuccess(Void aVoid) {
                                Log.d("NEARBY_", "SUCCESSFULLY CONNECTED");
                            }
                        })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                e.printStackTrace();
                            }
                        });
            }

            @Override
            public void onConnectionResult(@NonNull String s, @NonNull ConnectionResolution connectionResolution) {
                switch (connectionResolution.getStatus().getStatusCode()) {
                    case ConnectionsStatusCodes.STATUS_OK:
                        Nearby.getConnectionsClient(ctx).stopAdvertising();
                        Nearby.getConnectionsClient(ctx).stopDiscovery();
                        break;
                    case ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED:
                        break;
                    case ConnectionsStatusCodes.STATUS_ERROR:
                        break;
                }
            }

            @Override
            public void onDisconnected(@NonNull String s) {
                Log.d("NEARBY_", "DISCONNECTED " + s);
            }
        };
        endpointDiscoveryCallback = new EndpointDiscoveryCallback() {
            @Override
            public void onEndpointFound(@NonNull String s, @NonNull DiscoveredEndpointInfo discoveredEndpointInfo) {
                Nearby.getConnectionsClient(ctx)
                        .requestConnection(
                                s,
                                ctx.getPackageName(),
                                connectionLifecycleCallback)
                        .addOnSuccessListener(new OnSuccessListener<Void>() {
                            @Override
                            public void onSuccess(Void aVoid) {
                                Log.d("NEARBY_", "ENDPOINT CONNECTED");
                            }
                        })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Log.d("NEARBY_", "FAILED TO CONNECT ENDPOINT " + e.getMessage());
                                e.printStackTrace();
                            }
                        });
            }

            @Override
            public void onEndpointLost(@NonNull String s) {
                Log.d("NEARBY_", "ENDPOINT LOST: " + s);
            }
        };
    }

    public void startDiscovering() {
        Nearby.getConnectionsClient(ctx)
                .startDiscovery(
                        SERVICE_ID,
                        endpointDiscoveryCallback,
                        new DiscoveryOptions.Builder()
                                .setStrategy(CONSTANTS.PEERTOPEER_STRATEGY).build())
                .addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        Log.d("NEARBY_DISCOVERER_", "onSuccess");
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        e.printStackTrace();
                    }
                });
    }

    public void startAdvertising() {
        Nearby.getConnectionsClient(ctx)
                .startAdvertising(
                        Build.MODEL,
                        SERVICE_ID,
                        connectionLifecycleCallback,
                        new AdvertisingOptions.Builder()
                                .setStrategy(CONSTANTS.PEERTOPEER_STRATEGY).build())
                .addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        e.printStackTrace();
                    }
                });
    }
}
NearbyHandler nearby = new NearbyHandler(getApplicationContext(), Strategy.P2P_POINT_TO_POINT);
if (IS_DEVICE_A) {
      nearby.startAdvertising();
} else {
      nearby.startDiscovering();
}

Update: Google's walkietalkie demo app works fine on both phones.

1

There are 1 answers

0
sOnt On

Finally I've managed to get it working but not sure about the problem. I managed the connection lifecycle a bit different way than in the API Docs.

So I created a private helper class

class Endpoint {
    @NonNull
    private final String id;
    @NonNull
    private final String name;

    public Endpoint(@NonNull String id, @NonNull String name) {
        this.id = id;
        this.name = name;
    }

    @NonNull
    public String getId() {
        return id;
    }

    @NonNull
    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Endpoint) {
            Endpoint other = (Endpoint) obj;
            return id.equals(other.id);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return id.hashCode();
    }

    @Override
    public String toString() {
        return String.format("Endpoint{id=%s, name=%s}", id, name);
    }
}

The ConnectionLifecycleCallback() and EndpointDiscoveryCallback() should look like this:

endpointDiscoveryCallback = new EndpointDiscoveryCallback() {
    @Override
    public void onEndpointFound(@NonNull String s, @NonNull DiscoveredEndpointInfo discoveredEndpointInfo) {
        Endpoint endpoint = new Endpoint(s, discoveredEndpointInfo.getEndpointName());
        ConnectionsClient c = Nearby.getConnectionsClient(ctx);
        c.requestConnection(endpoint.getName(), endpoint.getId(), connectionLifecycleCallback).addOnSuccessListener(new OnSuccessListener < Void > () {
            @Override
            public void onSuccess(Void aVoid) {}
        });
    }

    @Override
    public void onEndpointLost(@NonNull String s) {}
};



connectionLifecycleCallback = new ConnectionLifecycleCallback() {
    @Override
    public void onConnectionInitiated(@NonNull String s, @NonNull ConnectionInfo connectionInfo) {
        Nearby.getConnectionsClient(ctx).stopAdvertising();
        Nearby.getConnectionsClient(ctx).stopDiscovery();
        Endpoint endpoint = new Endpoint(s, connectionInfo.getEndpointName());
        ConnectionsClient c = Nearby.getConnectionsClient(ctx);
        c.acceptConnection(endpoint.getId(), payloadCallback).addOnSuccessListener(new OnSuccessListener < Void > () {
            @Override
            public void onSuccess(Void aVoid) {}
        });
    }

    @Override
    public void onConnectionResult(@NonNull String s, @NonNull ConnectionResolution connectionResolution) {
        switch (connectionResolution.getStatus().getStatusCode()) {
            case ConnectionsStatusCodes.STATUS_OK:
                Nearby.getConnectionsClient(ctx).stopAdvertising();
                Nearby.getConnectionsClient(ctx).stopDiscovery();
                break;
            case ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED:
                // The connection was rejected by one or both sides.
                break;
            case ConnectionsStatusCodes.STATUS_ERROR:
                // The connection broke before it was able to be accepted.
                break;
        }
    }
    @Override
    public void onDisconnected(@NonNull String s) {}
};