我尝试从Webview打开文件选择器并选择一个文件。但在某些手机中,相机打开后,我的活动被破坏,当用户单击图片并返回时,活动被重新创建。我使用URL保持Webview状态,但回调丢失。
class SampleWebActivity : AppCompatActivity() {
private var mUploadMessage: ValueCallback<Array<Uri>>? = null
private var mCM: String? = null
private val FILE_CHOOSER_REQUEST_CODE = 1111
private var uploadType: Int = TYPE_BOTH
private lateinit var binding: ActivitySampleWebActivity
@SuppressLint("SetJavaScriptEnabled")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySampleWebActivity.inflate(layoutInflater)
setContentView(binding.root)
binding.sampleWebView.settings.javaScriptEnabled = true
binding.sampleWebView.settings.domStorageEnabled = true
binding.sampleWebView.webChromeClient = sampleChromeClient()
binding.sampleWebView.webViewClient = sampleWebViewClient()
loadUrl()
}
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
intent: Intent?
) {
super.onActivityResult(requestCode, resultCode, intent)
var results: Array<Uri>? = null
//Check if response is positive
if (resultCode == Activity.RESULT_OK) {
if (requestCode == FILE_CHOOSER_REQUEST_CODE) {
if (null == mUploadMessage) { //this returns true as callback is null
return
}
if (intent == null) {
//Capture Photo if no image available
if (mCM != null) {
results = arrayOf(Uri.parse(mCM))
}
} else {
val dataString = intent.dataString
if (dataString != null) {
results = arrayOf(Uri.parse(dataString))
}else{
if (mCM != null) {
results = arrayOf(Uri.parse(mCM))
}
}
}
}
}
mUploadMessage?.onReceiveValue(results)
mUploadMessage = null
}
private inner class sampleChromeClient : WebChromeClient() {
@SuppressLint("LogNotTimber")
override fun onShowFileChooser(
mWebView: WebView,
filePathCallback: ValueCallback<Array<Uri>>,
fileChooserParams: FileChooserParams
): Boolean {
if (mUploadMessage != null){
mUploadMessage?.onReceiveValue(null)
}
cameraPermissionIntentData = CameraPermissionIntentData(null, arrayOf(), null, null)
mUploadMessage = filePathCallback
var takePictureIntent: Intent? = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (takePictureIntent!!.resolveActivity(this@sampleWebActivity.packageManager) != null) {
var photoFile: File? = null
try {
photoFile = createImageFile()
} catch (ex: IOException) {
Log.e(TAG, "Image file creation failed", ex)
}
if (photoFile != null) {
mCM = "file:" + photoFile.absolutePath
takePictureIntent.putExtra("PhotoPath", mCM)
val uri = FileProvider.getUriForFile(this@sampleWebActivity, this@sampleWebActivity.applicationContext.packageName + ".provider", photoFile)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
} else {
takePictureIntent = null
}
}
val chooserIntent = Intent(Intent.ACTION_CHOOSER)
val intentArray: Array<Intent?>
val contentSelectionIntent = Intent(Intent.ACTION_GET_CONTENT)
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE)
contentSelectionIntent.type = "*/*"
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Select file to send")
when(uploadType){
TYPE_CAMERA -> {
if(takePictureIntent != null) {
cameraPermissionIntentData.takePictureIntent = takePictureIntent
checkCameraPermission(
SnackBarRationale(
context = this@sampleWebActivity,
view = binding.sampleWebView,
rationaleText = getString(R.string.camera_access_required),
requestCode = TYPE_CAMERA
)
, openCamera = {
cameraPermissionIntentData.takePictureIntent?.let {
startActivityForResult(it, FILE_CHOOSER_REQUEST_CODE)
} ?: Log.logToCrashlytics(" +++++ fresh-bot take picture intent is null , permission already present")
})
} else {
return false
}
}
TYPE_GALLERY -> {
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent)
startActivityForResult(chooserIntent, FILE_CHOOSER_REQUEST_CODE)
}
TYPE_BOTH -> {
intentArray = if (takePictureIntent != null) {
arrayOf(takePictureIntent)
} else {
arrayOf()
}
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent)
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray)
cameraPermissionIntentData.apply {
this.takePictureIntent = takePictureIntent
this.intentArray = intentArray
this.contentSelectionIntent = contentSelectionIntent
this.chooserIntent = chooserIntent
}
checkCameraPermission(
SnackBarRationale(
context = this@sampleWebActivity,
view = binding.sampleWebView,
rationaleText = getString(R.string.camera_access_required),
requestCode = TYPE_BOTH
)
, openCamera = {
cameraPermissionIntentData.chooserIntent?.let {
startActivityForResult(it, FILE_CHOOSER_REQUEST_CODE)
} ?: Log.logToCrashlytics(" +++++ fresh-bot chooser intent is null , permission already present")
})
}
}
return true
}
override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress)
if (newProgress == 100) {
binding.sampleWebPb.postDelayed({
binding.sampleWebPb.visibility = View.GONE
}, 2000)
}
}
}
我尝试将回调和文件路径保存在Activity之外(在单例中),并在Activity创建时再次使用,但没有成功。我甚至尝试保存FreshBotChromeClient并再次使用相同的示例,但所选文件仍然无法加载。我该怎么办?
1条答案
按热度按时间iszxjhcz1#
由于方向更改,正在重新创建Activity。即使您强制Activity始终使用纵向方向,在某些手机上也会发生这种情况。
对我来说,三星S22上就是这样。相机应用会将方向更改为横向(在某些手机上)。当用户从相机前返回时,应用会注意到它处于横向模式,并会将自己删除并重新创建回纵向模式。但即使你保存了屏幕状态,你也无法再使用文件选择器回调。
要解决此问题,您需要在AndroidManifest中声明您的Activity手动处理方向更改,如下所示:
由于您声明要手动处理方向(和屏幕大小!)事件,因此Activity不会被删除和重新创建,并且不会丢失文件选择器回调。当方向发生更改时,onConfigurationChanged()回调将在Activity中调用,您应该手动处理它(如果需要)。
链接到清单中configChanges标记的文档:https://developer.android.com/guide/topics/manifest/activity-element.html#config