Skip to content

Commit 7cdd638

Browse files
authored
manager: add file chooser support to WebUI (#1360)
Signed-off-by: KOWX712 <leecc0503@gmail.com>
1 parent ed766af commit 7cdd638

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

app/src/main/java/me/bmax/apatch/ui/WebUIActivity.kt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ package me.bmax.apatch.ui
22

33
import android.annotation.SuppressLint
44
import android.app.ActivityManager
5+
import android.content.ActivityNotFoundException
6+
import android.content.Intent
57
import android.graphics.Color
8+
import android.net.Uri
69
import android.os.Build
710
import android.os.Bundle
811
import android.view.ViewGroup
12+
import android.webkit.ValueCallback
13+
import android.webkit.WebChromeClient
914
import android.webkit.WebResourceRequest
1015
import android.webkit.WebResourceResponse
1116
import android.webkit.WebView
@@ -14,6 +19,8 @@ import android.widget.FrameLayout
1419
import androidx.activity.ComponentActivity
1520
import androidx.activity.compose.setContent
1621
import androidx.activity.enableEdgeToEdge
22+
import androidx.activity.result.ActivityResultLauncher
23+
import androidx.activity.result.contract.ActivityResultContracts
1724
import androidx.compose.foundation.background
1825
import androidx.compose.foundation.layout.Box
1926
import androidx.compose.foundation.layout.fillMaxSize
@@ -45,6 +52,8 @@ class WebUIActivity : ComponentActivity() {
4552
private lateinit var insets: Insets
4653
private var insetsContinuation: CancellableContinuation<Unit>? = null
4754
private var isInsetsEnabled = false
55+
private lateinit var fileChooserLauncher: ActivityResultLauncher<Intent>
56+
private var filePathCallback: ValueCallback<Array<Uri>>? = null
4857

4958
override fun onCreate(savedInstanceState: Bundle?) {
5059

@@ -72,6 +81,27 @@ class WebUIActivity : ComponentActivity() {
7281
}
7382
setupWebView()
7483
}
84+
85+
fileChooserLauncher = registerForActivityResult(
86+
ActivityResultContracts.StartActivityForResult()
87+
) { result ->
88+
val uris: Array<Uri>? = when (result.resultCode) {
89+
RESULT_OK -> result.data?.let { data ->
90+
when {
91+
data.clipData != null -> {
92+
Array(data.clipData!!.itemCount) { i ->
93+
data.clipData!!.getItemAt(i).uri // Multiple files
94+
}
95+
}
96+
data.data != null -> { arrayOf(data.data!!) } // Single file
97+
else -> null
98+
}
99+
}
100+
else -> null
101+
}
102+
filePathCallback?.onReceiveValue(uris)
103+
filePathCallback = null
104+
}
75105
}
76106

77107
private suspend fun setupWebView() {
@@ -172,6 +202,28 @@ class WebUIActivity : ComponentActivity() {
172202
webViewInterface = WebViewInterface(this@WebUIActivity, this)
173203
addJavascriptInterface(webViewInterface, "ksu")
174204
setWebViewClient(webViewClient)
205+
webChromeClient = object : WebChromeClient() {
206+
override fun onShowFileChooser(
207+
webView: WebView?,
208+
filePathCallback: ValueCallback<Array<Uri>>?,
209+
fileChooserParams: FileChooserParams?
210+
): Boolean {
211+
this@WebUIActivity.filePathCallback?.onReceiveValue(null)
212+
this@WebUIActivity.filePathCallback = filePathCallback
213+
val intent = fileChooserParams?.createIntent() ?: Intent(Intent.ACTION_GET_CONTENT).apply { type = "*/*" }
214+
if (fileChooserParams?.mode == FileChooserParams.MODE_OPEN_MULTIPLE) {
215+
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
216+
}
217+
try {
218+
fileChooserLauncher.launch(intent)
219+
} catch (_: ActivityNotFoundException) {
220+
filePathCallback?.onReceiveValue(null)
221+
this@WebUIActivity.filePathCallback = null
222+
return false
223+
}
224+
return true
225+
}
226+
}
175227
loadUrl("https://mui.kernelsu.org/index.html")
176228
}
177229
}

0 commit comments

Comments
 (0)