CompanionDeviceManager


public final class CompanionDeviceManager
extends Object

java.lang.Object
   ↳ android.companion.CompanionDeviceManager


Public interfaces for managing companion devices.

The interfaces in this class allow companion apps to associate(android.companion.AssociationRequest, java.util.concurrent.Executor, android.companion.CompanionDeviceManager.Callback) discover and request device profiles} for companion devices, listen to device presence events, transfer system level data via the reported channel and more.

Developer Guides

For more information about managing companion devices, read the Companion Device Pairing developer guide.


Requires the PackageManager#FEATURE_COMPANION_DEVICE_SETUP feature which can be detected using PackageManager.hasSystemFeature(String).

Summary

Nested classes

class CompanionDeviceManager.Callback

Callback for applications to receive updates about and the outcome of AssociationRequest issued via associate() call. 

Constants

String EXTRA_ASSOCIATION

Extra field name for the AssociationInfo object, included into Intent which application receive in Activity#onActivityResult(int, int, Intent) after the application's AssociationRequest was successfully processed and an association was created.

String EXTRA_DEVICE

This constant was deprecated in API level 33. use AssociationInfo#getAssociatedDevice() instead.

int FLAG_CALL_METADATA

Used by enableSystemDataSyncForTypes(int, int)}.

int RESULT_CANCELED

The result code to propagate back to the user activity, indicates if the association dialog is implicitly cancelled.

int RESULT_DISCOVERY_TIMEOUT

The result code to propagate back to the user activity, indicates the association dialog is dismissed if there's no device found after 20 seconds.

int RESULT_INTERNAL_ERROR

The result code to propagate back to the user activity, indicates the internal error in CompanionDeviceManager.

int RESULT_OK

The result code to propagate back to the user activity, indicates the association is created successfully.

int RESULT_USER_REJECTED

The result code to propagate back to the user activity, indicates the association dialog is explicitly declined by the users.

Public methods

void associate(AssociationRequest request, Executor executor, CompanionDeviceManager.Callback callback)

Request to associate this app with a companion device.

void associate(AssociationRequest request, CompanionDeviceManager.Callback callback, Handler handler)

Request to associate this app with a companion device.

void attachSystemDataTransport(int associationId, InputStream in, OutputStream out)

Attach a bidirectional communication stream to be used as a transport channel for transporting system data between associated devices.

IntentSender buildAssociationCancellationIntent()

Cancel the current association activity.

IntentSender buildPermissionTransferUserConsentIntent(int associationId)

Build a permission sync user consent dialog.

void detachSystemDataTransport(int associationId)

Detach the transport channel that's previously attached for the associated device.

void disableSystemDataSyncForTypes(int associationId, int flags)

Disable system data sync (it only supports call metadata sync for now).

void disassociate(int associationId)

Remove an association.

void disassociate(String deviceMacAddress)

This method was deprecated in API level 33. use disassociate(int)

void enableSystemDataSyncForTypes(int associationId, int flags)

Enable system data sync (it only supports call metadata sync for now).

List<String> getAssociations()

This method was deprecated in API level 33. use getMyAssociations()

List<AssociationInfo> getMyAssociations()

Calling this API requires a uses-feature PackageManager#FEATURE_COMPANION_DEVICE_SETUP declaration in the manifest

boolean hasNotificationAccess(ComponentName component)

This method was deprecated in API level 33. Use NotificationManager#isNotificationListenerAccessGranted(ComponentName) instead.

boolean isPermissionTransferUserConsented(int associationId)

Return the current state of consent for permission transfer for the association.

void requestNotificationAccess(ComponentName component)

Request notification access for the given component.

void startObservingDevicePresence(String deviceAddress)

Register to receive callbacks whenever the associated device comes in and out of range.

void startSystemDataTransfer(int associationId, Executor executor, OutcomeReceiver<VoidCompanionException> result)

Start system data transfer which has been previously approved by the user.

void stopObservingDevicePresence(String deviceAddress)

Unregister for receiving callbacks whenever the associated device comes in and out of range.

Inherited methods

Constants

EXTRA_ASSOCIATION

Added in API level 33
public static final String EXTRA_ASSOCIATION

Extra field name for the AssociationInfo object, included into Intent which application receive in Activity#onActivityResult(int, int, Intent) after the application's AssociationRequest was successfully processed and an association was created.

Constant Value: "android.companion.extra.ASSOCIATION"

EXTRA_DEVICE

Added in API level 26
Deprecated in API level 33
public static final String EXTRA_DEVICE

This constant was deprecated in API level 33.
use AssociationInfo#getAssociatedDevice() instead.

A device, returned in the activity result of the IntentSender received in Callback#onDeviceFound Type is:

Constant Value: "android.companion.extra.DEVICE"

FLAG_CALL_METADATA

Added in API level 34
public static final int FLAG_CALL_METADATA

Used by enableSystemDataSyncForTypes(int, int)}. Sync call metadata like muting, ending and silencing a call.

Constant Value: 1 (0x00000001)

RESULT_CANCELED

Added in API level 34
public static final int RESULT_CANCELED

The result code to propagate back to the user activity, indicates if the association dialog is implicitly cancelled. E.g. phone is locked, switch to another app or press outside the dialog.

Constant Value: 0 (0x00000000)

RESULT_DISCOVERY_TIMEOUT

Added in API level 34
public static final int RESULT_DISCOVERY_TIMEOUT

The result code to propagate back to the user activity, indicates the association dialog is dismissed if there's no device found after 20 seconds.

Constant Value: 2 (0x00000002)

RESULT_INTERNAL_ERROR

Added in API level 34
public static final int RESULT_INTERNAL_ERROR

The result code to propagate back to the user activity, indicates the internal error in CompanionDeviceManager.

Constant Value: 3 (0x00000003)

RESULT_OK

Added in API level 34
public static final int RESULT_OK

The result code to propagate back to the user activity, indicates the association is created successfully.

Constant Value: -1 (0xffffffff)

RESULT_USER_REJECTED

Added in API level 34
public static final int RESULT_USER_REJECTED

The result code to propagate back to the user activity, indicates the association dialog is explicitly declined by the users.

Constant Value: 1 (0x00000001)

Public methods

associate

Added in API level 33
public void associate (AssociationRequest request, 
                Executor executor, 
                CompanionDeviceManager.Callback callback)

Request to associate this app with a companion device.

Note that before creating establishing association the system may need to show UI to collect user confirmation.

If the app needs to be excluded from battery optimizations (run in the background) or to have unrestricted data access (use data in the background) it should declare use of Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND and Manifest.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND in its AndroidManifest.xml respectively. Note that these special capabilities have a negative effect on the device's battery and user's data usage, therefore you should request them when absolutely necessary.

Application can use getMyAssociations() for retrieving the list of currently AssociationInfo objects, that represent their existing associations. Applications can also use disassociate(int) to remove an association, and are recommended to do when an association is no longer relevant to avoid unnecessary battery and/or data drain resulting from special privileges that the association provides

Note that if you use this api to associate with a Bluetooth device, please make sure to cancel your own Bluetooth discovery before calling this api, otherwise the callback may fail to return the desired device.

Calling this API requires a uses-feature PackageManager#FEATURE_COMPANION_DEVICE_SETUP declaration in the manifest

Parameters
request AssociationRequest: A request object that describes details of the request. This value cannot be null.

executor Executor: The executor which will be used to invoke the callback. This value cannot be null.

callback CompanionDeviceManager.Callback: The callback used to notify application when the association is created. This value cannot be null.

associate

Added in API level 26
public void associate (AssociationRequest request, 
                CompanionDeviceManager.Callback callback, 
                Handler handler)

Request to associate this app with a companion device.

Note that before creating establishing association the system may need to show UI to collect user confirmation.

If the app needs to be excluded from battery optimizations (run in the background) or to have unrestricted data access (use data in the background) it should declare use of Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND and Manifest.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND in its AndroidManifest.xml respectively. Note that these special capabilities have a negative effect on the device's battery and user's data usage, therefore you should request them when absolutely necessary.

Application can use getMyAssociations() for retrieving the list of currently AssociationInfo objects, that represent their existing associations. Applications can also use disassociate(int) to remove an association, and are recommended to do when an association is no longer relevant to avoid unnecessary battery and/or data drain resulting from special privileges that the association provides

Calling this API requires a uses-feature PackageManager#FEATURE_COMPANION_DEVICE_SETUP declaration in the manifest

Parameters
request AssociationRequest: A request object that describes details of the request. This value cannot be null.

callback CompanionDeviceManager.Callback: The callback used to notify application when the association is created. This value cannot be null.

handler Handler: The handler which will be used to invoke the callback. This value may be null.

attachSystemDataTransport

Added in API level 34
public void attachSystemDataTransport (int associationId, 
                InputStream in, 
                OutputStream out)

Attach a bidirectional communication stream to be used as a transport channel for transporting system data between associated devices.
Requires Manifest.permission.DELIVER_COMPANION_MESSAGES

Parameters
associationId int: id of the associated device.

in InputStream: Already connected stream of data incoming from remote associated device. This value cannot be null.

out OutputStream: Already connected stream of data outgoing to remote associated device. This value cannot be null.

Throws
DeviceNotAssociatedException Thrown if the associationId was not previously associated with this app.

buildAssociationCancellationIntent

Added in API level 34
public IntentSender buildAssociationCancellationIntent ()

Cancel the current association activity.

The app should launch the returned intentSender by calling Activity#startIntentSenderForResult(IntentSender, int, Intent, int, int, int) to cancel the current association activity

Calling this API requires a uses-feature PackageManager#FEATURE_COMPANION_DEVICE_SETUP declaration in the manifest

Returns
IntentSender An IntentSender that the app should use to launch in order to cancel the current association activity This value may be null.

buildPermissionTransferUserConsentIntent

Added in API level 34
public IntentSender buildPermissionTransferUserConsentIntent (int associationId)

Build a permission sync user consent dialog.

Only the companion app which owns the association can call this method. Otherwise a null IntentSender will be returned from this method and an error will be logged. The app should launch the Activity in the returned intentSender IntentSender by calling Activity#startIntentSenderForResult(IntentSender, int, Intent, int, int, int).

The permission transfer doesn't happen immediately after the call or when the user consents. The app needs to call attachSystemDataTransport(int, java.io.InputStream, java.io.OutputStream) to attach a transport channel and startSystemDataTransfer(int, java.util.concurrent.Executor, android.os.OutcomeReceiver) to trigger the system data transfer}.

Parameters
associationId int: The unique ID assigned to the association of the companion device recorded by CompanionDeviceManager

Returns
IntentSender An IntentSender that the app should use to launch the UI for the user to confirm the system data transfer request.

Throws
DeviceNotAssociatedException

detachSystemDataTransport

Added in API level 34
public void detachSystemDataTransport (int associationId)

Detach the transport channel that's previously attached for the associated device. The system will stop transferring any system data when this method is called.
Requires Manifest.permission.DELIVER_COMPANION_MESSAGES

Parameters
associationId int: id of the associated device.

Throws
DeviceNotAssociatedException Thrown if the associationId was not previously associated with this app.

disableSystemDataSyncForTypes

Added in API level 34
public void disableSystemDataSyncForTypes (int associationId, 
                int flags)

Disable system data sync (it only supports call metadata sync for now). By default all supported system data types are enabled.

Calling this API requires a uses-feature PackageManager#FEATURE_COMPANION_DEVICE_SETUP declaration in the manifest

Parameters
associationId int: id of the device association.

flags int: system data types to be disabled. Value is either 0 or FLAG_CALL_METADATA

disassociate

Added in API level 33
public void disassociate (int associationId)

Remove an association.

Any privileges provided via being associated with a given device will be revoked

Calling this API requires a uses-feature PackageManager#FEATURE_COMPANION_DEVICE_SETUP declaration in the manifest

Parameters
associationId int: id of the association to be removed.

disassociate

Added in API level 26
Deprecated in API level 33
public void disassociate (String deviceMacAddress)

This method was deprecated in API level 33.
use disassociate(int)

Remove the association between this app and the device with the given mac address.

Any privileges provided via being associated with a given device will be revoked

Consider doing so when the association is no longer relevant to avoid unnecessary battery and/or data drain resulting from special privileges that the association provides

Calling this API requires a uses-feature PackageManager#FEATURE_COMPANION_DEVICE_SETUP declaration in the manifest

Parameters
deviceMacAddress String: the MAC address of device to disassociate from this app. Device address is case-sensitive in API level < 33. This value cannot be null.

enableSystemDataSyncForTypes

Added in API level 34
public void enableSystemDataSyncForTypes (int associationId, 
                int flags)

Enable system data sync (it only supports call metadata sync for now). By default all supported system data types are enabled.

Calling this API requires a uses-feature PackageManager#FEATURE_COMPANION_DEVICE_SETUP declaration in the manifest

Parameters
associationId int: id of the device association.

flags int: system data types to be enabled. Value is either 0 or FLAG_CALL_METADATA

getAssociations

Added in API level 26
Deprecated in API level 33
public List<String> getAssociations ()

This method was deprecated in API level 33.
use getMyAssociations()

Calling this API requires a uses-feature PackageManager#FEATURE_COMPANION_DEVICE_SETUP declaration in the manifest

Returns
List<String> a list of MAC addresses of devices that have been previously associated with the current app are managed by CompanionDeviceManager (ie. does not include devices managed by application itself even if they have a MAC address). This value cannot be null.

