Library for integrating Queue-it's virtual waiting room into an Android app written in java.
A sample app to try out functionality in the library can be found on the Releases page. This sample app uses the first approach of integration calling QueueITEngine run method.
Before starting please download the whitepaper "Mobile App Integration" from GO Queue-it Platform. This whitepaper contains the needed information to perform a successful integration.
Using Gradle:
implementation 'com.queue-it.androidsdk:webui:3.0.0'Artifact renamed in 3.0.0. The SDK is now published as
com.queue-it.androidsdk:webui. The previous artifact idscom.queue-it.androidsdk:libraryandcom.queue-it.androidsdk:library-androidxare discontinued and relocate to:webui— update your dependency to the coordinate above.
As the App developer, you must manage the state (whether the user was previously queued up or not) inside the app's storage.
After you have received the onQueuePassed callback, the app must remember to keep the state, possibly with a date/time expiration.
When the user wants to navigate to specific screens on the app which needs Queue-it protection, your code check this state/variable, and only call SDK methods / QueueITEngine.run in the case where the user did not previously queue up.
Please note that when the user clicks back to navigate back to a protected screen, the same check needs to be done.
The simplest mobile SDK integration requires you to call one method, run() before showing the protected screen and potentially calling server API which needs peak traffic protection.
Invoke QueueITEngine as per example below. Parameters layoutName, language, waitingRoomDomain, queuePathPrefix and options are optional. Use null to let the SDK make the decision for those parameters (see below parameter table).
QueueListenerqueueListener = newQueueListener() {
// This callback will be called when the user has been through the queue.// Here you should store session information, so user will only be sent to queue again if the session has timed out.@OverridepublicvoidonQueuePassed(QueuePassedInfoqueuePassedInfo) {
}
// This callback will be called just before the webview (hosting the queue page) will be shown.// Here you can change some relevant UI elements.@OverridepublicvoidonQueueViewWillOpen() {
}
// This callback will be called when the queue used (event alias ID) is in the 'disabled' state.// Most likely the application should still function, but the queue's 'disabled' state can be changed at any time,// so session handling is important.@OverridepublicvoidonQueueDisabled(QueueDisabledInfoqueueDisabledInfo) {
}
// This callback will be called when the mobile application can't reach Queue-it's servers.// Most likely because the mobile device has no internet connection.// Here you decide if the application should function or not now that is has no queue-it protection.@OverridepublicvoidonQueueItUnavailable() {
}
// This callback will be called when the mobile application can't reach Queue-it's servers.// It can be any one of these scenarios:// 1) Queue-it's servers can't be reached (connectivity issue).// 2) SSL connection error if custom queue domain is used having an invalid certificate.// 3) Client receives HTTP 4xx response.// In all these cases is most likely a misconfiguration of the queue settings:// Invalid customer ID, event alias ID or cname setting on queue (GO Queue-it portal -> event settings).@OverridepublicvoidonError(Errorerror, StringerrorMessage) {
} // Called on connectivity problems// This callback will be called after a user clicks a close link in the layout and the WebView closes.// The close link is "queueit://close". Whenever the user navigates to this link, the SDK intercepts the navigation// and closes the WebView.@OverridepublicvoidonWebViewClosed(){
}
// This callback will be called when the user clicks on a link to restart the session.// The link is 'queueit://restartSession'. Whenever the user navigates to this link, the SDK intercepts the navigation,// closes the WebView, clears the URL cache and calls this callback.// In this callback you would normally call run/runWithToken/runWithKey in order to restart the queueing.@OverridepublicvoidonSessionRestart(QueueITEnginequeueITEngine) {
}
};
QueueITEngineengine = newQueueITEngine(
YourActivity.this,
customerId,
eventIdOrAlias,
layoutName, // @Nullable (optional)language, // @Nullable (optional)waitingRoomDomain, // @Nullable (optional)queuePathPrefix, // @Nullable (optional)queueListener,
options// @Nullable (optional)
);
try {
engine.run(YourActivity.this);
}
catch (QueueITExceptione) { } // Gets thrown when a request is already in progress. In general you can ignore this.Note all the parameters must be passed to the
QueueITEngineconstructor.runis an instance function.
| Parameter | Required (Default value) | Description |
|---|---|---|
| activityContext | Yes | Your Context |
| customerId | Yes | Your customer id |
| eventIdOrAlias | Yes | Id of the waiting room or alias |
| layoutName | No (Waiting Room's default theme) | Layout name to use for the waiting room. If omitted, the Waiting Room's default layout will be used |
| language | No (Waiting Room's default language) | Language id to use for the waiting room. If omitted, the Waiting Room's default language will be used |
| waitingRoomDomain | No ({customerId}.queue-it.net) | Custom Waiting Room domain to use for the requests from Mobile to Queue-it. Can be a Proxy Domain, if you are running Queue-it Behind Proxy |
| queuePathPrefix | No (none) | Queue Path Prefix to use, if you are running Waiting Room on same domain as your normal website. Requires waitingRoomDomain to also be provided. If not, then this parameter will be ignored. |
| queueListener | Yes | Listener with callback functions. Must implement the QueueListener interface. |
| options | No (QueueItEngineOptions.getDefault()) | Allows you to configure the SDK. Can disable back button (default: disabled) and set a custom User Agent (default: "") for the web view and the http client. |
While a user is in the waiting room, Android may kill your app's process if it is backgrounded and the device is low on memory (common on low-RAM devices and aggressive OEM battery managers). If the user is passed through the queue around that time, the pass would otherwise be lost — the in-memory QueueListener no longer exists, so the user returns to your app but is never let in and has to restart the app.
To handle this, the SDK persists the pass to disk (best-effort) the moment it completes. Call QueueITEngine.consumePendingPass(context, queueListener) from your launching Activity's onResume() (or onCreate()):
@OverrideprotectedvoidonResume() {
super.onResume();
// Deliver a queue pass that completed while our process was killed in the background.QueueITEngine.consumePendingPass(this, queueListener);
}If a pass completed while your process was gone, it is delivered to your listener's onQueuePassed(...); otherwise it does nothing. It is safe to call on every resume: the stored token is read-and-cleared atomically, so a pass is delivered at most once and will not double-fire with the live delivery path. Returns true if a pending pass was delivered, false otherwise.
Note: the token is cleared before your
onQueuePassed(...)runs, so if your handler throws, the pass is not redelivered on a later resume — keep the handler robust. Persistence is best-effort (a failed disk write is not retried), so treat this recovery as a safety net on top of your own session handling, not a guaranteed transaction.
The QueueITEngine can be configured if you use the options argument in it's constructor. Here's an example.
QueueItEngineOptionsoptions = newQueueItEngineOptions();
// Use this if you want to disable the back button when the waiting room is shownoptions.setBackButtonDisabledFromWR(true);
// Use this if you want to set a custom User Agent. // The user agent will be used by the WebView when the waiting room is shown, and for requests from the mobile app to Queue-it.options.setSdkUserAgent("<user-agent>");
// ------ //// If null is provided for the QueueItEngineOptions, the default options will be used:QueueItEngineOptions.getDefault();If your waiting room is configured as invite-only, visitors need to present an invite code (the code query parameter on the waiting-room URL). Pass that code to the engine before calling run() (or tryPass()), and the SDK will append it to the queue URL it loads:
engine.setInviteCode("<your-invite-code>");
engine.run(YourActivity.this);setInviteCode accepts a String; passing null or an empty string clears any previously-set code.
Capturing the code from the link your user opened (App Link, custom URL scheme, push payload, manually pasted text, etc.) is the app's responsibility — the SDK only consumes the resulting string. A minimal example pulling code from the launching Intent:
@OverrideprotectedvoidonCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
// ...applyInviteCode(getIntent());
}
@OverrideprotectedvoidonNewIntent(Intentintent) {
super.onNewIntent(intent);
setIntent(intent);
applyInviteCode(intent);
}
privatevoidapplyInviteCode(Intentintent) {
if (intent == null) return;
Uridata = intent.getData();
if (data == null) return;
Stringcode = data.getQueryParameter("code");
if (!TextUtils.isEmpty(code)) {
engine.setInviteCode(code);
}
}You also need an <intent-filter> in your AndroidManifest.xml matching the URL pattern you want to handle. See the demoapp/ module for a working example.
If you need finer granularity control over the mobile integration, you can use tryPass and showQueue instead of just using run method (which will open a webview to the Queue when needed).
tryPass allows you to check the state of the Waiting Room. Later you can show the waiting room using the showQueue function. QueueITEngine.run does the same, but with the granular setup, you can decide in which layer of your app, each step happens.
This provides you more control of the logic before potentially opening the webview and showing the Queue page, as well as more control over the webview showing the queue page.
It is possible to get the status of a waiting room to make sure it is ready to be visited. To do this, one of the below methods from QueueITWaitingRoomProvider class could be used.
- tryPass
- tryPassWithEnqueueToken
- tryPassWithEnqueueKey
Calling any of these methods will result in executing onSuccess or onFailure callbacks. These two callbacks must be provided by implementing QueueITWaitingRoomProviderListener interface and passed to the constructor of QueueITWaitingRoomProvider class, and will lead to below:
- If
isPassedThrough()returns true, queueittoken and more information will be available as an argument toOnSuccessfunction with type ofQueueTryPassResult. - If
isPassedThrough()returns false, it means that the waiting room is active. The waiting room page should be shown to the visitor by callingshowQueuemethod of theQueueITWaitingRoomView, then the visitor will wait for its turn. TheshowQueuemethod needsQueryTryPassResultobject fromOnSuccessfunction.
Note the parameters are constructor parameters. The three
tryPassvariants has different parameters (none,enqueueTokenandenqueueKey).
| Parameter | Required (Default value) | Description |
|---|---|---|
| activityContext | Yes | Your Context |
| customerId | Yes | Your customer id |
| eventIdOrAlias | Yes | Id of the waiting room or alias |
| layoutName | No (Waiting Room's default theme) | Layout name to use for the waiting room. If omitted, the Waiting Room's default layout will be used |
| language | No (Waiting Room's default language) | Language id to use for the waiting room. If omitted, the Waiting Room's default language will be used |
| waitingRoomDomain | No ({customerId}.queue-it.net) | Custom Waiting Room domain to use for the requests from Mobile to Queue-it. Can be a Proxy Domain, if you are running Queue-it Behind Proxy |
| queuePathPrefix | No (none) | Queue Path Prefix to use, if you are running Waiting Room on same domain as your normal website. Requires waitingRoomDomain to also be provided. If not, then this parameter will be ignored. |
| userAgent | No (User agent of the Mobile's default webview) | Custom User Agent to use for requests from Mobile to Queue-it. |
| queueITWaitingRoomProviderListener | Yes | Listener with callback functions. Must implement the QueueITWaitingRoomProviderListener interface. |
When waiting room is queueing the visitors, each visitor has to visit the waiting room page once. The queue page could be shown to visitors when it is necessary using showQueue method of QueueITWaitingRoomView class.
Before calling showQueue, the status of the waiting room should be already retrieved as described in Get waiting room status to make sure that the waiting room is ready.
sample code for showing the queue page:
QueueITWaitingRoomViewqueueITWaitingRoomView = newQueueITWaitingRoomView(MainActivity.this, queueListener, queueItEngineOptions);
queueITWaitingRoomView.showQueue(_queueTryPassResult, queueItEngineOptions.getSdkUserAgent());If you are using Behind Your Own CDN feature you must pass your waitingRoomDomain and queuePathPrefix:
QueueITWaitingRoomViewqueueITWaitingRoomView = newQueueITWaitingRoomView(MainActivity.this, queueListener, queueItEngineOptions, waitingRoomDomain, queuePathPrefix);
queueITWaitingRoomView.showQueue(_queueTryPassResult, queueItEngineOptions.getSdkUserAgent());Note: This only applies if you are using the Mobile SDK as a client-side protection only. I.e. this does not apply if you are protecting the API endpoints your Mobile app is using.
If you have server-side Queue-it protection on your API endpoints, please see section below.
If you are running Queue-it behind your own reverse proxy the Mobile Integration can also be setup to run behind your proxy.
To do this simply use your Proxy Domain as the waitingRoomDomain parameter to QueueITEngine.run. If you are running Queue-it Waiting Room on the same domain as your normal website, you also need to provide the queuePathPrefix parameter, to ensure your proxy can route the request to Queue-it origin.
If your application is using an API that's protected by a Queue-it server-side connector (KnownUser) you can check out this documentation.
<uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permissionandroid:name="android.permission.INTERNET"/><activityandroid:name="com.queue_it.androidsdk.QueueActivity" />