use the accessory sdk in android 1 declaring the android permission to use the accessory sdk, you must declare the following permission the following permission has to be specified in the androidmanifest xml file to use the samsung accessory service <uses-permission android name= "com samsung accessory permission accessory_framework" /> 2 declaring the broadcast receiver if the broadcast receiver is not added in the androidmanifest xml file, no intents handled by the samsung accessory service framework are delivered to your application <application> <receiver android name="com samsung android sdk accessory registeruponinstallreceiver"> <intent-filter> <action android name="com samsung accessory action register_agent" /> </intent-filter> </receiver> <receiver android name="com samsung android sdk accessory serviceconnectionindicationbroadcastreceiver"> <intent-filter> <action android name="com samsung accessory action service_connection_requested" /> </intent-filter> </receiver> </application> note the action names are changed from 2 3 0 for backward compatibility, old actions are not supported anymore in latest sdk communicating with the remote peer agent needs the declaration of a service in the androidmanifest xml saservice can handle receiving request of service connections when the tested devices are o os or above, saservice should be running in foreground because of the background limitation this ensures that the application is derived from the saagentv2 class <application> <service android name="com samsung android sdk accessory saservice" /> </application> note saagentv2 is a new version of saagent to support android o os or above without running in foreground it has same functionalities as saagent but code generation has few differences from saagent the saagentv2 class does not extend the android service saservice can be executed in a worker thread and make saagentv2 to handle asynchronous accessory-related intents for devices having o os or above, please add foreground permission to manifest and make sure your application has an icon which will be used by notification for foreground service 3 defining the accessory service profile communicating with a remote peer agent requires the declaration of descriptions about the accessory service profile this is declared in a separate file in the /res/xml folder in your application project the path of the actual xml file can be added in the application’s androidmanifest xml file for example, /res/xml/ xml <application> <meta-data android name="accessoryserviceslocation" android value="/res/xml/accessoryservices xml" /> </application> an example of the accessory service profile xml file <?xml version="1 0" encoding="utf-8"?> <resources> <application name="myapplication"> <serviceprofile id="/org/example/myapp/my_message" name="myapplication" role="provider" serviceimpl="com example myapplication providerservice" version="1 0" servicelimit="any" servicetimeout="10"> <supportedtransports> <transport type="transport_bt" /> <transport type="transport_wifi" /> </supportedtransports> <servicechannel id="110" datarate="low" priority="low" reliability= "enable"/> </serviceprofile> </application> </resources> when the application is installed, the samsung accessory service framework automatically registers its accessory peer agents using the information specified in your service profile xml file similarly, the accessory peer agents are deregistered when the application is uninstalled an error log is dumped if the registration process fails to register the accessory service profile implementation to define the accessory service profile, see a 1 validating accessory service profile xml in this 4 finding accessory peer agents the service provider or service consumer application can search for matching accessory peer agents by calling the saagentv2 findpeeragents method matching accessory peer agents have the same accessory service profile such as notification service or weather service , and have a complementary provider or consumer relationship with the calling accessory peer agent accessory peer agents with different accessory service profiles for service providers or service consumers do not “match” and cannot be connected with each other if 2 accessory peer agents have the same accessory service profile with different versions, however, they are still considered to “match” for example, a notification service consumer that implements the notification service profile version 2 0 and a notification service provider that implements the notification service profile version 1 0 “match” the application searches for matching peer agents by calling the saagentv2 findpeeragents method if a matching peer agent is found, the application is notified though the saagentv2 onfindpeeragentresponse method if a matching peer agent is not found, the same callback is used, but the result has a null peer agent and the reason why no match was found @override protected void onfindpeeragentresponse sapeeragent peeragent, int result { if result == peer_agent_found { /* peer agent is found */ } else if result == findpeer_device_not_connected { /* peer agents are not found, no accessory device connected */ } else if result == findpeer_service_not_found { /* no matching service on connected accessory */ } } 5 setting up the service connection if the application wants to establish a service connection with only one accessory peer agent, check the first callback you can also check the identity or properties of the discovered accessory peer agents by calling the methods provided by the sapeeragent class to decide which accessory peer agent you want to form a service connection with the application can initiate a service connection with an accessory peer agent by calling the saagentv2 requestserviceconnection method this method is called from a worker thread if you need to do any heavy lifting or long latency work in the callback, spawn a separate thread if a service provider connects only with a specific service consumer, or a service consumer with a specific service provider, the service provider and consumer are called ”companion applications” when you only want to connect to a companion service provider or service consumer, call the methods provided by the sapeeragent class for specific information, such as model number or vendor information, before calling the saagentv2 requestserviceconnection method for example, when a photo printer service provider on an accessory device from a company only wants to connect to a photo printer service consumer on a smart device from the same company, they are companion applications the remote accessory peer agent either accepts or rejects your service connection request your application is notified with the saagentv2 onserviceconnectionresponse callback the request can be accepted and a service connection established or rejected, or it can fail to establish the service connection for other reasons when a service connection is successfully established, the requesting accessory peer agent gets an instance of the sasocket object, which is used to handle service connection events and send or receive data to and from accessory peer agents private providerserviceconnection mconnectionhandler = null; @override protected void onserviceconnectionresponse sapeeragent peeragent, sasocket socket, int result { if result == saagentv2 connection_success { if socket != null { mconnectionhandler = providerserviceconnection socket; log d tag, "gear connection is successful " ; } } else if result == saagentv2 connection_already_exist { log e tag, "gear connection is already exist " ; } } public class providerserviceconnection extends sasocket { } 6 handling the setup service connection request the service provider or consumer application is notified with the saagentv2 onserviceconnectionrequested callback when a remote accessory peer agent wants to create a service connection with it the accessory peer agent implementation can accept or reject service connection requests by calling the acceptserviceconnectionrequest or rejectserviceconnectionrequest method the default implementation of the saagentv2 onserviceconnectionrequested callback is to accept every incoming service connection request from any remote accessory peer agent your accessory peer agent implementation can override this method, usually to check the identity and properties of the requesting remote accessory peer agent before accepting or rejecting incoming service connection requests the saagentv2 onserviceconnectionrequested callback can check for accessory peer agent-specific information before accepting service connection requests you can use the sapeeragent object methods for checking specific information, such as application name or vendor id if your application accepts the service connection request, your application is notified through the saagentv2 onserviceconnectionresponse callback when the service connection is established or a failure occurs on success, an sasocket object is passed with the callback if you want to implement a service provider application that can serve multiple service consumer applications at the same time, keep a repository of the sasocket objects for all active service connections, and give an identifier for each sasocket object the saagentv2 onserviceconnectionresponse callback is called from a worker thread if you need to do any heavy lifting or long latency work in the callback, spawn a separate thread @override protected void onserviceconnectionrequested sapeeragent peeragent { if peeragent != null { acceptserviceconnectionrequest peeragent ; } } @override protected void onserviceconnectionresponse sapeeragent peeragent, sasocket socket, int result { if result == saagentv2 connection_success { if socket != null { mconnectionhandler = providerserviceconnection socket; log d tag, "gear connection is successful " ; } } else if result == saagentv2 connection_already_exist { log e tag, "gear connection is already exist " ; } } 7 exchanging data with the accessory peer agent call the sasocket send method of the sasocket object passed with the saagentv2 onserviceconnectionresponse callback to send data on the selected service channel inside an established service connection the samsung accessory service framework provides a datagram service either all the data is sent or nothing is sent the service connection encapsulates all service channels as defined by the accessory service profile specification do not send a byte array bigger than that defined by the sapeeragent getmaxalloweddatasize method, which returns the size limit that you can send to the remote accessory peer agent the limit is a variable that depends on the transport type and memory size of the remote accessory device public void sendmessage final string message { if mconnectionhandler != null { new thread new runnable { public void run { try { mconnectionhandler send channel_id, message getbytes ; } catch ioexception e { e printstacktrace ; } } } start ; } } if you want your data encrypted, call the sasocket securesend method instead of send note the sasocket send and sasocket securesend methods are called from a worker thread if you need to do any heavy lifting or long latency work in the callback, spawn a separate thread do not invoke these methods in the main thread of the application when your application receives data from a remote accessory peer agent, it is notified with the sasocket onreceive callback implement the sasocket onreceive method to handle the data public class providerserviceconnection extends sasocket { @override public void onreceive int channelid, byte[ ] data { if mconnectionhandler == null { return; } final string message = new string data ; if mproviderservicelistener != null && !mproviderservicelistener isactivityhidden { mproviderservicelistener onreceivemessage message ; } else { mhandler post new runnable { @override public void run { toast maketext getbasecontext , message, toast length_short show ; try { mconnectionhandler send channel_id, "android app is sleeping" getbytes ; } catch ioexception e { e printstacktrace ; } } } ; } } }