getMyAssociations

Added in API level 33
public List<AssociationInfo> getMyAssociations ()

Calling this API requires a uses-feature PackageManager#FEATURE_COMPANION_DEVICE_SETUP declaration in the manifest

Returns
List<AssociationInfo> a list of associations that have been previously associated with the current app. This value cannot be null.

hasNotificationAccess

Added in API level 26
Deprecated in API level 33
public boolean hasNotificationAccess (ComponentName component)

This method was deprecated in API level 33.
Use NotificationManager#isNotificationListenerAccessGranted(ComponentName) instead.

Check whether the given component can access the notifications via a NotificationListenerService Your app must have an association with a device before calling this API

Calling this API requires a uses-feature PackageManager#FEATURE_COMPANION_DEVICE_SETUP declaration in the manifest

Parameters
component ComponentName: the name of the component

Returns
boolean whether the given component has the notification listener permission

isPermissionTransferUserConsented

Added in API level 35
public boolean isPermissionTransferUserConsented (int associationId)

Return the current state of consent for permission transfer for the association. True if the user has allowed permission transfer for the association, false otherwise.

Note: The initial user consent is collected via a permission transfer user consent dialog. After the user has made their initial selection, they can toggle the permission transfer feature in the settings. This method always returns the state of the toggle setting.

Parameters
associationId int: The unique ID assigned to the association of the companion device recorded by CompanionDeviceManager

Returns
boolean True if the user has consented to the permission transfer, or false otherwise.

Throws
DeviceNotAssociatedException Exception if the companion device is not associated with the user or the calling app.

requestNotificationAccess

Added in API level 26
public void requestNotificationAccess (ComponentName component)

Request notification access for the given component. The given component must follow the protocol specified in NotificationListenerService Only components from the same package as the calling app are allowed. Your app must have an association with a device before calling this API. Side-loaded apps must allow restricted settings before requesting notification access.

Calling this API requires a uses-feature PackageManager#FEATURE_COMPANION_DEVICE_SETUP declaration in the manifest

Parameters
component ComponentName

startObservingDevicePresence

Added in API level 31
public void startObservingDevicePresence (String deviceAddress)

Register to receive callbacks whenever the associated device comes in and out of range.

The provided device must be associated with the calling app before calling this method.

Caller must implement a single CompanionDeviceService which will be bound to and receive callbacks to CompanionDeviceService#onDeviceAppeared and CompanionDeviceService#onDeviceDisappeared. The app doesn't need to remain running in order to receive its callbacks.

Calling app must declare uses-permission Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE.

Calling app must check for feature presence of PackageManager#FEATURE_COMPANION_DEVICE_SETUP before calling this API.

For Bluetooth LE devices, this is based on scanning for device with the given address. The system will scan for the device when Bluetooth is ON or Bluetooth scanning is ON.

For Bluetooth classic devices this is triggered when the device connects/disconnects. WiFi devices are not supported.

If a Bluetooth LE device wants to use a rotating mac address, it is recommended to use Resolvable Private Address, and ensure the device is bonded to the phone so that android OS is able to resolve the address.


Requires Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE

Parameters
deviceAddress String: a previously-associated companion device's address This value cannot be null.

Throws
DeviceNotAssociatedException if the given device was not previously associated with this app.

startSystemDataTransfer

Added in API level 34
public void startSystemDataTransfer (int associationId, 
                Executor executor, 
                OutcomeReceiver<VoidCompanionException> result)

Start system data transfer which has been previously approved by the user.

Before calling this method, the app needs to make sure the transport channel is attached, and the user consent dialog has prompted to the user. The transfer will fail if the transport channel is disconnected or detached during the transfer.

Parameters
associationId int: The unique ID assigned to the Association of the companion device recorded by CompanionDeviceManager

executor Executor: The executor which will be used to invoke the result callback. This value cannot be null.

result OutcomeReceiver: The callback to notify the app of the result of the system data transfer. This value cannot be null.

Throws
DeviceNotAssociatedException Exception if the companion device is not associated

stopObservingDevicePresence

Added in API level 31
public void stopObservingDevicePresence (String deviceAddress)

Unregister for receiving callbacks whenever the associated device comes in and out of range. The provided device must be associated with the calling app before calling this method. Calling app must declare uses-permission Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE. Calling app must check for feature presence of PackageManager#FEATURE_COMPANION_DEVICE_SETUP before calling this API.
Requires Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE

Parameters
deviceAddress String: a previously-associated companion device's address This value cannot be null.

Throws
DeviceNotAssociatedException if the given device was not previously associated with this app.