Hybrid Integration
Check the following to integrate Saucelive Web
and Mobile
.
Implementing In-App Bridge Communication
In hybrid apps or web-based apps with native modules, a "bridge" refers to the communication layer between web content and native code.
By using this bridge, web-based code can access and control native device features such as the camera, GPS, or file system. This enables developers to reuse web code across platforms while delivering native-like performance and user experience.
Android Bridge Setup
Project Setup
STEP 1. Create a new project using Android Studio.
STEP 2. Add the following permissions to AndroidManifest.xml
for bridge functionality:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
STEP 3. Add a WebView
in activity_main.xml
:
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Creating the Web Page
Create an index.html
file in theassets
folder of the project:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Bridge Example</title>
</head>
<body>
<button onclick="sendMessageToAndroid()">Send Message to Android</button>
<script>
function sendMessageToAndroid() {
AndroidBridge.showMessage("Hello from Web!");
}
</script>
</body>
</html>
WebView Configuration
In MainActivity.java
or MainActivity.kt
, configure the WebView
:
class MainActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
// Enable JavaScript
webView.getSettings().setJavaScriptEnabled(true);
//Add JavaScript interface
webView.addJavascriptInterface(new WebAppInterface(this), "sauceflex");
// Load HTML file from assets
webView.loadUrl("file:///android_asset/index.html");
}
public class WebAppInterface {
Context mContext;
WebAppInterface(Context c) {
mContext = c;
}
@JavascriptInterface
public void showMessage(String message) {
// Handle the message here
}
}
}
MainActivity : AppCompatActivity() {
private lateinit var webView: WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
webView = findViewById(R.id.webview)
// Enable JavaScript
webView.settings.javaScriptEnabled = true
// Add JavaScript interface
webView.addJavascriptInterface(WebAppInterface(this), "sauceflex")
// Load HTML file from assets
webView.loadUrl("file:///android_asset/index.html")
}
class WebAppInterface(private val mContext: Context) {
@JavascriptInterface
fun showMessage(message: String) {
// Handle the message here
}
}
}
Sending Messages from Web to Android
Clicking the button in the web page will call the Android showMessage()
method via the sendMessageToAndroid()
JavaScript function.
Sending Messages from Android to Web
To call a JavaScript function in the web page from Android, use evaluateJavascript()
:
webView.evaluateJavascript("alert('Hello from Android!');", null)
// Show PIP button (enable)
myWebView?.evaluateJavascript(
"(function() { window.dispatchEvent(sauceflexPictureInPictureUse(true)); })();"
) { }
// Hide PIP button (disable)
myWebView?.evaluateJavascript(
"(function() { window.dispatchEvent(sauceflexPictureInPictureUse(false)); })();"
) { }
Flutter Bridge Setup
This section explains how to use the webview_flutter
package to enable communication between a Flutter app and web content.
Add Required Package
Add the webview_flutter
package to your pubspec.yaml
file:
dependencies:
flutter:
sdk: flutter
webview_flutter: ^3.0.0
Configure the WebView Widget
Use the WebView widget in Flutter to load a web page and establish communication with JavaScript.
// code example
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebViewExample extends StatefulWidget {
@override
_WebViewExampleState createState() => _WebViewExampleState();
}
class _WebViewExampleState extends State<WebViewExample> {
final _controller = Completer<WebViewController>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('WebView Example'),
),
body: WebView(
initialUrl: 'https://yourwebsite.com',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
javascriptChannels: <JavascriptChannel>{
_createJavascriptChannel(),
},
),
);
}
JavascriptChannel _createJavascriptChannel() {
return JavascriptChannel(
name: 'FlutterBridge',
onMessageReceived: (JavascriptMessage message) {
print('Message received from web: ${message.message}');
});
}
}
Sending Messages from Web Page to Flutter
This section explains the basic method of communication between Flutter and web content.
// code example
function sendMessageToFlutter(message) {
if (window.FlutterBridge) {
window.FlutterBridge.postMessage(message);
}
}
Player Bridge Integration Guide (Web → App Communication)
After implementing the base guide, add platform-specific code as needed.
Add Player Bridge
Android
...
webView.addJavascriptInterface(new WebAppInterface(this), "sauceflex");
...
...
webView.addJavascriptInterface(WebAppInterface(this), "sauceflex")
...
Implement a Functional Bridge for Web-App Communication
Android
public class AndroidBridge {
private final Context context;
private final Handler handler = new Handler();
public AndroidBridge(Context context) {
this.context = context;
}
// Callback when entering the broadcast - automatically triggered upon page load
@JavascriptInterface
public void sauceflexEnter() {
handler.post(new Runnable() {
@Override
public void run() {
// Add handling code here
}
});
}
// Callback when the broadcast status changes - triggered automatically on state change
@JavascriptInterface
public void sauceflexBroadcastStatus(String message) {
final String finalMessage = message;
handler.post(new Runnable() {
@Override
public void run() {
// Add handling code here
}
});
}
//Callback when exiting
@JavascriptInterface
public void sauceflexMoveExit() {
handler.post(new Runnable() {
@Override
public void run() {
// Add handling code here
}
});
}
// Callback when logging in
@JavascriptInterface
public void sauceflexMoveLogin() {
handler.post(new Runnable() {
@Override
public void run() {
// Add handling code here
}
});
}
// Callback when a product is clicked
@JavascriptInterface
public void sauceflexMoveProduct(String message) {
final String finalMessage = message;
handler.post(new Runnable() {
@Override
public void run() {
// Add handling code here
}
});
}
//Callback when a banner is clicked
@JavascriptInterface
public void sauceflexMoveBanner(String message) {
final String finalMessage = message;
handler.post(new Runnable() {
@Override
public void run() {
// Add handling code here
}
});
}
// Callback when a coupon is clicked
@JavascriptInterface
public void sauceflexMoveCoupon(String message) {
final String finalMessage = message;
handler.post(new Runnable() {
@Override
public void run() {
// Add handling code here
}
});
}
// Callback when a reward is completed
@JavascriptInterface
public void sauceflexMoveReward(String message) {
final String finalMessage = message;
handler.post(new Runnable() {
@Override
public void run() {
// Add handling code here
}
});
}
// Callback when the share button is clicked
@JavascriptInterface
public void sauceflexOnShare(String message) {
final String finalMessage = message;
handler.post(new Runnable() {
@Override
public void run() {
// Add handling code here
}
});
}
// Callback when the PIP toggle button is clicked
//(UI elements above the player will be automatically hidden in PIP mode)
@JavascriptInterface
public void sauceflexPictureInPicture() {
handler.post(new Runnable() {
@Override
public void run() {
// Add handling code here
}
});
}
// Callback for WebView reloading
@JavascriptInterface
public void sauceflexWebviewReloading() {
handler.post(new Runnable() {
@Override
public void run() {
// Add handling code here
}
});
}
}
class AndroidBridge(private val context: Context) {
private val handler = Handler()
// Callback when entering the broadcast - automatically triggered when the page loads
@JavascriptInterface
fun sauceflexBroadcastStatus() {
handler.post {
// Add handling code here
}
}
// Callback when broadcast status changes - triggered automatically on status updates
@JavascriptInterface
fun sauceflexBroadcastStatus(message: String) {
handler.post {
// Add handling code here
}
}
// Callback when exiting
@JavascriptInterface
fun sauceflexMoveExit() {
handler.post {
// Add handling code here
}
}
// Callback when login is triggered
@JavascriptInterface
fun sauceflexMoveLogin() {
handler.post {
// Add handling code here
}
}
// Callback when a product is clicked
@JavascriptInterface
fun sauceflexMoveProduct(message: String) {
handler.post {
// Add handling code here
}
}
// Callback when a banner is clicked
@JavascriptInterface
fun sauceflexMoveBanner(message: String) {
handler.post {
// Add handling code here
}
}
// Callback when a coupon is clicked
@JavascriptInterface
fun sauceflexMoveCoupon(message: String) {
handler.post {
// Add handling code here
}
}
// Callback when a reward is completed
@JavascriptInterface
fun sauceflexMoveReward(message: String) {
handler.post {
// Add handling code here
}
}
// Callback when the share button is clicked
@JavascriptInterface
fun sauceflexOnShare(message: String) {
handler.post {
// Add handling code here
}
}
// Callback when the PIP toggle button is clicked
//(Elements above the player will be hidden automatically in PIP mode)
@JavascriptInterface
fun sauceflexPictureInPicture () {
handler.post {
// Add handling code here
}
}
// Callback when the WebView is reloaded
@JavascriptInterface
fun sauceflexWebviewReloading() {
handler.post {
// Add handling code here
}
}
}
Player Bridge Integration Example (Share)
Android
public class AndroidBridge {
private Context context;
private Handler handler;
// Constructor to initialize the context and handler
public AndroidBridge(Context context) {
this.context = context;
this.handler = new Handler();
}
...
// sharing
@JavascriptInterface
public void sauceflexOnShare(String message) {
final String finalMessage = message;
handler.post(new Runnable() {
@Override
public void run() {
try {
// message format - Json String
JSONObject jsonObject = new JSONObject(message);
String shareURL = jsonObject.getString("linkUrl");
// If using `shortUrl`, you can replace it with the code below.
// String shareURL = jsonObject.getString("shortUrl");
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, shareURL);
context.startActivity(Intent.createChooser(intent, "Share via"));
} catch (Exception e) {
e.printStackTrace();
// Error Handling
}
}
});
}
...
}
class AndroidBridge(private val context: Context) {
private val handler = Handler()
...
@JavascriptInterface // sharing
fun sauceflexOnShare(message: String) {
handler.post {
try {
// message format - Json String
val jsonObject = JSONObject(message)
val shareURL = jsonObject.getString("linkUrl")
// If using `shortUrl`, you can replace it with the code below.
// val shareURL = jsonObject.getString("shortUrl")
val intent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, shareURL)
}
context.startActivity(Intent.createChooser(intent, "Share via"))
} catch (e: Exception) {
e.printStackTrace()
// Error Handling
}
}
}
...
}
Updated 13 days ago