Integrating FittyAI Virtual Trainer
The Full FittyAI workout integration provides the fastest and most comprehensive solution for incorporating the FittyAI virtual trainer into your application. The features include repetition counting, live voice feedback, time constraints, and motivational encouragement.
Setting-up the project
This tutorial will walk you through the process of integrating a full virtual trainer workout into a JAVA native Android application using a demo app.
Rendering WebView with Fitty Workout
1. Create a WebView Component
Fitty Workout operates as a web application. For Android integration, a WebView
component is recommended. Insert this component into your application activity or fragment and assign it a specific resource ID (for this example, we’ll use fittyCamera
).
2. Request Camera Permission
Depending on your Android version, the application may need explicit permission to access the camera:
// import pub.devrel.easypermissions.EasyPermissions;
EasyPermissions.requestPermissions(
this,
"This application requires camera access.",
CAMERA_REQUEST_CODE,
Manifest.permission.CAMERA);
3. Generate a Session GUID
To uniquely identify a user session, generate a GUID:
String sessionId = java.util.UUID.randomUUID().toString();
4. Acquire JWT for User Authorization
⚠️ Important: Acquiring the JWT must be managed on your backend server. It’s essential because this process involves sending your secret. For security, never store or send secrets from a client device.
Read the instructions to receive your JWT here.
Upon retrieval, the JWT will resemble:
String userToken = "eyJhbGciOiJIUzI1NiIsInR5cCI..."
5. Configure the WebView
Ensure that the WebView
is correctly configured to work seamlessly:
private WebView fittyCamera;
public static WebView configureWebView(WebView webView) {
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setMediaPlaybackRequiresUserGesture(false);
CookieManager.getInstance().setAcceptCookie(true);
CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
webView.setWebViewClient(new WebViewClient());
WebChromeClientCustomPoster chromeClient = new WebChromeClientCustomPoster();
webView.setWebChromeClient(chromeClient);
webView.setWebContentsDebuggingEnabled(true);
return webView;
}
6. Establish a User Session
Connect the WebView to a workout session that will process user joint data:
clientName = "fitty";
environment = "prod";
sessionId = java.util.UUID.randomUUID().toString();
exerciseIndex = 0;
if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
fittyCamera = (WebView) findViewById(R.id.fittyCamera);
fittyCamera.loadUrl(String.format("https://%s.fittyai.com/web/%s/%s/%s?JWT=%s&eventIndex=%d", environment, clientName, workoutID, sessionId, userToken, exerciseIndex));
configureWebView(fittyCamera);
}
Where:
clientName
: Is the unique client name that has been asigned to you during the onboarding procedure.workoutID
: A unique id of the workout you created (can be retrieved using our API or by contacting Fitty support).sessionId
: A unique id for retrieving the session results information.exerciseIndex
: an optional parameter to provide a starting exercise of the workout. By default it will be 0.userToken
: A JWT used to authorize the user to establish a session.
🎉 Great! If you compile and run the application now, the workout should play seamlessly.
Optional: Connecting to WebSocket for Live Events
If you wish to receive live feedback and events during the workout, you can connect to the FittyAI WebSocket server. This will allow you to monitor events like repetition count, feedback, and more, including the “session_end” event.
To achieve this:
- Establish a WebSocket connection:
public void connectWebSocket() {
URI uri;
try {
uri = new URI("wss://backend.fittyai.com:443");
} catch (URISyntaxException e) {
e.printStackTrace();
return;
}
mWebSocketClient = new WebSocketClient(uri) {
@Override
public void onOpen(ServerHandshake serverHandshake) {
Log.i("Websocket", "Opened");
// Construct the session_start payload
JSONObject sessionStart = new JSONObject();
try {
sessionStart.put("session_id", sessionId); //Same sessionGUID as in the WebView
sessionStart.put("timestamp", String.valueOf(System.currentTimeMillis()));
sessionStart.put("company_name", "YOUR_CLIENT_NAME"); // Replace with your clientName
sessionStart.put("event_type", "session_start");
sessionStart.put("jwt", userToken); // Replace with your JWT you generated.
sessionStart.put("receiver", true);
// Send the session_start event
mWebSocketClient.send(sessionStart.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onMessage(String s) {
final String message = s;
runOnUiThread(() -> {
Log.i("Websocket", "received a message: " + message);
});
}
@Override
public void onClose(int i, String s, boolean b) {
Log.i("Websocket", "Closed " + s);
}
@Override
public void onError(Exception e) {
Log.i("Websocket", "Error " + e.getMessage());
}
};
mWebSocketClient.connect();
}
Make sure to call connectWebSocket() at an appropriate place in your code, idealy after WebView URL has been loaded.
// ... THE REST OF THE CODE
if(ContextCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.CAMERA)==PackageManager.PERMISSION_GRANTED) {
fittyCamera = findViewById(R.id.fittyCamera);
fittyCamera.loadUrl(String.format("https://prod.fittyai.com/web/%s/%s/0/%s?JWT=%s", companyName, workoutId, sessionId, userToken));
configureWebView(fittyCamera);
connectWebSocket();
}
Implement handlers within the onMessage method to process incoming WebSocket messages. For example, you can update the UI based on the incoming feedback or events, or wait for session end event to know when to close the iframe.
With this setup, you can now receive live events from the FittyAI trainer, enabling you to provide a richer, more interactive experience to your users.
After you receive session_end event you can then call our API to retrieve all the information about the session: