Appearance
Integrating LIQA into Android app
Use this guide when your client application is native Android but should offer the same LIQA smart-camera flow as the web integration. The WebView hosts LIQA, then forwards capture and error events into the Kotlin application.
WebView with LIQA integrated
Here is a ready-to-use implementation of WebView with integrated LIQA functionality. Use it as the technical layer after your product team has decided where the LIQA capture step belongs in the Android journey.
Production recommendation
For simplicity, WebView loads the HTML page from a string containing the page's HTML content.
In a real-world application, you may consider loading the page from a CDN managed by your organization. Check the Hosting the HTML Page section for more details.
IMPORTANT
WebView should be opened over HTTPS. Without HTTPS, the camera access will not be requested, and the camera cannot be used.
When hosting locally, you can open the WebView using https://localhost/ as the baseUrl
kotlin
loadDataWithBaseURL("https://localhost/", HTML, "text/html", "UTF-8", null)kotlin
package ai.haut.liqa
import android.net.Uri
import android.webkit.*
import androidx.activity.ComponentActivity
import androidx.activity.result.contract.ActivityResultContracts
import org.json.JSONObject
const val HTML = """ PUT THE HTML PAGE CONTENT HERE """
fun LiqaWebView(context: ComponentActivity, onLiqaEvent: (name: String, payload: JSONObject?) -> Unit): WebView {
return WebView(context).apply {
webViewClient = WebViewClient()
webChromeClient = object : WebChromeClient() {
// Grant camera permissions to WebView
override fun onPermissionRequest(request: PermissionRequest) {
request.grant(request.resources)
}
// Handle Upload device photo
override fun onShowFileChooser(
webView: WebView?,
filePathCallback: ValueCallback<Array<Uri>>?,
fileChooserParams: FileChooserParams?
): Boolean {
onFilePicked = filePathCallback
filePicker.launch(fileChooserParams?.createIntent())
return true
}
private var onFilePicked: ValueCallback<Array<Uri>>? = null
private val filePicker = context.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
val data = result.data?.data
if (data != null)
onFilePicked?.onReceiveValue(arrayOf(data))
}
}
settings.apply {
javaScriptEnabled = true
mediaPlaybackRequiresUserGesture = false
}
// Communication interface between WebView‘s JavaScript and the Native App
addJavascriptInterface(object {
@JavascriptInterface
fun postMessage(message: String) {
val json = JSONObject(message)
val name = json.getString("name")
val payload = if (json.has("payload")) json.getJSONObject("payload") else null
onLiqaEvent(name, payload)
}
}, "NativeApp")
// `https://` is required to get WebView camera working
loadDataWithBaseURL("https://YOUR.DOMAIN.COM", HTML, "text/html", "UTF-8", null)
}
}Before integrating the snippet into your app, please, ensure that:
- Content of the HTML Page is inlined into the
HTMLstring. WebChromeClient.settings.javaScriptEnabledis set totrue.- WebView loads the page over HTTPS.
Application integration example
Here is an app's entry point, showcasing a sample integration of LiqaWebView:
kotlin
package ai.haut.liqa
import android.Manifest
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.result.contract.ActivityResultContracts
import org.json.JSONObject
import android.widget.Toast
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val webView = LiqaWebView(this) { name, payload ->
handleLiqaEvent(name, payload)
}
// Request camera permission before loading WebView
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
setContentView(webView)
}.launch(Manifest.permission.CAMERA)
}
// The App‘s business logic for handling LIQA events
private fun handleLiqaEvent(name: String, payload: JSONObject?) {
var text = "LIQA: $name"
payload?.let {
var extars = "$payload"
// Do not overwhelm the log
if (extars.length >= 1024) extars = extars.substring(0, 1024) + "..."
text += "\n$extars"
}
log(text)
}
private fun log(text: String) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
}
}Feel free to adapt the example for your application's needs.
Application permissions configuration
Additionally, there is an example of the minimal Android manifest file necessary for LiqaWebView to function correctly:
xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<application android:label="LIQA WebView integration">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>Before running your app with LiqaWebView integrated, please, ensure that:
INTERNETandCAMERAuser permissions are included in theAndroidManifest.xml.
Need Assistance?
If you have any questions regarding the integration or need further assistance, please contact Haut.AI Support Team with this request via the Support Desk.