Class NearbyTransport

java.lang.Object
com.codename1.nearby.transport.NearbyTransport

public final class NearbyTransport extends Object

Moving bytes and files to a device that is physically nearby, with no access point, no pairing and no internet.

The platform picks and combines the radios itself -- Bluetooth to find each other, then Wi-Fi to move the data -- so an app advertises a service id, discovers peers using the same id, connects, and sends payloads.

This transport does not cross ecosystems

Android talks to Android and Apple talks to Apple, and the two do not meet. Underneath are Google's Nearby Connections and Apple's MultipeerConnectivity, which share no wire protocol; nothing in this API papers over that, because a portable-looking API that silently never finds the peer is worse than an honest limitation.

For an iPhone that must talk to an Android phone, the framework already has two things that do work across the divide:

  • com.codename1.bluetooth.le.L2capChannel -- a raw bidirectional byte stream over BLE, on every platform that has BLE.
  • com.codename1.io.bonjour plus ordinary sockets, when both devices are on the same Wi-Fi network.
Quick start
NearbyTransport.addTransportListener(new TransportAdapter() {
    public void endpointFound(Endpoint e) {
        NearbyTransport.requestConnection(e, "Shai's phone");
    }
    public void connectionRequested(IncomingConnection r) {
        // show r.getAuthenticationToken() on both screens before this
        r.accept();
    }
    public void connected(Endpoint e) {
        NearbyTransport.send(e, Payload.fromBytes(data));
    }
    public void payloadReceived(Endpoint e, Payload p) {
        process(p.getBytes());
    }
});
NearbyTransport.startAdvertising("com.example.chat", "Shai's phone",
        TransportStrategy.CLUSTER);
NearbyTransport.startDiscovery("com.example.chat", TransportStrategy.CLUSTER);
Threading

Every callback here is delivered on the EDT.

  • Method Details

    • isSupported

      public static boolean isSupported()
      true when this port implements the nearby transport.
    • getAvailability

      public static NearbyAvailability getAvailability()

      How usable the transport is right now.

      Returns

      the current availability, never null

    • getMaxPayloadSize

      public static int getMaxPayloadSize()

      The largest byte payload send(Endpoint, Payload) accepts in one call. Anything bigger has to go as a file payload.

      Returns

      the limit in bytes, or zero when the transport is unsupported

    • requestPermissions

      public static AsyncResource<Boolean> requestPermissions(NearbyPermission... permissions)

      Asks for the runtime permissions the transport needs -- on Android that is the Bluetooth trio plus nearby Wi-Fi, which is a lot to ask for at once, so ask when the user reaches the feature rather than at startup.

      Parameters
      • permissions: what the app intends to do
      Returns

      resolves true when every requested permission is granted

    • startAdvertising

      public static AsyncResource<Boolean> startAdvertising(String serviceId, String localName, TransportStrategy strategy)

      Starts advertising this device so peers running the same service id can find it.

      The service id must match exactly on both sides. On iOS it also becomes the Bonjour service type, which the platform restricts to fifteen characters of lowercase letters, digits and hyphens -- so a reverse-DNS string works on Android and is rejected on iOS. Pick a short one.

      Parameters
      • serviceId: the service both ends agreed on
      • localName: the name to show peers
      • strategy: the topology to use; must match on both sides
      Returns

      resolves true once the platform is advertising

    • stopAdvertising

      public static void stopAdvertising()
      Stops advertising. Idempotent; existing connections stay open.
    • startDiscovery

      public static AsyncResource<Boolean> startDiscovery(String serviceId, TransportStrategy strategy)

      Starts looking for peers advertising the same service id. Sightings arrive as TransportListener.endpointFound(Endpoint).

      Parameters
      • serviceId: the service both ends agreed on
      • strategy: the topology to use; must match on both sides
      Returns

      resolves true once the platform is discovering

    • stopDiscovery

      public static void stopDiscovery()
      Stops discovery. Idempotent; existing connections stay open.
    • requestConnection

      public static AsyncResource<Boolean> requestConnection(Endpoint endpoint, String localName)

      Asks a discovered endpoint to connect.

      The resource here resolves once the request has been sent, which is not the same as being connected: the far side still has to accept, and that answer arrives as TransportListener.connected(Endpoint) or TransportListener.connectionFailed(Endpoint, NearbyException).

      Parameters
      • endpoint: the peer to ask
      • localName: the name to show them
      Returns

      resolves true once the request has been sent

    • send

      public static AsyncResource<Boolean> send(Endpoint endpoint, Payload payload)

      Sends a payload to one connected endpoint.

      Parameters
      • endpoint: the recipient
      • payload: what to send
      Returns

      resolves true once the payload is handed to the platform. Delivery is reported by TransportListener.payloadProgress(Endpoint, PayloadTransferUpdate).

    • send

      public static AsyncResource<Boolean> send(Endpoint[] endpoints, Payload payload)

      Sends a payload to several connected endpoints at once, which both platforms do more efficiently than one call each.

      Parameters
      • endpoints: the recipients
      • payload: what to send
      Returns

      resolves true once the payload is handed to the platform

    • cancel

      public static void cancel(int payloadId)

      Cancels an in-flight payload. Idempotent.

      The send reaches PayloadStatus.CANCELED on this side, and a transfer the platform can still recall is recalled -- which for a file is every byte not yet sent, on all three implementations.

      A BYTE payload is a different matter, and the same on every one of them: it is handed to the platform whole, and no platform offers a handle to take it back. Cancelling one that has already been accepted stops this side reporting it as delivered, but the peer may receive it anyway. Cancel a byte payload to stop waiting on it, not to prevent its arrival.

      Parameters
    • disconnect

      public static void disconnect(Endpoint endpoint)

      Disconnects one endpoint. Idempotent.

      Parameters
      • endpoint: the peer to drop
    • stop

      public static void stop()
      Stops advertising and discovery and drops every connection. Call it when the feature's UI closes: both platforms keep the radios busy until something says stop.
    • addTransportListener

      public static void addTransportListener(TransportListener l)

      Registers a listener. Callbacks arrive on the EDT.

      Parameters
      • l: the listener to add
    • removeTransportListener

      public static void removeTransportListener(TransportListener l)

      Removes a listener added by addTransportListener(TransportListener).

      Parameters
      • l: the listener to remove