public final class NearbyTransport
- Object
- NearbyTransport
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.bonjourplus 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.
Methods
Inherited methods
Method details
isSupported
public static boolean isSupported()true when this port implements the nearby transport.getAvailability
public static NearbyAvailability getAvailability()Returns
getMaxPayloadSize
public static int getMaxPayloadSize()send accepts in one call. Anything bigger
has to go as a file payload.Returns
requestPermissions
public static AsyncResource<Boolean> requestPermissions(NearbyPermission... permissions)Parameters
permissionsNearbyPermission...- what the app intends to do
Returns
true when every requested permission is grantedstartAdvertising
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
serviceIdString- the service both ends agreed on
localNameString- the name to show peers
strategyTransportStrategy- the topology to use; must match on both sides
Returns
true once the platform is advertisingstopAdvertising
public static void stopAdvertising()startDiscovery
public static AsyncResource<Boolean> startDiscovery(String serviceId, TransportStrategy strategy)TransportListener.endpointFound.Parameters
serviceIdString- the service both ends agreed on
strategyTransportStrategy- the topology to use; must match on both sides
Returns
true once the platform is discoveringstopDiscovery
public static void stopDiscovery()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 or
TransportListener.connectionFailed.
Parameters
endpointEndpoint- the peer to ask
localNameString- the name to show them
Returns
true once the request has been sentsend
public static AsyncResource<Boolean> send(Endpoint endpoint, Payload payload)Parameters
endpointEndpoint- the recipient
payloadPayload- what to send
Returns
true once the payload is handed to the platform. Delivery
is reported by TransportListener.payloadProgress.send
public static AsyncResource<Boolean> send(Endpoint[] endpoints, Payload payload)Parameters
endpointsEndpoint[]- the recipients
payloadPayload- what to send
Returns
true once the payload is handed to the platformcancel
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
payloadIdint- the id from
Payload.getId()
disconnect
public static void disconnect(Endpoint endpoint)Parameters
endpointEndpoint- the peer to drop
stop
public static void stop()addTransportListener
public static void addTransportListener(TransportListener l)Parameters
lTransportListener- the listener to add
removeTransportListener
public static void removeTransportListener(TransportListener l)addTransportListener.Parameters
lTransportListener- the listener to remove