相机文件选择器未在 WebView android 中打开

Posted

技术标签:

【中文标题】相机文件选择器未在 WebView android 中打开【英文标题】:Camera file chooser not opening in WebView android 【发布时间】:2021-09-23 08:15:00 【问题描述】:

上传时,会弹出一个自定义意图,其中包含文件图标和相机图标。文件图标用于文件上传,相机图标用于从相机捕获图像后上传图像。文件上传工作正常..但相机动作没有工作..当我点击相机图标时它什么也没做..我还检查了 logcat 是否发生任何错误..我没有看到任何错误..

public class QuestionUploaderActivity extends AppCompatActivity 

String Sub_Question_url;


public static final int REQUEST_CODE_LOLIPOP = 1;
private final static int RESULT_CODE_ICE_CREAM = 2;
private WebView webView;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
private ValueCallback<Uri> mUploadMessage;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_question_uploader);

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);

    Sub_Question_url = getIntent().getStringExtra("Sub_Question_url");

    webView = (WebView) findViewById(R.id.webView);
    setUpWebViewDefaults(webView);
    webView.loadUrl(Sub_Question_url);

    webView.setWebChromeClient(new WebChromeClient() 
        private String TAG;
        // For android 3.0+
        public void openFileChooser(ValueCallback<Uri> uploadMsg) 
            mUploadMessage = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("image/*");
            startActivityForResult(Intent.createChooser(i, "File Chooser"),
                    RESULT_CODE_ICE_CREAM);

        
        // For Android 3.0+
        public void openFileChooser(ValueCallback uploadMsg, String acceptType) 
            mUploadMessage = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("*/*");
            startActivityForResult(Intent.createChooser(i, "File Browser"),
                    RESULT_CODE_ICE_CREAM);
        
        //For Android 4.1
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) 
            mUploadMessage = uploadMsg;
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("image/*");
            startActivityForResult(Intent.createChooser(i, "File Chooser"),
                    RESULT_CODE_ICE_CREAM);

        
        //For Android5.0+
        public boolean onShowFileChooser(
                WebView webView, ValueCallback<Uri[]> filePathCallback,
                FileChooserParams fileChooserParams) 
            if (mFilePathCallback != null) 
                mFilePathCallback.onReceiveValue(null);
            
            mFilePathCallback = filePathCallback;
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            if (takePictureIntent.resolveActivity(getApplicationContext().getPackageManager()) != null) 
                // Create the File where the photo should go
                File photoFile = null;
                try 
                    photoFile = createImageFile();
                    takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
                 catch (IOException ex) 
                    // Error occurred while creating the File
                    Log.e(TAG, "Unable to create Image File", ex);
                
                // Continue only if the File was successfully created
                if (photoFile != null) 
                    mCameraPhotoPath = "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, REQUEST_CODE_LOLIPOP);

            return true;
        
    );


private File createImageFile() throws IOException 
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File imageFile = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
    return imageFile;


@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setUpWebViewDefaults(WebView webView) 
    WebSettings settings = webView.getSettings();
    // Enable javascript
    settings.setJavaScriptEnabled(true);

    settings.setDomStorageEnabled(true);
    settings.setPluginState(WebSettings.PluginState.ON);

    // Use WideViewport and Zoom out if there is no viewport defined
    settings.setUseWideViewPort(true);
    settings.setLoadWithOverviewMode(true);
    // Enable pinch to zoom without the zoom buttons
    settings.setBuiltInZoomControls(true);
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) 
        // Hide the zoom controls for HONEYCOMB+
        settings.setDisplayZoomControls(false);
    
    // Enable remote debugging via chrome://inspect
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
        WebView.setWebContentsDebuggingEnabled(true);
    
    // We set the WebViewClient to ensure links are consumed by the WebView rather
    // than passed to a browser if it can
    webView.setWebViewClient(new WebViewClient());



@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) 
        case RESULT_CODE_ICE_CREAM:
            Uri uri = null;
            if (data != null) 
                uri = data.getData();
            
            mUploadMessage.onReceiveValue(uri);
            mUploadMessage = null;
            break;
        case REQUEST_CODE_LOLIPOP:
            Uri[] results = null;
            // Check that the response is a good one
            if (resultCode == Activity.RESULT_OK) 
                if (data == null|| data.getDataString() == null) 
                    // If there is not data, then we may have taken a photo
                    if (mCameraPhotoPath != null) 
                        results = new Uri[]Uri.parse(mCameraPhotoPath);
                    
                 else 
                    String dataString = data.getDataString();
                    if (dataString != null) 
                        results = new Uri[]Uri.parse(dataString);
                    
                
            
            mFilePathCallback.onReceiveValue(results);
            mFilePathCallback = null;
            break;
    


【问题讨论】:

【参考方案1】:

我遇到了同样的问题,我只是删除了选择器以直接启动相机意图,然后我遇到了一个崩溃并显示错误:

Android: Permission Denial: starting Intent with revoked permission android.permission.CAMERA

在这个post 他们说我们应该删除

<uses-permission android:name="android.permission.CAMERA" />

然后它就起作用了!你可以使用选择器。希望对你来说还不算太晚。

编辑:如果您想将此权限用于其他需要,您只需在启动选择器之前向用户询问权限。 Intent 本身不会触发请求权限。

【讨论】:

以上是关于相机文件选择器未在 WebView android 中打开的主要内容,如果未能解决你的问题,请参考以下文章

反应本机选择器未在android上显示

联系人选择器未在 Android Studio 中提供预期结果

有没有办法让颤动的 webview 使用 android 相机进行文件上传?如何在 webview_flutter 中打开文件选择器?

来自画廊工作的文件选择器,但它不适用于 android webview 中的相机

Android Kotlin:定期工作管理器未在后台定期运行该功能

引导日期选择器未在 editorFor 中显示模型值