【问题标题】:Getting null intent.getDataString() on camera image upload in Android webview with SDK 30在Android WebView中获取Null Intent.getDatastring()在Android WebView中载于SDK 30
【发布时间】:2021-12-19 07:37:18
【问题描述】:

我正在使用以下代码在android webview中上传相机图像

private ValueCallback<Uri[]> file_path;     // received file(s) temp. location
private final static int file_req_code = 1;

/*-- creating new image file here --*/
    private File create_image() throws IOException {
        @SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "checkimg_"+timeStamp+"_";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        return File.createTempFile(imageFileName,".jpg",storageDir);
    }

// Handling onshow file chooser
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {

                    file_path = filePathCallback;
                    Intent takePictureIntent = null;

                    takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    if (takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {
                        File photoFile = null;
                        try {
                            photoFile = create_image();
                            takePictureIntent.putExtra("PhotoPath", cam_file_data);
                        } catch (IOException ex) {
                            Log.e(TAG, "Image file creation failed", ex);
                        }

                        //Code modiied to make camera uploads work with webview with latest android version - https://stackoverflow.com/questions/62424102/android-webview-cannot-save-or-upload-image-taken-with-camera-to-html5-canvas
                        if (photoFile != null) {
                            cam_file_data = "file:" + photoFile.getAbsolutePath();
                            Uri imgUrl;
                            if (getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.M) {
                                String authority = getPackageName();
                                imgUrl = FileProvider.getUriForFile(MainActivity.this, authority, photoFile);
                            } else {
                                imgUrl = Uri.fromFile(photoFile);
                            }
                            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imgUrl);
                        } else {
                            cam_file_data = null;
                            takePictureIntent = null;
                        }

                    }

                    Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
                    contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
                    contentSelectionIntent.setType(file_type);

                    Intent[] intentArray;

                    intentArray = new Intent[]{takePictureIntent};

                    Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
                    chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
                    chooserIntent.putExtra(Intent.EXTRA_TITLE, "Select Photo for Upload");
                    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);

                    chooserIntentForCameraPermission = chooserIntent;

                //Camera & Storage Permissions Granted
                if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && Build.VERSION.SDK_INT >= 21) {


                   startActivityForResult(chooserIntent, file_req_code);
                    return true;

                } else {

                    file_path = filePathCallback;

                    Intent intent = fileChooserParams.createIntent();

                    intentForFileChooserPermissions = intent;

                    ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA}, 2);

                    return true;
                }
            }








// On activity result of file chooser
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent){
        super.onActivityResult(requestCode, resultCode, intent);
        if(Build.VERSION.SDK_INT >= 21){
            Uri[] results = null;


            /*-- if file request cancelled; exited camera. we need to send null value to make future attempts workable --*/
            if (resultCode == Activity.RESULT_CANCELED) {


                if (requestCode == file_req_code) {
                    file_path.onReceiveValue(null);
                    return;
                }
            }

            /*-- continue if response is positive --*/
            if(resultCode== Activity.RESULT_OK){
                if(requestCode == file_req_code){
                    if(null == file_path){
                        return;
                    }

                    ClipData clipData;
                    String stringData;
                    try {
                        clipData = intent.getClipData();
                        stringData = intent.getDataString();

                    }catch (Exception e){

                        clipData = null;
                        stringData = null;
                    }

                    if (clipData == null && stringData == null && cam_file_data != null) {
                        results = new Uri[]{Uri.parse(cam_file_data)};
                    }else{
                        if (clipData != null) { // checking if multiple files selected or not
                            final int numSelectedFiles = clipData.getItemCount();
                            results = new Uri[numSelectedFiles];
                            for (int i = 0; i < clipData.getItemCount(); i++) {
                                results[i] = clipData.getItemAt(i).getUri();
                            }
                        } else {

                            
                                results = new Uri[]{Uri.parse(stringData)};//This part is causing sdk 30 to crash after camera image upload as stringData is null 
                            
                            }
                    }
                }
            }
            file_path.onReceiveValue(results);
            file_path = null;
        }else{
            if(requestCode == file_req_code){
                if(null == file_data) return;
                Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();
                file_data.onReceiveValue(result);
                file_data = null;
            }
        }
    }

清单已注册以下提供程序:

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

provider_paths.xml 也存在于res/xml 中,并带有以下代码:

<?xml version="1.0" encoding="utf-8"?>
<!-- File added to enable camera uploads in webview - https://stackoverflow.com/questions/62424102/android-webview-cannot-save-or-upload-image-taken-with-camera-to-html5-canvas -->

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

这适用于 Android SDK 29。但是,对于 SDK 30,intent.getDataString()onActivityResult 部分代码中为空,当我们在此使用 Uri.parse() 时会引发错误。使用 if 条件检查该值可以避免该错误,但是,由于 intent.getDataString() 为空,因此无法使用 SDK 30 上传相机图像。如何使其工作?

【问题讨论】:

    标签: android


    【解决方案1】:

    我能够通过将以下代码添加到清单 AndroidManifest.xml 文件来解决上述问题:

     <!--Android 30 and Above Permission-->
        <queries>
            <intent>
                <action android:name="android.media.action.IMAGE_CAPTURE" />
            </intent>
        </queries>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      • 2013-03-01
      • 2012-05-18
      • 1970-01-01
      • 2011-01-14
      • 1970-01-01
      相关资源
      最近更新 更多