简体   繁体   English

Android Webview 从图库和相机上传图片,相机不工作

[英]Android Webview image upload from gallery and camera, camera not working

I have been searching all related posts here regarding this problem, but I cannot figure out, why the image upload does not work (testing on device with Android 8), when taking a picture from my camera.我一直在此处搜索有关此问题的所有相关帖子,但我无法弄清楚为什么从我的相机拍照时图像上传不起作用(在具有 Android 8 的设备上进行测试)。 Gallery upload works fine as expected.图库上传按预期正常工作。

In the activity result i get a path to the image in the cache directory (variable mCameraPhotoPath), but it seems that the result or the website cannot access this file or maybe there is an empty image file in there.在活动结果中,我得到了缓存目录中图像的路径(变量 mCameraPhotoPath),但似乎结果或网站无法访问此文件,或者可能那里有一个空图像文件。

Taking and uploading the image via google chrome directly on the device works, so I think the problem is not on the website side.直接在设备上通过谷歌浏览器拍摄和上传图像是可行的,所以我认为问题不在网站方面。

Here are my permissions这是我的权限

<uses-feature android:name="android.hardware.camera"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<!-- for new versions api 21+-->
<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CAMERA2" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

this is my application definition这是我的应用程序定义

 <application
    android:name="***"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:requestLegacyExternalStorage="true"
    android:hardwareAccelerated="true"
    android:theme="@style/Theme.Android">

    <!-- added fileprovider support -->
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

Then I added an xml folder in the res directory with a file called file_path.xml and added the content然后我在res目录下添加了一个xml文件夹,里面有一个叫file_path.xml的文件,并添加了内容

<paths>
  <cache-path
    name="mediaimages"
    path="./">
  </cache-path>
</paths>

And this is my activity code这是我的活动代码

private var mUploadCallbackAboveL: ValueCallback<Array<Uri>>? = null
private var mUploadCallbackBelow: ValueCallback<Uri?>? = null
private var imageUri: Uri? = null

override fun onCreate(savedInstanceState: Bundle?) {   
  super.onCreate(savedInstanceState)
  // webview definition 
  myWebView.webChromeClient = initChromeWebViewClient()
  myWebView.webViewClient = initWebViewClient()
  myWebView.settings.javaScriptEnabled = true
  myWebView.settings.domStorageEnabled = true
  myWebView.settings.allowFileAccess = true
  myWebView.settings.allowContentAccess = true
  myWebView.settings.supportZoom()
  myWebView.visibility = View.INVISIBLE
  myWebView.settings.userAgentString = "android"
  myWebView.setLayerType(View.LAYER_TYPE_HARDWARE, null)

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      myWebView.settings.mixedContentMode = 0
  }
}

private fun initChromeWebViewClient() : WebChromeClient {
    webChromeViewClient = object : WebChromeClient() {
        /**
         * API > = 21 (Android 5.0.1) calls back this method
         */
        override fun onShowFileChooser(
            webView: WebView?,
            valueCallback: ValueCallback<Array<Uri>>,
            fileChooserParams: FileChooserParams?
        ): Boolean {
            //(1) when the method calls back, it indicates that the version API > = 21. In this case, assign the result to muploadcallbackabovel to make it! = null
            mUploadCallbackAboveL = valueCallback
            takePhoto()
            return true
        }
    }
    return webChromeViewClient
}

@Override
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == REQUEST_CODE) {
        val file: File = File(imageUri!!.toString())
        val file_size = (file.length() / 1024).toString().toInt()
        //After the above two assignment operations (1) and (2), we can decide which processing method to adopt according to whether its value is empty
        if (mUploadCallbackBelow != null) {
            chooseBelow(resultCode, data);
        } else if (mUploadCallbackAboveL != null) {
            chooseAbove(resultCode, data);
        } else {
            Toast.makeText (this, "an error occurred.", Toast.LENGTH_SHORT).show();
        }
    }
}

Method which creates and starts the chooser Intent创建和启动选择器 Intent 的方法

private fun takePhoto() {
    //Adjust the camera in a way that specifies the storage location for taking pictures
    var photoFile : File? = null
    val authorities : String = applicationContext.packageName + ".provider"
    try {
        photoFile = createImageFile()
        imageUri = FileProvider.getUriForFile(this, authorities, photoFile)
    } catch(e: IOException) {
        e.printStackTrace()
    }

    val captureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
    val Photo = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
    val chooserIntent = Intent.createChooser(Photo, "Image Chooser")
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf<Parcelable>(captureIntent))
    startActivityForResult(chooserIntent, REQUEST_CODE)
}

@Throws(IOException::class)
  private fun createImageFile(): File {
    val imageFileName = "JPEG_" + SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
    return File(applicationContext.cacheDir.toString() + File.separator + imageFileName + ".jpg")
}

method to handle Android L+ results处理 Android L+ 结果的方法

private fun chooseAbove(resultCode : Int, data : Intent?) {
    if (RESULT_OK == resultCode) {
        updatePhotos()

        if (data != null) {
            //Here is the processing of selecting pictures from a file
            val results : Array<Uri>
            val uriData : Uri? = data.data
            if (uriData != null) {
                results = arrayOf(uriData)
                mUploadCallbackAboveL!!.onReceiveValue(results)
            } else {
                mUploadCallbackAboveL!!.onReceiveValue(null)
            }
        } else {
            if (imageUri != null) {
                mUploadCallbackAboveL!!.onReceiveValue(arrayOf(imageUri!!))
            }
        }
    } else {
        mUploadCallbackAboveL!!.onReceiveValue(null)
    }
    mUploadCallbackAboveL = null
}

Edit: Updated code to working code up until Android 10, Android 11 does not work.编辑:将代码更新为工作代码直到 Android 10,Android 11 不起作用。 Picture is taken, but not shown in Webviews Input.图片已拍摄,但未显示在 Webviews 输入中。 It seems the Fileprovider approach does not work or something is misconfigured for Android 11.似乎 Fileprovider 方法不起作用或 Android 11 配置错误。

Question was updated with working code.问题已使用工作代码更新。 Now chooser intent allows to select image from gallery or taken by the camera for Android +5 devices.现在选择器意图允许 select 图片来自画廊或由相机为 Android +5 设备拍摄。

Main issue was, that no FileProvider was used and cache directory was not specified correctly in file_paths.xml file.主要问题是,没有使用 FileProvider,并且在 file_paths.xml 文件中没有正确指定缓存目录。

Thanks to @blackapps for help and guiding into the correct direction!感谢@blackapps 的帮助和指导正确的方向!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android Webview从图库或相机上传图像 - Android Webview Upload Image from gallery or camera android webview 从画廊上传但不是从相机上传代码丢失? - android webview upload from gallery working but not from camera Code missing? 在 WebView 中从相机或图库上传图像 - Upload an Image from camera or gallery in WebView 从我的WebView中的相机或图库上传图像 - Upload an Image from camera or gallery in my WebView Android Image Upload适用于相机,但不适用于图库 - Android Image Upload working for camera but not gallery 无法在Android 8和9中从相机和图库上传图片 - Not able to upload image from camera and gallery in Android 8 & 9 用于从库中上传图像或在Android中捕获相机的库 - Library for upload image from gallery or camera capture in android 如何从相机或图库中获取图像并上传到 Android Q 中的服务器? - How to get image from camera or gallery and upload to server in Android Q? 从相机上传的照片在Nexus,Android WebView中无法正常工作 - Photo upload from Camera not working in Nexus, Android WebView 从图库中上传照片或在Webview中从相机拍摄 - Upload photo from gallery or take from camera in Webview
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM