android - 无法从 Android 10 Web View 访问相机

标签 android webview android-camera android-10.0

升级到 Android 10 后,自从 Android 5 或 6 停止提供对相机的访问以来,我一直在混合 Android Web View 应用程序中使用 onShowFileChooser 代码。用户仍然可以访问存储的照片,但不再向用户提供相机选项。

我一直使用的代码如下所示

      //For Android 5.0+
    public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
        {
        if(mUMA != null)
            {
            mUMA.onReceiveValue (null);
            }
        mUMA = filePathCallback;
        Intent takePictureIntent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity (MainActivity.this.getPackageManager()) != null)
            {
            File photoFile = null;
            try
                {
                photoFile = createImageFile();
                takePictureIntent.putExtra("PhotoPath", mCM);
                }
            catch(IOException ex)
                {
                Log.e(TAG, "Image file creation failed", ex);
                }
            if (photoFile != null)
                {
                mCM = "file:" + photoFile.getAbsolutePath();
                takePictureIntent.putExtra (MediaStore.EXTRA_OUTPUT, Uri.fromFile (photoFile));
                }
            else
                {
                takePictureIntent = null;
                }
            }
        Intent contentSelectionIntent = new Intent (Intent.ACTION_GET_CONTENT);
        contentSelectionIntent.addCategory (Intent.CATEGORY_OPENABLE);
        contentSelectionIntent.setType ("image/*");
        Intent[] intentArray;
        if (takePictureIntent != null)
            {
            intentArray = new Intent[] {takePictureIntent};
            }
        else
            {
            intentArray = new Intent[0];
            }

        Intent chooserIntent = new Intent (Intent.ACTION_CHOOSER);
        chooserIntent.putExtra (Intent.EXTRA_INTENT, contentSelectionIntent);
        chooserIntent.putExtra (Intent.EXTRA_TITLE, "Image Chooser");
        chooserIntent.putExtra (Intent.EXTRA_INITIAL_INTENTS, intentArray);
        startActivityForResult (chooserIntent, FileChooserActivityCode);
        return true;
        }

配合以下代码处理结果

protected void onActivityResult (int requestCode, int resultCode, Intent intent)
    {
    super.onActivityResult(requestCode, resultCode, intent);

    if (requestCode == FileChooserActivityCode)
        {
        Uri[] results = null;
        //Check if response is positive
        if (resultCode == Activity.RESULT_OK)
            {
            if (null == mUMA)
                {
                return;
                }
            if (intent == null || intent.getData() == null)
                {
                //Capture Photo if no image available
                if (mCM != null)
                    {
                    results = new Uri[]{Uri.parse(mCM)};
                    }
                }
            else
                {
                String dataString = intent.getDataString();
                if(dataString != null)
                    {
                    results = new Uri[]{Uri.parse(dataString)};
                    }
                }
            }
        mUMA.onReceiveValue(results);
        mUMA = null;
        }
    }

我已经从 this link 找到了如何访问相机并将 takePictureIntent 代码更改为以下内容:

    if(takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {

    File photoFile = null;
    Uri photoUri = null;

    if (isAndroidQ) {
        // Android Q compatibility
        photoUri = createImageUri();
        mCameraUri = photoUri;
        if (photoUri != null) {
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
        }
    } else {
        try {
            photoFile = createImageFile();
            takePictureIntent.putExtra("PhotoPath", mCM);
        } catch (IOException ex) {
            Log.e(LOG_TAG, "Image file creation failed", ex);
        }
        if (photoFile != null) {
            mCM = "file:" + photoFile.getAbsolutePath();
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
        } else {
            takePictureIntent = null;
        }
    }
}

private Uri createImageUri()
        {
        String status = Environment.getExternalStorageState();
        if (status.equals(Environment.MEDIA_MOUNTED))
            {
            return MainActivity.this.getApplicationContext().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
            }
        else
            {
            return MainActivity.this.getApplicationContext().getContentResolver().insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, new ContentValues());
            }
        }

但是现在在 onActivityResult 代码中拍照后,变量 mCM 为 null,并且没有任何内容传递到 Web View 。

请问有人可以告诉我我错过了什么吗?

最佳答案

如果您的目标是 Android 10 - 此版本引入了一种新的、更安全/私密的存储访问方式,名为“作用域存储”。查看THIS文章了解如何实现的更多信息

对于更复杂的解决方案,您应该显示 createImageUri 中发生的情况和createImageFile方法

HERE我们有很好的文档如何处理新旧方式

您可以选择禁用新的访问方式,但仅适用于 Android 10,从 11 开始将需要此支持。添加android:requestLegacyExternalStorage="true"对于 <application> list 中的标签

关于android - 无法从 Android 10 Web View 访问相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61590038/

相关文章:

Android 从 CSS 文件到字体的相对路径

android - public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) 没有反应

android - Android 中的 "public float getFocalLength ()"和 "public void getFocusDistances (float[] output)"有什么区别?

android - 在android代码中向 ImageView 添加进度条

Android R.anim,未找到摇动

android - 为什么我无法使用 Android WebView 调用 onPageStarted、onReceivedError 或 onPageFinished?

android - 释放后调用的方法

android - 正确处理异常 : "getParameters failed (empty parameters)"

android - 捕获 SeekBar 值

android - Android应用程序显示默认图标启动器