Almost every multidevice experience begins with finding available devices. To simplify this common task, we offer the Device Discovery API.
Launch the device selection dialog
Device discovery uses a system dialog to let the user select a target device. To
initiate the device selection dialog, you first need to get a device discovery
client and register a result receiver. Note that similar to
registerForActivityResult
, this receiver must be registered unconditionally as
part of the activity or fragment initialization path.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) devicePickerLauncher = Discovery.create(this).registerForResult(this, handleDevices) }
Java
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); devicePickerLauncher = Discovery.create(this).registerForResult(this, handleDevices); }
In the code snippet above, we have an undefined handleDevices
object. After
the user chooses the devices to connect to, and once the SDK successfully
connects to the other devices, this callback receives the list of Participants
selected.
Kotlin
handleDevices = OnDevicePickerResultListener { participants -> participants.forEach { // Use participant info } }
Java
handleDevices = participants -> { for (Participant participant : participants) { // Use participant info } }
After the device picker is registered, launch it using the devicePickerLauncher
instance. DevicePickerLauncher.launchDevicePicker
takes two parameters – a
list of device filters (see section below) and a startComponentRequest
. The
startComponentRequest
is used to indicate which activity should be started on
the receiving device, and the reason for the request that is shown to the user.
Kotlin
devicePickerLauncher.launchDevicePicker( listOf(), startComponentRequest { action = "com.example.crossdevice.MAIN" reason = "I want to say hello to you" }, )
Java
devicePickerLauncher.launchDevicePickerFuture( Collections.emptyList(), new StartComponentRequest.Builder() .setAction("com.example.crossdevice.MAIN") .setReason("I want to say hello to you") .build());
Accept connection requests
When the user selects a device in the device picker, a dialog appears on the
receiving device to ask the user to accept the connection. Once accepted, the
target activity is launched, which can be handled in onCreate
and
onNewIntent
.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) handleIntent(getIntent()) } override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) handleIntent(intent) } private fun handleIntent(intent: Intent) { val participant = Discovery.create(this).getParticipantFromIntent(intent) // Accept connection from participant (see below) }
Java
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); handleIntent(getIntent()); } @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent); handleIntent(intent); } private void handleIntent(Intent intent) { Participant participant = Discovery.create(this).getParticipantFromIntent(intent); // Accept connection from participant (see below) }
Device filters
When discovering devices, it’s common to want to filter these devices to only show the ones relevant to the use case at hand. For example:
- Filtering to only devices with camera to help scan a QR code
- Filtering to only TVs for a big screen viewing experience
For this developer preview, we are starting with the ability to filter to devices owned by the same user.
You can specify the device filter using class DeviceFilter
:
Kotlin
val deviceFilters = listOf(DeviceFilter.trustRelationshipFilter(MY_DEVICES_ONLY))
Java
List<DeviceFilter> deviceFilters = Arrays.asList(DeviceFilter.trustRelationshipFilter(MY_DEVICES_ONLY));
Once you define the device filters, you can initiate device discovery.
Kotlin
devicePickerLauncher.launchDevicePicker(deviceFilters, startComponentRequest)
Java
Futures.addCallback( devicePickerLauncher.launchDevicePickerFuture(deviceFilters, startComponentRequest), new FutureCallback<Void>() { @Override public void onSuccess(Void result) { // do nothing, result will be returned to handleDevices callback } @Override public void onFailure(Throwable t) { // handle error } }, mainExecutor);
Notice that the launchDevicePicker
is an asynchronous function that uses the
suspend
keyword.