Third-party Integration¶
Warning
These APIs are deprecated. Use of APIs v1.2 is recommended when using UF Android Client Service ≥ v1.4.
UFAndroidClient has a set of APIs that allow a third party application to interact with it.
To integrate the UFAndroidClient into your application you must:
- Import the module uf-client-service-api (see Module uf-client-service-api section)
- Bind to the UFAndroidClient service (see Bind to UFAndroidClient service section)
The UF Service API Reference Implementation provides an example third party application that is able to:
- show the current service status (Log page);
- open the preferences page of UFAndroidClient (Settings page)
- grant authorization to execute an action during a soft update
Module uf-client-service-api¶
uf-client-service-api contains three classes:
- UFServiceCommunicationConstants: class with the message constants
- UFServiceMessage: a data class which contains the current state of the service
- UFServiceConfiguration: a data class that contains the current configuration of the service
To import this module:
- configure your project to use jitpack (see jitpack documentation).
- add
implementation 'com.github.kynetics:uf-android-client:<version>'
in your gradle dependencies (e.g.implementation 'com.github.kynetics:uf-android-client:v0.4.5'
)
Bind to UFAndroidClient service¶
UFAndroidClient is a bound service, it allows components (such as activities) to bind to the service, send requests, receive responses, and perform interprocess communication.
To bind to the service create an intent with:
- action =
UFServiceCommunicationConstants.SERVICE_ACTION
- package =
UFServiceCommunicationConstants.SERVICE_PACKAGE_NAME
This is an example of how to bind an Application with the service:
private Messenger mService;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
mService = new Messenger(service);
Toast.makeText(MainActivity.this, R.string.connected,
Toast.LENGTH_SHORT).show();
try {
Message msg = Message.obtain(null,
UFServiceCommunicationConstants.MSG_REGISTER_CLIENT);
msg.replyTo = mMessenger;
mService.send(msg);
} catch (RemoteException e) {
Toast.makeText(MainActivity.this, "service communication error",
Toast.LENGTH_SHORT).show();
}
mIsBound = true;
}
...
};
void doBindService() {
final Intent intent = new Intent(UFServiceCommunicationConstants.SERVICE_ACTION);
intent.setPackage(UFServiceCommunicationConstants.SERVICE_PACKAGE_NAME);
intent.setFlags(FLAG_INCLUDE_STOPPED_PACKAGES);
final boolean serviceExist = bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
if(!serviceExist){
Toast.makeText(getApplicationContext(), "UpdateFactoryService not found",Toast.LENGTH_LONG).show();
unbindService(mConnection);
this.finish();
}
}
Messages¶
The UFAndroidClient service uses Android Messenger to receive input and to notify its status. The main characteristic of a message are these fields:
- what the message code, specify the kind of action (mandatory)
- data, the message payload (optional)
- replyTo, messenger where replies to this message can be sent (optional)
For more details see the official documentation.
Messages sent by third party applications¶
Client subscription¶
To subscribe to the service the application has to send a message with the
field what equal to UFServiceCommunicationConstants.MSG_REGISTER_CLIENT
(to receive the response from the service, the field replyTo must also be set)
Client unsubscription¶
To unsubscribe from the service the application has to send a message with the what field
equal to UFServiceCommunicationConstants.MSG_UNREGISTER_CLIENT
Service configuration¶
To configure the service the application has to send a message with:
- what =
UFServiceCommunicationConstants.MSG_CONFIGURE_SERVICE
- data = A bundle object with a serializable object:
- key =
UFServiceCommunicationConstants.SERVICE_DATA_KEY
- value = an instance of UFServiceConfiguration (use the
UFServiceConfiguration.builder()
builder to obtain the instance)
- key =
Example
final Bundle data = new Bundle();
HashMap<String,String> targetAttributes = new HashMap<>(2);
targetAttributes.put("attribute1","attributeValue1");
targetAttributes.put("attribute2","attributeValue2");
final Bundle data = new Bundle();
data.putSerializable(SERVICE_DATA_KEY, UFServiceConfiguration.builder()
.withControllerId("controllerId")
.withTenant("tenant")
.withUrl("https://personal.updatefactory.io")
.withTargetAttributes(targetAttributes)
.build());
Message msg = Message.obtain(null,
UFServiceCommunicationConstants.MSG_CONFIGURE_SERVICE);
msg.replyTo = mMessenger;
msg.setData(data);
Authorization response¶
When the service sends an Authorization request message (e.g. authorization to download or install an OTA update file) the application has to
respond with an Authorization response
that indicates whether the action is allowed or not.
The message response fields are:
- what =
UFServiceCommunicationConstants.MSG_AUTHORIZATION_RESPONSE
- data = a boolean with key
UFServiceCommunicationConstants.SERVICE_DATA_KEY
Example
private void sendPermissionResponse(boolean response){
Message msg = Message.obtain(null, MSG_AUTHORIZATION_RESPONSE);
msg.getData().putBoolean(SERVICE_DATA_KEY, response);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
Resume suspend state¶
After an authorization is denied, it is possible to grant it in a second
moment by sending a message with the field what equal to
UFServiceCommunicationConstants.MSG_RESUME_SUSPEND_UPGRADE
Sync request¶
Sending a message with the what field equal to UFServiceCommunicationConstants.MSG_SYNCH_REQUEST
, the service responds
with two messages:
- the first contains the configuration of the service (see Configuration status section).
- the second contains the last notification message sent by the service (see Current status section).
Messages sent by UFAndroidClient service¶
Authorization request¶
When the service finds a Soft update, it asks to the client for the authorization to download, and then to install the update. These kind of requests are made sending a message with:
- what =
UFServiceCommunicationConstants.MSG_AUTHORIZATION_REQUEST
- data = key
SERVICE_DATA_KEY
; possible values are of type String:DOWNLOAD
when the service is requesting authorization to download OTA update fileUPDATE
when the service is requesting authorization to proceed with installation of OTA update file
Configuration status (response to sync)¶
In response to a sync request the service sends a message that describes its current configuration:
- what =
UFServiceCommunicationConstants.MSG_SERVICE_CONFIGURATION_STATUS
- data = an instance of
UFServiceConfiguration
Example to retrieve UFServiceConfiguration from the message
final Serializable serializable = msg.getData().getSerializable(SERVICE_DATA_KEY);
if(!(serializable instanceof UFServiceConfiguration)) {
UFServiceConfiguration ufServiceConfiguration = (UFServiceConfiguration)serializable;
}
Current status (response to sync)¶
In response to a sync request the service sends a message that describes its current status:
- what =
UFServiceCommunicationConstants.MSG_SERVICE_STATUS
- data = an instance of
UFServiceMessage
Example to retrieve UFServiceConfiguration from the message
final Serializable serializable = msg.getData().getSerializable(SERVICE_DATA_KEY);
if(!(serializable instanceof UFServiceConfiguration)) {
UFServiceMessage messageObj = (UFServiceMessage)serializable;
}