我试图建立一个应用程序与webview,有简单的文件选择器html元素:
<input type="file" accept="image/*" capture="camera" onchange="readURL(this);"/>
为了让它工作,我构建了下面的代码,它工作得很好,打开选择器意图,允许我选择相机或文件资源管理器来选择一个准备好的图片。
我现在有一个问题,如何处理返回的结果,因为startActivityForResult(takePictureIntent, CAPTURE_IMAGE_REQUEST)
是不赞成的。
我喜欢我的代码是小块文件,所以我写了最后2个文件来处理结果CamResult
和SelectorResult
,但得到了错误:
试图在当前状态恢复时注册
我读了这个,但不知道如何在我的情况下实现它!
MainActivity.kt:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Global.context = baseContext
Global.activity = this
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
Global.webView = binding.webView
WebListener.initiate()
WebSettings.setUp()
}
}
WebListener。Kt
interface WebListener {
companion object {
fun initiate() {
Global.webView.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
view.loadUrl("javascript:alert('Welcome to native app')")
}
}
Global.webView.webChromeClient = object : WebChromeClient() {
override fun onShowFileChooser(
webView: WebView,
filePathCallback: ValueCallback<Array<Uri>>,
fileChooserParams: FileChooserParams
): Boolean {
Util.displayMessage("selected")
if (ContextCompat.checkSelfPermission(
Global.context,
Manifest.permission.CAMERA
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
Global.activity,
arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE),
0
)
}
FileChooser.create()
filePathCallback.onReceiveValue(null)
return true
}
}
}
}
}
FileChooser.kt
interface FileChooser {
companion object {
fun create() {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
takePictureIntent.resolveActivity(Global.activity.packageManager)?.also {
// Create the File where the photo should go
try {
// photoFile = createImageFile()
Global.photoURI = ImageUri.create() //createImageUri()
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Global.photoURI)
} catch (ex: Exception) {
// Error occurred while creating the File
Util.displayMessage(ex.message.toString())
}
}
val intentArray: Array<Intent?> = arrayOf(takePictureIntent)
val contentSelectionIntent = Intent(Intent.ACTION_GET_CONTENT)
contentSelectionIntent.let{
it.addCategory(Intent.CATEGORY_OPENABLE)
it.type = "image/*"
}
val chooserIntent = Intent(Intent.ACTION_CHOOSER)
chooserIntent.let {
it.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent)
it.putExtra(Intent.EXTRA_TITLE, "Image Chooser")
it.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray)
Global.activity.startActivity(it)
}
}
}
}
CamResult.kt
interface CamResult {
companion object {
val pickResult = Global.activity.registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
Global.webView.loadUrl("javascript:showResponse()")
}
}
}
SelectorResult.kt
interface SelectorResult {
companion object {
val pickResult = Global.activity.registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
Global.webView.loadUrl("javascript:showResponse()")
}
}
}
我解决了这个问题,通过在主活动中注册响应,为:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Global.context = baseContext
Global.activity = this
CameraResults.register()
}
}
,定义为:
interface CameraResults {
companion object {
fun register() {
Global.CameraResult = Global.activity.registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result: ActivityResult ->
if (result.resultCode == RESULT_OK) {
result.data?.let {
val f = GetFileFromUrl.getFileFromUri(it.data!!)
Global.activity.contentResolver.query(it.data!!, null, null, null, null)
?.use { cursor ->
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
cursor.moveToFirst()
// val n = cursor.getString(nameIndex)
// val s = cursor.getLong(sizeIndex).toString()
// Util.displayMessage("$n / $s")
}
when (it.extras) {}
}
Global.webView.loadUrl("javascript:showResponse()")
} else {
// Util.displayMessage("Sorry no image camputred")
}
}
}
}
}
我的完整代码在这里,如果有兴趣看看。