Android:从网络视图中选择文件

vbkedwbf  于 2023-01-07  发布在  Android
关注(0)|答案(1)|浏览(199)

我尝试从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并再次使用相同的示例,但所选文件仍然无法加载。我该怎么办?

iszxjhcz

iszxjhcz1#

由于方向更改,正在重新创建Activity。即使您强制Activity始终使用纵向方向,在某些手机上也会发生这种情况。
对我来说,三星S22上就是这样。相机应用会将方向更改为横向(在某些手机上)。当用户从相机前返回时,应用会注意到它处于横向模式,并会将自己删除并重新创建回纵向模式。但即使你保存了屏幕状态,你也无法再使用文件选择器回调。
要解决此问题,您需要在AndroidManifest中声明您的Activity手动处理方向更改,如下所示:

<activity
    android:name=".YourActivity"
    android:configChanges="orientation|keyboardHidden|screenSize"
    android:screenOrientation="portrait" />

由于您声明要手动处理方向(和屏幕大小!)事件,因此Activity不会被删除和重新创建,并且不会丢失文件选择器回调。当方向发生更改时,onConfigurationChanged()回调将在Activity中调用,您应该手动处理它(如果需要)。
链接到清单中configChanges标记的文档:https://developer.android.com/guide/topics/manifest/activity-element.html#config

相关问题